[Home]

Комментарии к решению задачи в Maxima

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

Ссылки для скачивания размещены в конце статьи: ссылки на документы для скачивания.

Оглавление
Введение
Основы работы
Простейший пример использования
Полный список функций (в порядке объявления) и краткие комментарии к ним
Список функций (в алфавитном порядке)
Ссылки на документы для скачивания

Ссылки на внешние документы
Универсальный решатель умножителей
   Решатель умножителей. Постановка задачи
   Метод решения задачи
   Комментарии к решению задачи в Maxima
   Примеры использования решателя



Введение

Анализировать умножители можно с использованием предлагаемого здесь документа для Maxima с набором необходимых для этого функций (m_solver_core.wxmx). Для использования, необходимо открыть документ, выполнить команду меню для вычисления всех ячеек ([Cell], [Evaluate All Cells]), после чего можно будет анализировать умножители с использованием предоставленных функций, добавляя в документ свои команды. Документ содержит некоторое количество комментариев, поясняющих назначение функций.

Файл-документ дублируется пакетным файлом m_solver_core.mac, имеющим аналогичное содержимое и который можно загрузить в свой документ командой
batchload("m_solver_core.mac");
что избавляет от необходимости загромождать свой документ текстом используемых библиотечных функций. Если файл, использующий m_solver_core.mac и сам пакетный файл находятся в разных каталогах, потребуется указать полное имя файла (включающее путь к файлу), либо добавить каталог с данным пакетным файлом в список каталогов по умолчанию для поиска файлов.

Пакетный файл является обычным текстовым файлом и с его содержимым можно ознакомиться даже в отсутствие установленной системы Maxima.

Основы работы

solve_multiplier(circuit, nd, xc, a, F, IL)
Самая главная функция, собственно она и выполняет анализ умножителя. Функция имеет следующие аргументы:
circuit - сокращённая матрица соединений, описывающая структуру анализируемого умножителя; может быть задана непосредственно или сгенерирована с помощью функций create_circuitA, create_circuitB, create_circuitZ, создающих матрицы для предопределённых типов умножителей (подробнее о матрице соединений - далее);
nd - количество диодов в умножителе (которое равно коэффициенту умножения);
xc - список, содержащий значения ёмкостей конденсаторов, элемент с индексом j должен содержать ёмкость конденсатора Cj; количество элементов в списке должно быть равно количеству конденсаторов в схеме;
a - амплитуда питающего источника;
F - частота колебаний питающего источника;
IL - ток нагрузки.
Возвращаемое значение - список из трёх элементов:
1-й элемент - выходное напряжение (напряжение на нагрузке) при заданном токе нагрузки в установившемся режиме в начальной точке рассматриваемого цикла, т.е. пиковое значение;
2-й элемент - размах пульсаций выходного напряжения;
3-й элемент сам является списком и содержит напряжения на всех рассматриваемых ветвях цепи в характерных точках рабочего цикла (элементы 1..nb - напряжения u[1]..u[nb]; элементы nb+1..2*nb - напряжения ux[1]..ux[nb] и т.д.; напряжения u2[j] не включены в список); всего данный список содержит 4*nb элементов, где nb=nc+2, а nc - количество конденсаторов.

Рассмотрим подробнее сокращённую матрицу соединений circuit, которая описывает структуру умножителя. Вообще под матрицей соединений здесь мы понимаем матрицу размера nb*2 (nb строк, 2 столбца; nb - количество ветвей в цепи), каждая строка которой соответствует определённому элементу цепи и определяет, к каким узлам подключён этот элемент. То есть, circuit[j, 1] содержит номер узла, к которому подключён первый вывод ветви с номером j, а элемент матрицы circuit[j, 2] содержит номер узла, к которому подключён вывод 2 ветви с номером j.

