PhysUnitCalc: калькулятор с физическими размерностями и комплексными числами

Jan 26, 2015 00:04

Всех причастных - с Татьяниным днем!

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




В этой незамысловатой программе есть возможности, которым Mathcad и Matlab могут позавидовать, это автоматический пересчет между единицами СИ, СГС, а также всевозможными системами, в которых работают физики, где задано "для упрощения", что c=h=1, в том числе планковской, когда вообще все величины оказываются безразмерными. Правильная размерность не только будет восстановлена, но и будет показано, на что для этого нужно помножить выражение.

Кроме того, корректно сделана работа с температурами, так что, с одной стороны, существует четкое различие между температурой (20oC = 293.15 K) и разницей температур (20oC{dif} = 20 K{dif}), но в то же время над нею можно совершать любые операции, не натыкаясь на каждом ходу на ограничения.

Сейчас расскажу чуть подробнее.

[Ввод физической величины]

Ввод физической величины
Тут все просто: после числа ставим пробел и затем наименование величины, например, 1 m, 20 kg, 4 Ohm*mm^2/m. Поддерживаются множители k,M,G,T,d,c,m,u,n,p,f (кило-, мега-, гига-, тера-, деци-, санти-, милли-, микро-,нано-,пико-,фемто-) и они же по-русски: к,М,Г,Т,д,с,м,мк,н,п,ф. Множитель может быть только один, писать ммк (миллимикро) нельзя. Множитель, очевидно, чувствителен к регистру, м - это милли, М - это мега, отличается в миллиард раз. А вот наименование величины к регистру нечувствительно.

Если величина производная, то сейчас ее запись должна удовлетворять довольно строгому синтаксису, в следующих версиях его чуть ослаблю. А именно, скобки не допускаются, только наименования единиц, символ ^ и идущее за ним число - показатель степени (тоже без скобок, даже если отрицательное), символы * и /. Деление относится только к одной величине, т.е W/m/K - это именно ватт на метр на кельвин. То же самое можно записать как W*m^-1*K^-1.

Можно присваивать размерность целому выражению, если до этого оно было безразмерным, например (2+2*2) м, или (1+5i) V. Если у величины уже есть размерность, ее таким образом нельзя поменять, например, выражение (1 м) км - приведет к ошибке. Для представления той же величины в другой форме предназначен другой оператор, "квадратные скобки".

Когда мы назначаем единицу измерения, она вводится ровно в том виде, который мы задали. Скажем, 1 Ом*мм^2/м не спешит преобразовываться в Ом*м, пока в этом не возникает необходимость. Так сделано, чтобы избежать ненужных преобразований и сохранять контекст, который внес пользователь. Например, H*м имеет ту же размерность, что Дж, но крутящий момент в джоулях не измеряют! Точно так же и упомянутые Ом*мм^2/м - более понятная величина, это сопротивление проволоки из данного материала с длиной 1 метр и сечением 1 "квадрат".


[Приведение к другой единице измерения]

Приведение к другой единице измерения
Если мы хотим получить ответ в определенной единице измерения, например, в км/ч, мы должны в конце выражения написать [км/ч]. Если выражение имело размерность скорости, то преобразование пройдет "тихо", без дополнительных сообщений, 1 м/с преобразуется в 3.6 км/ч и т.д. Если же размерности отличаются, то программа попытается воспользоваться допущениями, что c=1, h=1 и пр.. При запуске программы они все отключены, так что выражение 1 [m/s] приведет к ошибке: "Некорректное приведение типов: [] в [m/s]".

Если мы зайдем в меню "Допустить, что..." и щелкнем по "с=1" (внизу, в строке состояния будет подсказка), то выражение 1 [m/s] станет допустимым, мы получим ответ 299792458 m/s, а перед этим синим будет показано сообщение: "Для преобразования из [] в [m/s] выражение домножено на c". О таких преобразованиях чуть ниже, а сейчас еще немного о синтаксисе.

