Package: pyballistics
PyBallisticsPython-библиотека для решения ОЗВБ в термодинамической и газодинамической постановках.УстановкаУстановить библиотеку можно через менеджер пакетовpip. Для этого достаточно выполнить в консоли командуpip install --upgrade pyballisticsКраткая инструкция по использованиюПример расчета ОЗВБ в термодинамической постановке задачи AGARD:frompyballisticsimportozvb_termo,get_options_agardopts=get_options_agard()# получить словарь с начальными данными задачи AGARDresult=ozvb_termo(opts)# произвести расчет и получить результатПеременнаяresultявляетсясловарем, в котором находятся результаты расчета.
Для визуализации части результатов можно воспользоваться следующим кодом:importmatplotlib.pyplotasplt# если нет библиотеки matplotlib, то установить ее можно при помощи команды pip install matplotlibplt.plot(result['t'],result['p_m'])# среднебаллистическое давление от времениplt.grid()# сетка на графикеplt.show()# показать графикВ результате будет получен следующий график зависимости среднебаллистического давления (Па) от времени (с):В словареresultесть все необходимые данные для дальнейшего анализа:importnumpyasnp# максимальное давлениеprint(np.max(result['p_m']))>>>319103989.57# дульная скоростьprint(result['v_p'][-1])>>>671.16# доля сгоревшего порохаprint(result['psi_1'][-1])>>>0.932Более подробная инструкцияЗа сами расчеты ОЗВБ отвечают две функции:ozvb_termoиozvb_lagrange. Они могут быть импортированы непосредственно из библиотеки:frompyballisticsimportozvb_termo,ozvb_lagrangeФункцияozvb_termoпроизводит термодинамический расчет, аozvb_lagrange- газодинамический в Лагранжевых координатах.Обе эти функции на вход принимают словари, в которых хранятся все необходимые для расчета начальные данные. Примеры таких словарей можно получить из функцийget_options_agardиget_options_sample:frompyballisticsimportget_options_agard,get_options_sampleopts1=get_options_agard()opts2=get_options_sample()print(opts2)# {#   'powders': [#       {'omega': 7, 'dbname': 'ДГ-4 15/1'},#       {'omega': 6, 'dbname': '22/7'}],#  'init_conditions': {#       'q': 51.76,#       'd': 0.122,#       'W_0': 0.0325,#       'phi_1': 1.02,#       'p_0': 30000000.0 },#  'igniter': {#       'p_ign_0': 1000000.0},#  'meta_termo': {#       'dt': 5e-06,#       'method': 'rk2'},#  'meta_lagrange': {#       'CFL': 0.9,#       'n_cells': 150},#  'stop_conditions': {#       'v_p': 690,#       'p_max': 600000000.0,#       'x_p': 9}# }Словарь со входными данными является иерархической структурой данных (словарь словарей, списков и т.д.). Для указания всех данных, однозначно описывающих задачу ОЗВБ, словарь должен быть довольно громоздким и неудобным для формирования. Для упрощения формирования словаря многие входящие в него элементы имеют значения по умолчанию и их, в случае необходимости, можно не указывать. Однако есть ряд элементов и значений, которые указывать обязательно.
Словарь со входными данными состоит из следующих элементов "верхнего уровня":'init_conditions'-обязательный раздел. В данном разделе хранится словарь с начальными данными:'q'- масса снаряда в кг.'d'- калибр, м.'W_0'- начальный объем каморы, м^3.'phi_1'- коэффициент, учитывающий силу трения в нарезах (участвует в формуле расчета коэффициента фиктивности массы снаряда).'p_0'- давление форсирования, Па.'T_0'(опционально) - начальная температура, К (значение по умолчанию 293.15 К).'n_S'(опционально) - коэффициент учета площади нарезов (*значение по умолчанию 1). Площадь поперечного сечения высчитывается по формуле S = n_S pi d^2 / 4 .'powders'-обязательный раздел. В данном разделе хранитсясписокс данными по пороховым навескам, из которых состоит метательный заряд.Обязательно должен иметь хотя бы один элемент. Каждый элемент списка отвечает за свою навеску и тоже является словарем со следующими элементами:'omega'- масса навески заряда, кг.'dbname'(опционально) - имя пороха в БД.Если указать, то для остальных элементов будут определены значения по умолчанию. Если не указать, то все остальные элементы будет необходимо инициализировать(список доступных имен можно получить из функцииget_powder_names). Т.е. при желании можно корректировать часть характеристик табличных порохов и брать у них остальные значения стандартными.'I_e'(опционально, если указан'dbname') - импульс конца горения, Па с.'nu'(опционально, если указан'dbname') - показатель в степенном законе горения (по умолчанию 1).'b'(опционально, если указан'dbname') - коволюм пороховых газов, м^3/кг.'delta'(опционально, если указан'dbname') - плотность пороха, кг/м^3.'f'(опционально, если указан'dbname') - сила пороха, Дж/кг.'k'(опционально, если указан'dbname') - коэффициент адиабаты пороховых газов.'T_p'(опционально, если указан'dbname') - темп. горения пороха, К.'z_e'(опционально, если указан'dbname') - относительная толщина сгоревшего слоя конца горения.'kappa_1'(опционально, если указан'dbname') - коэффициент в геометрическом законе горения.'lambda_1'(опционально, если указан'dbname') - коэффициент в геометрическом законе горения.'mu_1'(опционально, если указан'dbname') - коэффициент в геометрическом законе горения.'kappa_2'(опционально, если указан'dbname') - коэффициент в геометрическом законе горения.'lambda_2'(опционально, если указан'dbname') - коэффициент в геометрическом законе горения.'mu_2'(опционально, если указан'dbname') - коэффициент в геометрическом законе горения.'k_I'(опционально, если указан'dbname') - коэффициент для пересчета импульса конца горения для других начальных температур, 1/K.'k_f'(опционально, если указан'dbname') - коэффициент для пересчета силы пороха для других начальных температур, 1/K.'igniter'-обязательный раздел. В данном разделе хранится словарь с начальными данными, которые относятся к воспламенителю. Словарь имеет следующие элементы:'p_ign_0'- давление вспышки, Па.'k_ign'(опционально) - коэффициент адиабаты газов воспламенителя (значение по умолчанию 1.22).'T_ign'(опционально) - температура горения воспламенителя, К (значение по умолчанию 2427).'f_ign'(опционально) - сила воспламенителя, Дж/кг (значение по умолчанию 260 000 Дж/кг).'b_ign'(опционально) - коволюм газов воспламенителя, м^3/кг (значение по умолчанию 0.0006).'windage'-опциональный раздел. В данном разделе хранится словарь с начальными данными, которые относятся к силе сопротивления воздуха перед снарядом. Если не указывать этот элемент, то будут использованы значения по умолчанию. Словарь имеет следующие элементы:'shock_wave'(опционально) - флагTrue/False, показывающий нужно ли рассчитывать давление ударной волны по формуле, или использовать просто статичное давление'p_0a'(значение по умолчаниюTrue).'p_0a'(опционально) - давление воздуха перед снарядом, Па (значение по умолчанию 100 000).'k_air'(опционально) - показатель адиабаты воздуха (значение по умолчанию 1.4).'c_0a'(опционально) - скорость звука в воздухе, м/с (значение по умолчанию 340).'heat'-опциональный раздел. В данном разделе хранится словарь с начальными данными, которые относятся к теплообмену ГПС со стволом. Если не указывать этот элемент, то будут использованы все значения по умолчанию. Словарь имеет следующие элементы:'enabled'(опционально) - флагTrue/False, показывающий нужно ли учитывать теплообмен со стволом (значение по умолчаниюTrue).'heat_barrel'(опционально) - флагTrue/False, показывающий нужно ли учитывать рассчитвать динамически температуру стенки ствола, или температура стенок ствола не меняется (значение по умолчаниюTrue).'F_0'(опционально) - начальная площадь теплоотдачи, м^2 (значение по умолчанию 4W_0/d).'Pr'(опционально) - число Прандля (значение по умолчанию 0.74).'T_w0'(опционально) - начальная температура стенки, К. Если не указывать - то будет взята начальная температура.'mu_0'(опционально) - коэффициент динамической вязкости пороховых газов для формулы Сазерленда, Па*с (значение по умолчанию 0.175e-4).'T_cs'(опционально) - тоже для формулы Сазерленда, К (значение по умолчанию 628).'T_0s'(опционально) - тоже для формулы Сазерленда, К (значение по умолчанию 273).'c_b'(опционально) - теплоемкость материала ствола, Дж/(кг * град) (значение по умолчанию 500).'rho_b'(опционально) - плотность материала ствола, кг/м^3 (значение по умолчанию 7900).'lambda_b'(опционально) - теплопроводность материала ствола, Вт/(м·град) (значение по умолчанию 40).'lambda_g'(опционально) - теплопроводность пороховых газов, Вт/(м·К) (значение по умолчанию 0.2218).'stop_conditions'-обязательный раздел. В данном разделе хранится словарь с начальными данными, которые относятся к условиям конца расчета.Должен иметь хотя бы один элемент(любой из нижеперечисленных). Если указано несколько условий, то расчет будет остановлен из-за условия, которое сработало раньше всего. Словарь имеет следующие элементы:'t_max'(опционально) - с, прервать расчет при t > t_max.'steps_max'(опционально) - сделать максимум  steps_max шагов интегрирования.'v_p'(опционально) - м/с, прервать расчет, когда скорость снаряда достигнет v_p.'x_p'(опционально) - м, прервать расчет, когда снаряд пройдет x_p метров (в начальный момент снаряд прошел 0 м).'p_max'(опционально) - Па, прервать расчет, если давление превысит p_max.'meta_termo'-обязательный раздел для термодинамического расчета. В данном разделе хранится словарь с начальными данными, которые относятся к мета-параметрам термодинамического расчета. Словарь имеет следующие элементы:'dt'- с, шаг по времени.'method'(опционально) - метод интегрирования. Возможные варианты: Эйлер - 'euler'; Рунге-Кутты 2 порядка -'rk2'; -  Рунге-Кутты 4 порядка - 'rk4' (значение по умолчанию 'rk2').'meta_lagrange'-обязательный раздел для газодинамического расчета. В данном разделе хранится словарь с начальными данными, которые относятся к мета-параметрам газодинамического расчета. Словарь имеет следующие элементы:'n_cells'- количество ячеек сетки.'CFL'- число Куранта (0 < CFL < 1).'W'(опционально) - дополнительное требование для повышения устойчивости: последующий шаг по времени не может быть больше текущего в W раз.Структура результатов термодинамической моделиВ зависимости от результатов расчета, словарь может быть двух видов. Если в результате расчета произошла ошибка, то будет сформирован следующий словарь:{'stop_reason':'error',# показывает, что в процессе расчета произошла ошибка'error_message':'...',# описание ошибки'exception':Error('...'),# ссылка на саму ошибку (ее можно вызвать при помощи raise для трассировки)'execution_time':float# время выполнения функции в секундах}Пример:result=ozvb_termo({})# передаем пустой словарьprint(result)>>>{'stop_reason':'error','error_message':'В словаре opts обязательно должно быть поле "powders", в котором указываются параметры заряда. Пример правильного словаря opts можно получить из функции get_termo_options_sample()','exception':ValueError('В словаре opts обязательно должно быть поле "powders", в котором указываются параметры заряда. Пример правильного словаря opts можно получить из функции get_termo_options_sample()'),'execution_time':1.7400000047018693e-05}Если расчет прошел без ошибок, то словарь с результатами будет следующий:{'t':np.array([...]),# numpy-массив с точками по времени в секундах, в которых были рассчитаны остальные значения'p_m':np.array([...]),# numpy-массив со среднебаллистическим давлением в Па'T':np.array([...]),# numpy-массив с температурой ГПС в Кельвинах'x_p':np.array([...]),# numpy-массив с положением снаряда в метрах (в начальный момент x_p==0)'v_p':np.array([...]),# numpy-массив со скоростью снаряда в м/c (в начальный момент v_p==0)'Q_pa':np.array([...]),# numpy-массив с суммарной энергией в Дж, потраченной на преодоление сил сопротивления атмосферному давлению перед снарядом'Q_w':np.array([...]),# numpy-массив с суммарной энергией в Дж, отданной  ГПС на нагрев ствола'W_p':np.array([...]),# numpy-массив с заснарядным объемом в м^3'W_c':np.array([...]),# numpy-массив с объемом в м^3, занятым коволюмом ГПС и конденсированной фазой ГПС'T_w':np.array([...]),# numpy-массив со средней температурой ствола в К'k':np.array([...]),# numpy-массив с показателями адиабаты ГПС'z_1':np.array([...]),# numpy-массив с относительной толщиной сгоревшего свода пороха навески №1'psi_1':np.array([...]),# numpy-массив с относительной массой сгоревшего пороха навески №1'z_2':np.array([...]),# numpy-массив с относительной толщиной сгоревшего свода пороха навески №2'psi_2':np.array([...]),# numpy-массив с относительной массой сгоревшего пороха навески №2...# и так N раз'stop_reason':str,# причина остановки расчета ('t_max', 'steps_max', 'v_p', 'x_p', 'p_max')'execution_time':float# время, потраченное на расчет, в секундах}Пример:opts=get_options_sample()result=ozvb_termo(opts)print(result)>>>{'t':array([0.,0.,...,0.027,0.027]),'p_m':array([1000000.,1002189.433,...,90680294.893,90629603.46]),'T':array([2427.,2427.487,...,1824.249,1823.988]),'x_p':array([0.,0.,...,6.394,6.398]),'v_p':array([0.,0.,...,689.994,690.085]),'Q_pa':array([0.,0.,...,45159.509,45195.554]),'Q_w':array([0.,0.,...,3447622.549,3449318.738]),'W_p':array([0.033,0.033,...,0.107,0.107]),'W_c':array([0.008,0.008,...,0.014,0.014]),'T_w':array([293.15,293.15,...,315.661,315.661]),'k':array([1.22,1.22,...,1.238,1.238]),'z_1':array([0.,0.,...,0.954,0.954]),'psi_1':array([0.,0.,...,0.954,0.954]),'z_2':array([0.,0.,...,1.343,1.343]),'psi_2':array([0.,0.,...,0.987,0.987]),'stop_reason':'v_p','execution_time':0.21484209999971426}Структура результатов газодинамической моделиВ зависимости от результатов расчета, словарь может быть двух видов. Если в результате расчета произошла ошибка, то будет сформирован следующий словарь:{'stop_reason':'error',# показывает, что в процессе расчета произошла ошибка'error_message':'...',# описание ошибки'exception':Error('...'),# ссылка на саму ошибку (ее можно вызвать при помощи raise для трассировки)'execution_time':float# время выполнения функции в секундах}Пример:result=ozvb_lagrange({})# передаем пустой словарьprint(result)>>>{'stop_reason':'error','error_message':'В словаре opts обязательно должно быть поле "powders", в котором указываются параметры заряда. Пример правильного словаря opts можно получить из функции get_termo_options_sample()','exception':ValueError('В словаре opts обязательно должно быть поле "powders", в котором указываются параметры заряда. Пример правильного словаря opts можно получить из функции get_termo_options_sample()'),'execution_time':1.7400000047018693e-05}Если расчет прошел без ошибок, то словарь с результатами будет следующий:{'stop_reason':str,# причина остановки расчета ('t_max', 'steps_max', 'v_p', 'x_p', 'p_max')'execution_time':float,# время выполнения расчета в секундах'layers':[# список со словарями. В каждом словаре хранятся данные одного временного слоя{# Словарь первого временного слоя. Слой состоит из N ячеек't':0.0,# время временного слоя в секундах'step_count':0,# номер шага по времени'x':np.array([...]),# numpy-массив координатами по длине узлов сетки в метрах, длина массива N+1'u':np.array([...]),# numpy-массив со скоростями узлов сетки в м/с, длина массива N+1'T':np.array([...]),# numpy-массив с температурами ГПС в ячейках в Кельвинах. Длина массива N'rho':np.array([...]),# numpy-массив с плотностями ГПС в ячейках в кг/м^3. Длина массива N'p':np.array([...]),# numpy-массив с давлениями ГПС в ячейках в Па. Длина массива N'T_w':np.array([...]),# numpy-массив с температурами стенок ствола в ячейках в Кельвинах. Длина массива N'k':np.array([...]),# numpy-массив с показателями адиабаты ГПС в ячейках. Длина массива N'z_1':np.array([...]),# numpy-массив с относительными толщинами сгоревшего свода пороха навески №1 по ячейкам. Длина массива N'psi_1':np.array([...]),# numpy-массив с относительными массами сгоревшего пороха навески №1 по ячейкам. Длина массива N'z_2':np.array([...]),# numpy-массив с относительными толщинами сгоревшего свода пороха навески №2 по ячейкам. Длина массива N'psi_2':np.array([...]),# numpy-массив с относительными массами сгоревшего пороха навески №2 по ячейкам. Длина массива N...# и так по всем навескам},{...},# Словарь второго временного слоя. Слой состоит из N ячеек{...},# Словарь третьего временного слоя. Слой состоит из N ячеек...,№ит.д.]# конец списка 'layers'}Пример:opts=get_options_sample()result=ozvb_lagrange(opts)print(result)>>>{'stop_reason':'v_p','execution_time':0.167843300000186,'layers':[{'t':0.0,'step_count':0,'x':array([-2.78,-2.762,...,-0.019,0.]),'u':array([0.,0.,...,0.,0.]),'T':array([2427.,2427.,...,2427.,2427.]),'rho':array([402.851,402.851,...,402.851,402.851]),'p':array([1000000.,1000000.,...,1000000.,1000000.]),'T_w':array([293.15,293.15,...,293.15,293.15]),'k':array([1.22,1.22,...,1.22,1.22]),'z_1':array([0.,0.,...,0.,0.]),'psi_1':array([0.,0.,...,0.,0.]),'z_2':array([0.,0.,...,0.,0.]),'psi_2':array([0.,0.,...,0.,0.])},{'t':0.00026096741712768897,'step_count':1,'x':array([-2.78,-2.762,...,-0.019,0.]),'u':array([0.,0.,...,0.,0.]),'T':array([2450.216,2450.216,...,2450.216,2450.216]),'rho':array([402.851,402.851,...,402.851,402.851]),'p':array([1114231.986,1114231.986,...,1114231.986,1114231.986]),'T_w':array([293.15,293.15,...,293.15,293.15]),'k':array([1.222,1.222,...,1.222,1.222]),'z_1':array([0.,0.,...,0.,0.]),'psi_1':array([0.,0.,...,0.,0.]),'z_2':array([0.,0.,...,0.,0.]),'psi_2':array([0.,0.,...,0.,0.])},...]}Дополнительные функцииВ библиотеке также есть несколько дополнительных функций, описание к которым есть в ихдокументации:frompyballisticsimportget_full_options,get_db_powder,get_powder_namesprint(get_full_options.__doc__)print(get_db_powder.__doc__)print(get_powder_names.__doc__)