Так как любой умножитель содержит определённые обязательные элементы, а его структура отвечает ряду обязательных требований, то у нас появляется возможность исключить из матрицы соединений избыточную информацию. Так, любой умножитель содержит диодную цепь, поэтому нет необходимости включать её описание в матрицу. Её наличие можно учесть, указав количество диодов в умножителе и используя определённое соглашение о нумерации узлов в диодной цепи. А именно, будем использовать последовательную нумерацию от 1 до nd+1, где nd - количество диодов (рис. %img:d_cir). Естественно, нумеровать диоды в диодной цепи также будем по порядку.

Нумерация узлов диодной цепи. Рис. %img:d_cir

Нагрузка всегда подключается между выходом (узел с номером nd+1) и общим узлом, поэтому нагрузку также не будем указывать явным образом.

Таким образом, для того чтобы полностью описать структуру умножителя, достаточно указать способ подключения всех конденсаторов и источника питания. Получившаяся сокращённая матрица будет содержать nc+1 строк, где nc - количество конденсаторов. Договоримся, что первые nc строк матрицы (1..nc) соответствуют конденсаторам С1..Cnc, а последняя строка - источнику.

Нумераций узлов в умножителе с чётным коэффициентом умножения. Рис. %img:en_even

Нумераций узлов в умножителе с нечётным коэффициентом умножения. Рис. %img:en_odd

И последний момент. Договоримся узлам, к которым подключён питающий источник, присваивать номера 1 и максимальный номер. При такой нумерации, в узловой матрице этим узлам будут соответствовать первая и последняя строки. Так как строки, соответствующие этим узлам мы должны будем вычеркнуть при составлении уравнений по первому правилу Кирхгофа, то фиксированное их расположение немного упрощает задачу. Следствием этого соглашения является то, что общий узел будет обязательно иметь номер либо 1, либо максимальный номер. Если коэффициент умножения напряжения чётный, то начало диодной цепи должно быть подключено к общему проводу (общему узлу), но первый узел диодной цепи, как мы договорились, всегда имеет номер 1, поэтому и общий узел получит этот номер (рис. %img:en_even). Если коэффициент нечётный, к началу диодной цепи подключается первый вывод питающего источника, тогда второй узел подключается к общему проводу. Но источник подключается между узлом 1 и узлом с максимальным номером, значит, в данном случае общий узел будет иметь максимальный номер (рис. %img:en_odd).

Пример составления сокращённой матрицы соединений для умножителя. Рис. %img:x3_matr

Рассмотрим пример, показывающий, каким образом по схеме умножителя может быть составлена сокращённая матрица соединений (рис. %img:x3_matr). Умножитель выбрали очень простой - Z-типа с коэффициентом 3. На рисунке показана нумерация узлов, отвечающая принятым ранее соглашениям. Тогда сокращённая матрица соединений может быть задана следующим образом:

circuit:matrix(
    [2, 5], /* C1 */
    [3, 1], /* C2 */
    [4, 5], /* C3 */
    [1, 5]  /* V-source */
);

Комментарии здесь поясняют, каким элементам соответствует каждая строка матрицы.

create_circuitA(nd)
create_circuitB(nd)
create_circuitZ(nd)
Функции возвращают сокращённую матрицу соединений для умножителя типа A, B, Z соответственно, содержащего nd диодов. Полученную матрицу можно использовать при вызове функции solve_multiplier(circuit, nd, xc, a, F, IL) в качестве аргумента circuit.

test_solve_multiplier(iterations) Функция предназначена для тестирования функции solve_multiplier путём применения её для анализа некоторых умножителей с заведомо известными характеристиками и проверки полученных результатов. В тестовый набор умножителей включаются несколько фиксированных вариантов, а также умножители типов A, B и Z с коэффициентами умножения от 1 до iterations включительно.

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

Простейший пример использования

Приведём пример, показывающий как использовать описанные инструменты на практике. Будем анализировать умножитель на 4 типа A (рис. %img:x4_exmpl); ёмкости всех конденсаторов мы предполагаем одинаковыми и равными C, амплитуду питающего источника считаем равной a, частоту равной F, а ток нагрузки считаем равным IL.

Умножитель на 4 типа A. Рис. %img:x4_exmpl

В этом случае можно использовать следующую последовательность команд.