Оператор a [b] - постфиксный, с самым низким приоритетом. Т.е в выражении 60 Вт + 220 В * 10 А [кВт] сначала будет посчитано выражение слева от квадратных скобок (получится 2260 Вт), и уже оно будет переведено в киловатты: 2.26 кВт. Собственно, операторов приведения единиц измерения может быть в выражении сколько угодно, хотя смысла в этом немного - от того, в какой единице выражены промежуточные выражения, ответ не зависит! Тем не менее, можно их использовать для самопроверки, что на этом этапе выражение имеет именно ту размерность, которую мы полагали (если это не так, будет высвечена ошибка), а также для изменения порядка действий выражения. В частности, если мы написали выражение, заканчивающееся квадратными скобками, то можем быть уверены - приписав к нему что-то еще, мы не изменим порядка действий. Поэтому дописав его:
60 Вт + 220 В * 10 А [кВт] * 3 min [kW*hr], мы будем знать - сначала будет посчитано выражение слева и уже целиком домножено на 3 минуты. Это всяко удобнее, чем стирать [кВт] и запихивать круглые скобки!

Разумеется, что с помощью скобок мы можем менять приоритет и оператора []:
10 m * (10 m + (2 mm + 3mm) [m]) - сначала будет посчитана внутренняя скобка, к ней прибавится 10 метров, полученный результат будет переведен в метры (ну скорее проверено, что это действительно длина) и уже потом домножен на 10 м. Без внешних скобок мы бы получили ошибку - перевод площади в длину.


[Сложение и вычитание величин]

Сложение и вычитание величин
Правила просты: можно складывать величины одной размерности (например, длины), при этом, если единицы измерения не совпадают, они приводятся к размерности левого операнда. Если даже размерности не совпадают (длина и время), то делается попытка привести их на основе "допущений" (c=h=1 и иже с ними), и выдается либо объяснение, на что мы помножили выражение, либо сообщение об ошибке.

И еще одно замечание: безразмерный ноль прибавлять к размерной величине нельзя! Хотя ноль - он и в Африке ноль, но, честно говоря, я не могу придумать ситуации, когда это было бы необходимо. Зато, сделав первым слагаемым размерный ноль (например, 0 км), мы получим префиксный оператор приведения единиц измерения, т.е он будет действовать на выражение справа от себя! Не знаю, зачем это нужно, но пущай будет.


[Умножение, деление, возведение в степень и функции]

Умножение, деление, возведение в степень и функции
До сих пор калькулятор очень "нежно" относился к введенным единицам измерения - менял их лишь при необходимости. В случае умножения и деления первым делом все величины преобразуются в единицы СИ, скажем 1 Ом*мм^2/м превращается даже не в 1e-6 Ом*м, а в 1E-6 kg*(m)^3*(s)^(-3)*(A)^(-2), т.е выражается исключительно через базовые величины. Перемножить такие величины - раз плюнуть! Степени при подобных множителях складываются, после чего производится поиск - есть ли какое-нибудь "приличное" название у получившийся величины, вроде ньютонов, паскалей, Ом и пр. Если есть - именно они отображаются в результате.

Понятное дело, что любые величины можно возводить только в безразмерную действительную степень, в противном случае сразу выдается ошибка. Возможности по возведению в действительную степень неограниченны, т.е у нас может получиться величина 1 (m)^1,4142135623731 - почему бы и нет, вдруг нам захочется узнать длину береговой линии на заданном масштабе!

Большинство математических функций (тригонометрические прямые и обратные, обычные и гиперболические, над углами в радианах и градусах, десятичный, двоичный и натуральный логарифм, экспонента) требуют безразмерную величину в аргументе и безразмерную же возвращают. Правила те же - если величина обладает размерностью, калькулятор постарается от нее избавиться, скажем, при включенном c=1, sinh(300 km/s) даст результат 0,00100069245260747, т.е найдет по сути sinh(v/c), не забыв об этом предупредить.

Квадратный корень можно брать от любой величины, это частный случай возведения в степень. И также от любой величины можно брать абсолютное значение abs, аргумент arg, действительную Re, мнимую Im части и комплексное сопряжение Conj. abs(),Re(),Im(), Conj() вернут ту же величину, а arg от любой величины даст безразмерный угол.


[Работа с температурами]

Работа с температурами
Казалось бы, чего проще - сходу переводим все в кельвины и считаем уже в них. Не тут-то было, вся проблема в том что температура - величина "аффинная", а не "векторная", у нее задана не только единица, но и начало отсчета. Классический пример. Мы ищем разность температур, 40 Celsius - 20 Celsius, для этого переводим каждую температуру в кельвины, получаем 20 К, а мы-то хотим в Цельсиях, поэтому из 20 К вычитается 273.15 и мы получаем абсурдные -253,15 Celsius!