/* Предполагается, что данная последовательность команд дописана в конце
   основного документа m_solver_core.wxmx
   Либо в начале нового документа выполнен вызов
   batchload("m_solver_core.mac");
 */
nd:4;
circuit:create_circuitA(nd);
xc:makelist(C, length(circuit)-1);
solve_multiplier(circuit, nd, xc, a, F, IL);

Мы используем переменную nd для хранения количества диодов,
nd:4;
это делает фрагмент более универсальным: данное значение используется при вызове двух функций, так что для анализа умножителя с другим коэффициентом, нам потребуется внести исправление только в одном месте.

Для создания сокращённой матрицы соединений circuit используется функция create_circuitA, с помощью которой можно получить матрицу для умножителя типа A с любым коэффициентом умножения:
circuit:create_circuitA(nd);

В нашем случае все конденсаторы имеют одинаковую ёмкость C, поэтому сформировать список ёмкостей очень просто:
xc:makelist(C, length(circuit)-1);
эта команда создаёт список размером length(circuit)-1, каждый элемент которого равен C. Здесь length(circuit) - это количество строк в матрице circuit, которое, как мы знаем, на 1 больше количества конденсаторов. Мы не указываем количество конденсаторов в явном виде, опять же для того, чтобы данный фрагмент был более универсальным и чтобы его было проще применить в других ситуациях.

После того, как все данные подготовлены, мы вызываем функцию для анализа умножителя:
solve_multiplier(circuit, nd, xc, a, F, IL);

В результате выполнения получим приблизительно следующий вывод.