Mathcad долгое время вообще не включал температуру в свою систему единиц, чтобы избежать всей этой путаницы, но позже "по заявкам трудящихся" ввел ее, причем в виде двух разных размерностей - температуры и разности температур. Увы, и такое решение не решает проблему до конца. Либо наложить очень жесткие ограничения на то, что делать с температурами - складывать нельзя (это действительно, как будто бы не имеет физического смысла), только один раз вычесть. Но если так, то среднее арифметическое мы посчитать уже не сможем! Точнее, придется пойти обходным путем, написать T1 + (T2-T1)/3 + (T3-T1)/3 для 3-х температур. Без жестких ограничений начинаются неоднозначности.

Мне хотелось сделать так, чтобы операторы приведения единиц измерения можно было расставлять произвольно, и итоговый результат от этого не менялся, ведь именно этого мы ждем от физических величин! И в текущей реализации, пока мы остаемся в рамках температуры, оно работает как положено, при этом свобода действий не сужается.

Идея довольно проста, у нас на ходу вводятся величины типа K{dif}, K{2}, K{3}, K{-1} и т.д, где число в скобках - это множитель. Например, мы складываем 3 температуры
10 Celsius + 20 Celsius + 30 Celsius
Нам высвечивается результат: 60 Celsius{3} - т.е это уже не просто температура, а утроенная температура, все логично. Надо это для того, чтобы преобразования единиц по-прежнему работали корректно:
10 Celsius + 20 Celsius + 30 Celsius [K] даст 879,45 K{3}.
Это ровно то же самое, как если бы мы сначала перевели температуру в кельвины, а только потом их сложили. Если бы этой тройки не было, калькулятор не знал бы, как поступить. Прибавив к 60 Celsius классические 273.15, он бы получил результат, не имеющий никакого смысла.

Наш первый пример:
40 Celsius - 20 Celsius
дает ответ: 20 Celsius{dif}, здесь dif означает 0 (разность). Преобразуем в кельвины:
40 Celsius - 20 Celsius [K]
получаем ответ: 20 K{dif}. Ага, разность температур в 20 кельвинов и 20 град. цельсия - одно и то же!

Опробуем какие-нибудь физические задачки. К.п.д идеальной тепловой машины с температурой нагревателя 100 град. Цельсия, а температурой холодильника: 0 град. Цельсия:
(100 Celsius - 0 Celsius) / 100 Celsius
результат: 0,267988744472732, все правильно. Наверху была разница температур, 100 град Цельсия, внизу просто температура, 100 град. Цельсия. Когда настал черед деления, то, как мы знаем, все величины были переведены в базовые системы СИ, т.е в Кельвины. Наверху 100 Celsius{dif} превратился в 100 K{dif}, а внизу 100 Celsius в 373.15 K. При делении эти множители более не играют никакой роли, все сбрасывается просто до кельвинов, и приходим к верному ответу. В этой формуле к.п.д тепловой машины мы можем величины в каком угодно виде задавать - Цельсии, Кельвины, Фаренгейты (Fahrenheit, эту величину калькулятор тоже знает), Ранкины (Rankine), Реамюры (Reaumur), а потом еще в любом месте формулы расставить приведение единиц в квадратных скобках - а ответ от этого не изменится, мы найдем-таки правильный к.п.д.

Еще одна: находим мощность излучения нагретой до 400 град. Цельсия абсолютно черной поверхности площадью 1 м^2. Включаем галочки "c=1","h=1","k=1" (последнее - это постоянная Больцмана) и вводим:
pi^2/60 * 1 m^2 * (400 Celsius)^4 [W]

вот что получается:
Для преобразования из [(m)^2*(K)^4] в [W] выражение домножено на (c)^-2*(h)^-3*(k)^ 4
11642,8451079148 W

Тут мы еще вместо ввода постоянной Стефана-Больцмана целиком записали лишь ее безразмерный множитель, а все остальное было выведено автоматически, об этом чуть ниже.

Единственное, где могут возникнуть проблемы - это когда мы будем получать температуру из других величин, скажем поделим мощность нагревателя на теплоемкость воды и ее массу и все в этом роде. Тут, увы, весь контекст безвозвратно утерян - ответ получится в кельвинах и может означать как саму температуру, так и ее разность или что-то еще. Как это сделать наиболее адекватно - предстоит еще поразмыслить.


[СИ, СГС, c=h=1 и другие системы]

СИ, СГС, c=h=1 и другие системы
Изначально калькулятор работает с величинами СИ, и поэтому емкость в фарадах и длина в сантиметрах для него - вещи совершенно разные. Точно так же температура и энергия имеют разную размерность, и в этом нет ничего плохого - обозначая вроде бы одинаковые вещи разными именами, мы сохраняем дополнительную информацию, которая иначе бы пропала. В большинстве задач емкость не тождественна длине, время и пространство - вещи ну совершенно разные, энергия не имеет ничего общего с частотой, список можно продолжить.

Но когда надо, мы можем перейти от одних величин к другим, не вводя ручками никаких постоянных и даже не запоминая, нужно ли на них умножать или делить, и в какой степени. Найдем, к примеру, емкость Земли как одиночного шара. Для этого поставим галочку "4pi*epsilon0=1" и напишем:
6400 km [uF]
и получим:
Для преобразования из [km] в [uF] выражение домножено на 4pi*Epsilon0
712,096035874308 uF
это правильный ответ. Емкости других объектов можно посчитать похожим образом, применяя формулы в СГС и подставляя под конец фарады.

Чтобы поразвлечься с индуктивностью, нам нужно дополнительно поставить галочку "c=1":
1 m [H]
Для преобразования из [m] в [H] выражение домножено на (c)^-2*(4pi*Epsilon0)^-1
1,00000000000002E-7 H

(где-то по ходу дела возникла ошибка в 14-м знаке после запятой, надо будет снизить количество выводимых на экран символов, что ли)
Тоже неплохо. Магнитная постоянная равна 4pi*10^(-7) Гн/м, но уравнения Максвелла для СИ и СГС еще отличаются на 4pi, поэтому ответ совершенно правильный - 1 м = 10^(-7) Гн.

Аналогичным образом мы поступаем, когда применяем формулу откуда-нибудь из Ландау-Лифшица, при выводе которой было сказано, "для простоты примем c=h=1, позже константы можно восстановить исходя из размерности". И правда можно, PhysUnitCalc позволяет это сделать автоматически.

Замечу, что условия в меню "допустить, что..." не могут быть выбраны все сразу. Верхние 5 пунктов задают планковскую систему единиц, в которой все величины безразмерны. Проверим:

> 1 [m]
Для преобразования из [] в [m] выражение домножено на (c)^-1,5*(h)^0,5*(G)^0,5
1,61620087270685E-35 m
> 1 [s]
Для преобразования из [] в [s] выражение домножено на (c)^-2,5*(h)^0,5*(G)^0,5
5,39107113616167E-44 s
> 1 [kg]
Для преобразования из [] в [kg] выражение домножено на (c)^0,5*(h)^0,5*(G)^-0,5
2,17641873523423E-8 kg

Все совпадает - и формулы, и значения!
Нижний пункт "e=1" нужен, чтобы можно было легко переходить из вольтов в электрон-вольты и вообще как можно чаще не писать явно элементарный электрический заряд. Но если мы при включенных первых 5 включим еще и его, то выскочит ошибка - "добавление условия e=1 приводит к противоречию". Все верно, планковский заряд отличается от элементарного в корень из постоянной тонкой структуры, вот и получается у нас тождество типа sqrt(137)=1.

Можно поиграться, попробовать построить систему единиц вроде планковской, где e=1, но отсутствуют какие-то другие условия.


[Другие пряники: комплексные числа и оператор ||]

Другие пряники: комплексные числа и оператор ||
Можно как отдельное число использовать мнимую единицу i, можно и I, но нельзя j, потому что его легко спутать с джоулями. Пример:
2*pi*i*50 Hz.
Или можно записать мнимую величину как число, после которого сразу, без пробела идет i или j, например:
(1 + 5j) V.

Небольшое замечание: если написать sqrt(-1), мы получим ошибку Invalid floating point operation, но зато sqrt(-1+0i) даст нам искомое i. Дело в том, что мы продолжаем работать с действительными числами, пока где-то не появится комплексное.

И еще в PhysUnitCalc введена операция ||, x || y = x*y/(x+y) - именно так мы считаем сопротивление параллельно соединенных резисторов, индуктивностей или последовательно соединенных конденсаторов.

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



Программа занимает меньше 600 кбайт и не требует установки, вот ссылка для скачивания. Более подробное описание с перечнем всех поддерживаемых единиц измерения и математических функций напишу чуть позже.

математика, программки, physunitcalc

Previous post Next post
Up