\( \DeclareMathOperator{\abs}{abs} \newcommand{\ensuremath}[1]{\mbox{$#1$}} \)
(%i1) batchload("m_solver_core.mac");
\[\tag{%o1}\label{o1} D:\ensuremath{\backslash}Prj\ensuremath{\backslash}electronics\ensuremath{\backslash}multiplier\ensuremath{\backslash}m\_\,solver\_\,core.mac\]
(%i5) nd:4;
circuit:create_circuitA(nd);
xc:makelist(C, length(circuit)-1);
solve_multiplier(circuit, nd, xc, a, F, IL);
\[\tag{nd}\label{nd}4\] \[\tag{circuit}\label{circuit}\begin{pmatrix}2 & 6\\ 3 & 1\\ 4 & 2\\ 5 & 3\\ 6 & 1\end{pmatrix}\] \[\tag{xc}\label{xc}[C,C,C,C]\mbox{}\] \[\tag{%o5}\label{o5} [4a-\frac{13\mathit{IL}}{2CF},\frac{3\mathit{IL}}{CF},[a-\frac{2\mathit{IL}}{CF},2a-\frac{2\mathit{IL}}{CF},2a-\frac{9\mathit{IL}}{2CF},2a-\frac{9\mathit{IL}}{2CF},\ldots \]
Created with wxMaxima.

Как видим, в нашем умножителе выходное напряжение равно \(4a-\frac{13I_L}{2FC}\), т.е. напряжение холостого хода составит 4*a, падение напряжения род нагрузкой равно \(13I_L/(2FC)\). Размах пульсаций составит \(3I_L/(FC)\). Также видим, что в режиме холостого хода напряжение на первом конденсаторе равно a, на последующих составляет 2*a. При необходимости, можем посмотреть напряжение в рассматриваемые моменты времени на любом конденсаторе при наличии нагрузки.

Полученные результаты совпадают с тем, что нам было известно об умножителях типа A.

Полный список функций (в порядке объявления) и краткие комментарии к ним

set_row(A, i, r)
set_col(A, j, c)
create_circuitA(nd)
create_circuitB(nd)
create_circuitZ(nd)
get_node_matrix(circuit, nd)
exclude_orphan_branches(A)
get_tree_matrix(A)
get_closed_loop(A)
get_independent_loops(A)
switch_diodes(A, nd, k)
get_switch_equations(A, nd, k, x1, x2, xc)
solve_multiplier(circuit, nd, xc, a, F, IL)
test_solve_multiplier(iterations)

set_row(A, i, r)
Функция модифицирует в матрице A строку с индексом i, присваивая её элементам значения из списка r (в качестве r можно передать матрицу, тогда она будет преобразована в список). Следует обратить внимание, что модифицируется матрица-аргумент. Возвращаемое значение - изменённая матрица.

set_col(A, j, c)
Аналогична set_row, но изменяет столбец в матрице A, возвращаемое значение - изменённая матрица.

create_circuitA(nd)
create_circuitB(nd)
create_circuitZ(nd)
Возвращает матрицу соединений (сокращённую) для умножителей с коэффициентом умножения nd типа A, B, Z соответственно.

get_node_matrix(circuit, nd)
Функция возвращает узловую матрицу для умножителя, содержащего nd диодов, заданного сокращённой матрицей соединений circuit. При составлении узловой матрицы считается, что диоды закрыты (заменяются разрывами). Автоматически добавляется ветвь с номером nc+2 (нагрузка). Здесь nc - количество конденсаторов.

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

exclude_orphan_branches(A)
Функция возвращает узловую матрицу, полученную из узловой матрицы A путём исключения "висящих" ветвей. Висящей считаем ветвь, если хотя бы один из её выводов подключён к узлу, к которому не подключена никакая другая ветвь. Процесс исключения осуществляется итерационно: если на предыдущей итерации удалось исключить какую-либо ветвь, выполняется очередная итерация, так как исключение одной ветви может сделать "висящими" другие ветви. В результате оставляются только те ветви, которые входят в состав каких-либо замкнутых контуров. В связи с этим, функция является удобным инструментом для выделения контура в чистом виде.

get_tree_matrix(A)
Функция для цепи, заданной своей узловой матрицей A, строит дерево (граф, не содержащий контуров, такой, что включение в него любой не вошедшей в дерево ветви приводит к образованию контура). Возвращаемое значение - список из двух элементов, первый элемент списка - построенное дерево в виде узловой матрицы этого дерева; второй элемент - список с номерами ветвей, не вошедших в дерево.

В реализации данной функции используется довольно примитивный, но очень простой и очевидный алгоритм: начинаем с пустого графа (которому соответствует нулевая узловая матрица), затем поочерёдно добавляем каждую из ветвей исходной цепи. Если возник контур, ветвь убираем из строящегося дерева (добавляем её номер в список ветвей, не входящих в дерево), если контуров не появилось, оставляем ветвь в дереве. Наличие контура выявляем очень просто: применяем функцию удаления висящих ветвей exclude_orphan_branches(A); если в результате получилась нулевая матрица - контуров нет, а если ненулевая - хотя бы один контур есть.

Построение дерева - эффективный способ выявления замкнутых контуров в цепи: добавляя поочерёдно к дереву не вошедшие в него ветви, найдём все независимые контуры цепи.

get_closed_loop(A)
Функция возвращает строку для матрицы контуров, соответствующую контуру, найденному в узловой матрице A. Для нормальной работы функции, узловая матрица A должна содержать один контур (дополнительно допускаются висящие ветви, так как перед поиском контура функция автоматически их удаляет). Функция возвращает значение в виде списка, длина которого равна количеству ветвей в цепи. Элемент списка с индексом j равен +1 или -1, если ветвь с номером j входит в найденный контур (знак зависит от ориентации ветви относительно выбранного направления обхода контура) и элемент равен 0, если ветвь в контур не входит.

get_independent_loops(A)
Функция возвращает матрицу независимых контуров для цепи, заданной узловой матрицей A. Для получения матрицы контуров, сначала по узловой матрице A строится дерево для рассматриваемой цепи, после чего, поочерёдно добавляя не вошедшие в дерево ветви, выявляем все независимые контуры в цепи. Применяя функцию get_closed_loop(A), построчно формируем матрицу-результат.

Матрица независимых контуров даёт возможность записать контурные уравнения (уравнения по второму правилу Кирхгофа) в компактной матричной форме B*u=O, где B - матрица независимых контуров, u - вектор-столбец напряжений на всех ветвях, O - нулевой вектор-столбец, размер которого равен количеству строк в матрице B.

switch_diodes(A, nd, k)
Функция возвращает узловую матрицу для цепи, получаемой из цепи с исходной узловой матрицей A при замыкании всех диодов с нечётными номерами (если k=1) или с чётными номерами (если k=2); общее количество диодов задаётся с помощью аргумента nd.

Замыкание каждого из диодов мы рассматриваем как объединение узлов, к которым диод подключён, в общий узел. Узловая матрица получаемой при этом цепи получается из исходной матрицы объединением строк, соответствующих объединяемым узлам: две строки заменяем одной, в которую переносим ненулевые элементы из исходных двух строк. Исходя из принципа работы умножителя, можно утверждать, что кроме диода, нет других элементов, подключаемых непосредственно между двумя объединяемыми узлами. Из этого следует, что в исходной узловой матрице в соответствующих строках элементы в одном столбце не могут быть одновременно ненулевыми. А значит, для объединения двух строк можно просто их сложить.

get_switch_equations(A, nd, k, x1, x2, xc)
Функция формирует список уравнений, составленных по первому и второму правилу Кирхгофа для одной из активных фаз рабочего цикла умножителя.
Функция имеет следующие аргументы:
A - исходная узловая матрица (для состояния цепи при разомкнутых диодах);
nd - общее количество диодов в умножителе;
k - параметр, определяющий, какие диоды в этой фазе переходят в открытое состояние; если k=1 открываются диоды с нечётными номерами; если k=2, то открываются диоды с чётными номерами;
x1 - список переменных - напряжений на ветвях цепи в начале фазы;
x2 - список переменных - напряжений на ветвях цепи в конце фазы;
xc - список ёмкостей конденсаторов умножителя.

solve_multiplier(circuit, nd, xc, a, F, IL)
Основная функция, выполняющая анализ умножителя. В данной функции выполняется построение системы линейных уравнений (из уравнений по первому и второму правилу Кирхгофа для каждой из четырёх фаз рабочего цикла; уравнений питающего источника; уравнений установившегося режима). Решая полученную систему, получаем искомый результат.

Подробнее об аргументах, возвращаемом значении и использовании этой функции смотрите в предыдущем пункте "Основы работы".

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

В данной реализации функции solve_multiplier не осуществляется исключение зависимых уравнений и доопределение системы дополнительными уравнениями для таких случаев. Дело в том, что Maxima успешно справляется с решением систем линейных уравнений, содержащих зависимые уравнения. При этом выдаётся предупреждение об исключении некоторых уравнений из системы, что неплохо, так как является сигналом пользователю о неблагополучии в его схеме. Результат для выходного напряжения умножителя и размаха пульсаций оказывается однозначным и не зависящим от дополнительных параметров.

test_solve_multiplier(iterations)
Функция предназначена для тестирования результатов, возвращаемых функцией solve_multiplier для умножителей типов A, B, Z с коэффициентами умножения от 1 до iterations и нескольких других предопределённых умножителей с заранее известными характеристиками. Функция может быть полезна для проверки работоспособности библиотеки после внесения в неё изменений.

Список функций (в алфавитном порядке)

create_circuitA(nd)
create_circuitB(nd)
create_circuitZ(nd)
exclude_orphan_branches(A)
get_closed_loop(A)
get_independent_loops(A)
get_node_matrix(circuit, nd)
get_switch_equations(A, nd, k, x1, x2, xc)
get_tree_matrix(A)
set_col(A, j, c)
set_row(A, i, r)
solve_multiplier(circuit, nd, xc, a, F, IL)
switch_diodes(A, nd, k)
test_solve_multiplier(iterations)

Ссылки на документы для скачивания

Скачать m_solver_core.wxmx
Maxima-документ, содержащий функции для анализа умножителей.

Скачать m_solver_core.mac
Пакетный файл, содержащий исходный текст функций для анализа умножителей. Имеет формат простого текстового файла и может использоваться для ознакомления без использования системы Maxima.

author: hamper; date: 2019-03-13
  @Mail.ru