Библиотека SFILE95 — API-документация
Пакет TMC Suite. Статическая библиотека работы с бинарными S-файлами (матрицами рассеяния). Язык документации: русский. Все сигнатуры приведены по исходникам из
src/libs/SFILE95/и общим заголовкам изsrc/Include/.
1. Назначение библиотеки
SFILE95 — статическая библиотека (StaticLibrary, UseOfMfc=false, собирается под win32 и x64) для работы с S-файлами — бинарными файлами матриц рассеяния формата TAMIC/TMC.
S-файл — это файл с меткой "SMT" (Scattering MaTrix) версии 102, который хранит многочастотную матрицу рассеяния многополюсника: для каждой частотной точки записывается комплексная S-матрица, а также служебная информация о сетке экстраполяции, числе входов и числе мод на входах.
Библиотека предоставляет:
- открытие/закрытие и низкоуровневое чтение/запись блоков S-файла;
- чтение всех частотных точек S-матрицы в память (
read_S_matrix); - запись одной частотной точки (
save_S_matrix) с формированием заголовка при первой точке; - работу с глобальной таблицей частот
FREQUENCY(сетка частот, единицы измерения Hz/KHz/MHz/GHz, текущая точка); - объединение и конкатенацию двух многочастотных S-матриц без дубликатов с сортировкой по частоте (
Unite_two_S,S_add); - сохранение/обновление отдельного столбца (входа) S-матрицы для заданной частоты (
save_S_matrix_element); - импорт элементов S-матрицы из текстовых файлов HFSS и CST;
- ведение таблиц смещений (offset tables) частотных точек внутри файла;
- вывод текстовой таблицы S-матрицы (модуль/фаза, КСВН/потери) в файл листинга (
put_S_table).
2. Состав
В сборку SFILE95.vcxproj входят 13 файлов .cpp:
| Файл | Назначение (кратко) |
|---|---|
Errors.cpp |
Заглушка обработки ошибок |
Frqdata.cpp |
Глобальная таблица частот FREQUENCY |
Read_s.cpp |
Чтение всех частотных точек S-матрицы |
S_file.cpp |
Низкоуровневая работа с файлом (открыть/закрыть/блоки) |
S_memf.cpp |
Память и заглушки (alloc_mem_err, free_mem, и т.п.) |
S_remt.cpp |
Чтение элементов S-матрицы из TMC/HFSS/CST |
S_table.cpp |
Печать текстовой таблицы S-матрицы в листинг |
S_wemt.cpp |
Сохранение одного столбца (входа) S-матрицы |
Sadd.cpp |
Объединение двух S-файлов (S_add) |
Sofftbl.cpp |
Таблица смещений частотных точек |
Unite_s.cpp |
Объединение двух частотных сеток в памяти |
Write_s.cpp |
Запись одной частотной точки + заголовок |
Wrrd_s.cpp |
Формирование имени временного S-файла, копирование |
Legacy-файлы вне сборки (не документируются)
Следующие файлы присутствуют в каталоге, но не включены в SFILE95.vcxproj и поэтому в данной документации не описываются:
Read_s1.cpp, S_CUT.CPP, S_DB.CPP, STXTABLE.CPP, SREAD.CPP, WRTSLST.CPP, LISTING.CPP, OUTTRACE.CPP, MAIN_S.CPP, GTARGENV.CPP.
3. Структуры и типы данных
Типы
_real,_complex,INT_1,WORD,DWORDопределены во внешних заголовках (typedef.h,complex1.h). В большинстве сборок_real—double(8 байт),_complex— параdouble(16 байт),INT_1— однобайтовый целочисленный тип,WORD— 16 бит,DWORD— 32 бита.
3.1. S_INDEX (Postpro.h)
Индекс сетки экстраполяции: имена файлов и шаги дискретизации по трём осям.
typedef struct {
char *tpl_name; // имя файла исходных данных (*.tpl)
char *S_name; // имя файла S-матрицы (*.s)
double delta1; // шаг сетки по оси X
double delta2; // шаг сетки по оси Y
double delta3; // шаг сетки по оси Z
} S_INDEX;
| Поле | Тип | Смысл |
|---|---|---|
tpl_name |
char* |
Имя файла исходных данных (шаблона *.tpl) |
S_name |
char* |
Имя файла S-матрицы (*.s) |
delta1 |
double |
Шаг сетки по оси X |
delta2 |
double |
Шаг сетки по оси Y |
delta3 |
double |
Шаг сетки по оси Z |
При экстраполяции используется массив из extrapol_flag+1 элементов S_INDEX.
3.2. INPUT_DATA (Postpro.h)
Описание портовой структуры многополюсника.
typedef struct {
INT_1 num; // число входов (портов)
INT_1 array[MAX_INPUT_NUM]; // число мод на каждом входе
INT_1 dim; // размерность S-матрицы (сумма мод по всем входам)
} INPUT_DATA;
| Поле | Тип | Смысл |
|---|---|---|
num |
INT_1 |
Число входов (портов) устройства |
array[] |
INT_1[MAX_INPUT_NUM] |
Число распространяющихся мод на каждом входе |
dim |
INT_1 |
Размерность квадратной S-матрицы (сумма мод по всем входам); матрица имеет dim × dim комплексных элементов |
MAX_INPUT_NUM определяется во внешнем заголовке tmclimit.h.
3.3. S_HEADER (S_file.h)
Заголовок таблицы смещений (служебная структура).
typedef struct {
WORD cPs; // число "pascal"-строк в файле
WORD cbSize; // размер таблицы смещений в байтах
WORD cnFrqNum; // число частот
} S_HEADER;
| Поле | Тип | Смысл |
|---|---|---|
cPs |
WORD |
Счётчик «pascal»-строк в заголовке файла |
cbSize |
WORD |
Размер таблицы смещений (байт) |
cnFrqNum |
WORD |
Число частотных точек |
3.4. S_OFFSET / _OFFSET (S_file.h)
Одна запись таблицы смещений: частота и позиция блока в файле.
typedef struct {
_real frq; // частота
DWORD lOffset; // смещение (позиция) блока параметров в файле
} _OFFSET;
typedef _OFFSET S_OFFSET;
| Поле | Тип | Смысл |
|---|---|---|
frq |
_real |
Значение частоты |
lOffset |
DWORD |
Смещение (offset) блока многополюсных параметров в файле для этой частоты |
3.5. S_OFFSET_TABLE (S_file.h)
Таблица смещений целиком.
typedef struct {
WORD cbSize; // размер таблицы (байт)
WORD cnFrqNum; // число частот
S_OFFSET *lpOffset; // указатель на массив записей S_OFFSET
} S_OFFSET_TABLE;
| Поле | Тип | Смысл |
|---|---|---|
cbSize |
WORD |
Размер таблицы смещений (байт) |
cnFrqNum |
WORD |
Число частотных точек в таблице |
lpOffset |
S_OFFSET* |
Указатель на массив записей смещений |
3.6. INTERP_COEFF (S_file.h)
Коэффициенты сплайн-интерполяции по частоте.
typedef struct {
_complex *lpxC0; // значения функции
_complex *lpxC1; // коэффициент сплайна 1-й степени
_complex *lpxC2; // коэффициент сплайна 2-й степени
_complex *lpxC3; // коэффициент сплайна 3-й степени
} INTERP_COEFF;
| Поле | Тип | Смысл |
|---|---|---|
lpxC0 |
_complex* |
Значения функции (S-параметров) в узлах |
lpxC1 |
_complex* |
Коэффициент сплайна при 1-й степени |
lpxC2 |
_complex* |
Коэффициент сплайна при 2-й степени |
lpxC3 |
_complex* |
Коэффициент сплайна при 3-й степени |
3.7. FREQUENCY (внешний frqdata.h)
Глобальная таблица частот. Заголовок frqdata.h не найден в src/Include; структура реконструирована по обращениям в Frqdata.cpp.
| Поле | Тип | Смысл |
|---|---|---|
num |
int |
Индекс текущей частотной точки |
max |
int |
Число частотных точек в сетке |
f |
_real* |
Массив значений частот (длина — до FREQ_MAX_NUM) |
code |
int |
Код текущей единицы измерения (индекс в unit[]/item[]) |
unit[4] |
_real[4] |
Коэффициенты единиц: Hz = 1, KHz = 1e3, MHz = 1e6, GHz = 1e9 |
item[4] |
char*[4] |
Строки единиц: "_Hz", "KHz", "MHz", "GHz" |
Значения по умолчанию (из Frqdata.cpp): num = 0, max = 0, массив f — статический буфер frq_buff[FREQ_MAX_NUM], code = 3 (текущая единица — GHz).
3.8. Константы (S_file.h)
| Константа | Значение | Смысл |
|---|---|---|
S_WR |
0 |
Режим открытия на запись |
S_RD |
1 |
Режим открытия на чтение |
S_PS_NUMBER |
7 |
Базовое число «pascal»-строк в заголовке |
OFF_TBL_MAIN |
1 |
Основная таблица смещений |
OFF_TBL_APPR |
2 |
Таблица смещений коэффициентов интерполяции |
SMT_LABEL |
"SMT" |
Метка файла матрицы рассеяния |
SMT_VERSION |
102 |
Номер версии формата |
S_UNKNOWN |
-1 |
Унитарность матрицы не определена |
S_UNITARY |
0 |
Матрица унитарна |
S_NOT_UNITARY |
1 |
Матрица не унитарна |
UNITARY_THRESH |
1.0e-12 |
Порог проверки унитарности |
4. Публичные функции
О макросах
_far,_near,_fortran. Это атрибуты модели памяти и соглашения о вызове из старого 16/32-битного кода (Microsoft C / ранний Visual C++). В современной 32/64-битной сборке они, как правило, разворачиваются в пустоту или в стандартную конвенцию вызова и на семантику не влияют. Для краткости ниже в сигнатурах эти макросы опускаются (показывается «чистый» прототип на C). Полные прототипы с_far/_fortranсм. в заголовкеS_file.h.
4.1. Обработка ошибок — Errors.cpp
int put_error_messege(int err_num, ...)
Обработка (вывод) сообщения об ошибке.
- Параметры:
err_num(int) — код ошибки (см. раздел 5);...— переменное число аргументов для форматирования сообщения.- Возврат: всегда
0. - Важно: в данной сборке функция является заглушкой — всё тело закомментировано. Никаких сообщений не выводится, обработки ошибок фактически нет. Возвращаемое значение всегда
0(см. раздел 5 о последствиях).
4.2. Таблица частот — Frqdata.cpp
Все функции работают с единственной глобальной статической структурой FREQUENCY frq.
int set_frequency(_real f0, _real df, int nf)
Задать равномерную сетку частот: первая частота, шаг, число точек.
- Параметры:
f0(_real) — первая частота (в текущих единицах; домножается наunit[code]);df(_real) — шаг частоты (в текущих единицах);nf(int) — число точек.- Возврат:
0.
int set_frequency_arr(_real *ftmp, int nf)
Задать сетку частот напрямую из массива.
- Параметры:
ftmp(_real*) — массив значений частот (в текущих единицах);nf(int) — число точек.- Возврат:
0.
_real get_frq_f0(int unit_flag)
Получить первую частоту.
- Параметры:
unit_flag(int) — если1, результат в текущих единицах (делится наunit[code]); иначе — в базовых (Гц). - Возврат: значение первой частоты
frq.f[0].
_real get_frq_df(int unit_flag)
Получить шаг частоты (f[1] - f[0]; при max == 1 возвращает 0).
- Параметры:
unit_flag(int) —1→ в текущих единицах, иначе — в базовых. - Возврат: шаг частоты.
int get_frq_nf(void)
- Возврат: число точек сетки (
frq.max).
int set_frq_nf(int nMax)
Задать число точек.
- Параметры:
nMax(int) — число точек; допустимо0 < nMax <= FREQ_MAX_NUM. - Возврат:
0при успехе;-1при нарушении диапазона (при этом вызываетсяput_error_messege(BAD_NF_PARM, ...)).
char* get_frq_item(int num)
- Параметры:
num(int) — индекс единицы (0..3). - Возврат: строка единицы измерения (
"_Hz","KHz","MHz","GHz").
char* get_current_frq_item(void)
- Возврат: строка текущей единицы (
frq.item[frq.code]).
_real get_frq_unit(int num)
- Параметры:
num(int) — индекс единицы (0..3). - Возврат: коэффициент единицы (
1,1e3,1e6,1e9).
void set_frq_item_num(int num)
Установить код текущей единицы измерения.
- Параметры:
num(int) — индекс единицы (0..3).
int get_frq_item_code(void)
- Возврат: код текущей единицы (
frq.code).
_real get_frq_element(int index)
- Параметры:
index(int) — индекс точки. - Возврат: значение частоты
frq.f[index](в базовых единицах).
void set_frq_element(_real fValue, int index)
Записать частоту по индексу как есть (без пересчёта единиц).
- Параметры:
fValue(_real) — значение;index(int) — индекс точки.
void set_frq_element_unit(_real fValue, int index)
Записать частоту по индексу с переводом из текущих единиц в базовые (домножение на unit[code]).
- Параметры:
fValue(_real) — значение в текущих единицах;index(int) — индекс точки.
_real get_current_frq(void)
- Возврат: значение текущей частоты
frq.f[frq.num].
double get_current_dbl_frq(void)
- Возврат: текущая частота, приведённая к
double(используется при записи в файл).
int get_current_frq_num(void)
- Возврат: индекс текущей частотной точки (
frq.num).
void set_current_frq_num(int num)
Установить индекс текущей частотной точки.
- Параметры:
num(int) — индекс.
FREQUENCY* GetPointerToFrq(void)
- Возврат: указатель на глобальную структуру
frq.
4.3. Низкоуровневая работа с файлом — S_file.cpp
FILE* Get_S_FILE(void)
- Возврат: указатель
FILE*на открытый S-файл (NULL, если файл не открыт).
void Set_PS_Number(int nNum)
Задать число «pascal»-строк в заголовке (хранится в статической переменной).
- Параметры:
nNum(int) — число строк.
int Get_PS_Number(void)
- Возврат: ранее заданное число «pascal»-строк.
int Open_S_file(char *szFile, int nOpenMode)
Открыть S-файл.
- Параметры:
szFile(char*) — имя файла;nOpenMode(int) — режим:S_RD(1) → открытие"rb"; иначе (S_WR) →"wb+", если текущая частотная точка == 0 (новый файл), либо"rb+", если != 0 (дозапись в существующий).- Возврат:
0при успехе;-1при ошибке (вызываетсяput_error_messege(ERROR_OPEN_S, ...)). - Примечание: при успешном открытии выделяется буфер
BUFSIZчерезalloc_mem_errи назначается файлу черезsetbuf(если не задан_NDP2).
void Close_S_file(void)
Закрыть S-файл (fclose), обнулить указатель, освободить буфер ввода-вывода.
int skip_string(void)
Пропустить одну «pascal»-строку: читает длину (INT_1), затем fseek на длину строки + разделитель.
- Возврат:
0при успехе;-1при ошибке чтения/позиционирования.
int write_S(void *ptr, size_t size)
Записать блок данных в файл (fwrite одним элементом размера size).
- Параметры:
ptr(void*) — данные;size(size_t) — размер блока (байт). - Возврат:
0при успехе;-1при ошибке записи.
int read_S(void *string, size_t size)
Прочитать блок данных из файла (fread одним элементом размера size).
- Параметры:
string(void*) — буфер приёма;size(size_t) — размер блока (байт). - Возврат:
0при успехе;-1при ошибке чтения.
4.4. Память и служебные заглушки — S_memf.cpp
void* alloc_mem_err(long size)
Выделить память (malloc). При неудаче вызывает put_error_messege(FATAL_MEM_ALLOC_ERROR) (заглушка).
- Параметры:
size(long) — размер блока (байт). - Возврат: указатель на блок или
NULLпри неудаче.
int free_mem(void *mem_ptr)
Освободить память (free).
- Параметры:
mem_ptr(void*) — указатель на блок. - Возврат:
0.
int free_mem_null(void **ptr)
Освободить память и обнулить указатель.
- Параметры:
ptr(void**) — адрес указателя; после вызова*ptr == NULL. - Возврат:
0.
void stat_messege(int num, char *mes)
Пустая заглушка (тело — return;). Ничего не делает.
int get_comp_file_flag(void)
Заглушка. Всегда возвращает 0.
- Возврат:
0. - Важно: многие ветки (
copy_S_matrix, отключениеput_S_table) проверяют этот флаг; так как он всегда0, соответствующая логика фактически неактивна.
4.5. Чтение S-матрицы — Read_s.cpp
int read_S_matrix(char *szFileName, S_INDEX **si, int *extrapol_flag, _complex ***sss, FREQUENCY *frq_out, INPUT_DATA **id)
Прочитать все частотные точки S-матрицы из файла в память.
- Параметры:
szFileName(char*) — имя S-файла;si(S_INDEX**) — выход: массив индексов сетки (extrapol_flag+1элементов), выделяется внутри;extrapol_flag(int*) — выход: флаг экстраполяции (0 — одна сетка, 1 — две, 2 — три);sss(_complex***) — выход: массив матриц по частотам (frq_out->maxуказателей на массивыdim*dimкомплексных значений);frq_out(FREQUENCY*) — выход: заполненная таблица частот;id(INPUT_DATA**) — выход: портовая структура.- Возврат:
0— успех;-1— ошибка чтения;-2— ошибка открытия файла;-3— нехватка памяти.- Внутренние (
static) функции:Read_TITLE,Read_GRID,read_string,read_CR— служебные, наружу не экспортируются.
void Free_GRID_Index(S_INDEX **si, int extrapol_flag)
Освободить массив S_INDEX (extrapol_flag+1 элементов вместе с именами файлов).
- Параметры:
si(S_INDEX**) — адрес массива;extrapol_flag(int) — флаг экстраполяции.
void Free_S_read(_complex ***sss, int nFrqNum)
Освободить массив матриц для nFrqNum частотных точек.
- Параметры:
sss(_complex***) — адрес массива;nFrqNum(int) — число частотных точек.
4.6. Чтение элементов S-матрицы (TMC / HFSS / CST) — S_remt.cpp
int read_S_matrix_element_TMC(...)
Прочитать один элемент S-матрицы из файла формата TMC/TAMIC (через read_S_matrix). Заполняет массив комплексных значений sss и массив частот f1 (double) по nPoint точкам.
- Возврат:
0при успехе,-1при ошибке.
int read_S_matrix_element(int *in1, int *mod1, int *in2, int *mod2, char *filename, _complex **sss, double **f1, int *nPoint)
Прочитать один элемент S-матрицы, автоматически перебирая форматы: сначала TMC, затем HFSS, затем CST.
- Параметры:
in1,mod1(int*) — номер входа 1 и моды 1;in2,mod2(int*) — номер входа 2 и моды 2;filename(char*) — имя файла;sss(_complex**) — выход: массив комплексных значений (выделяется внутри);f1(double**) — выход: массив частот;nPoint(int*) — выход: число точек.- Возврат: всегда
0. Результат определяется по*nPoint: значение<= 0означает неудачу (ни один формат не подошёл).
int read_S_matrix_element_HFSS(int *in1, int *mod1, int *in2, int *mod2, char *filename, _complex **sss, double **f1, int *nPoint)
Прочитать элемент S-матрицы из текстового файла HFSS.
- Параметры: аналогичны
read_S_matrix_element. - Возврат:
0/-1.
int SMatrixElementHFSS_InpMod(int *in1, int *mod1, int *in2, int *mod2, char *filename)
Определить номера входов/мод для элемента из HFSS-файла.
- Возврат: код результата (см. реализацию).
int SMatrixElementHFSS_ModMax(char *filename, int *pnInp)
Определить максимальное число мод (для входа *pnInp) в HFSS-файле.
int SMatrixElementHFSS_InpMax(char *filename)
Определить число портов (входов) в HFSS-файле.
int ChooseString(char *pszBuf, char *pszIdentifInput, char *pszIdentifMode, int *pnInp, int *pnMod)
Разобрать строку HFSS-файла, выделив номер порта и номер моды.
- Параметры:
pszBuf(char*) — разбираемая строка;pszIdentifInput(char*) — идентификатор-признак входа;pszIdentifMode(char*) — идентификатор-признак моды;pnInp(int*) — выход: номер входа;pnMod(int*) — выход: номер моды.
int SMatrixElementHFSS_FreqArray(int *in1, int *mod1, int *in2, int *mod2, char *filename, double **f1, _complex **sss, int *nPoint, int *nMatrixSize)
Сформировать массив частот и значений для элемента из HFSS-файла (агрегирующая функция).
void SMatrixElementHFSS_FreqArrayCalculation(char *filename, double **f1, int *nPoint, int *nMatrixSize)
Подсчитать число точек и размер матрицы по HFSS-файлу.
void SMatrixElementHFSS_FreqArrayAllocation(double **f1, _complex **sss, int *nPoint)
Выделить память под массивы частот и значений.
void SMatrixElementHFSS_FreqArrayRead(int *in1, int *mod1, int *in2, int *mod2, char *filename, double **f1, _complex **sss, int *nPoint, int *nMatrixSize)
Прочитать частоты и значения элемента из HFSS-файла в выделенные массивы.
Аналоги для CST — read_S_matrix_element_CST(...) и SMatrixElementCST_*(...)
Полностью аналогичный набор функций для импорта элементов S-матрицы из текстовых файлов CST.
Внутренняя функция: ChooseString1 — static, в заголовках отсутствует, используется только внутри S_remt.cpp. Наружу не экспортируется.
4.7. Сохранение одного столбца (входа) — S_wemt.cpp
int save_S_matrix_element(int in1, char *filename, _complex *sss, double f1, int nInput)
Сохранить один столбец S-матрицы (соответствующий входу in1) для частоты f1.
- Параметры:
in1(int) — номер входа (столбца);filename(char*) — имя S-файла;sss(_complex*) — массив комплексных значений столбца;f1(double) — частота;nInput(int) — число входов.- Логика:
- если файла нет — создаётся новая матрица;
- если такой частоты в файле нет — данные пишутся во временный файл
<filename>$и объединяются с основным черезS_add; - если частота уже есть — соответствующая запись обновляется и файл переписывается.
- Возврат:
0при успехе;-1при ошибке.
4.8. Таблица смещений — Sofftbl.cpp
int update_offset_table(_real frq, int num, int nTBL_Flag)
Записать (обновить) запись таблицы смещений для частоты frq и встать в конец файла.
- Параметры:
frq(_real) — значение частоты;num(int) — индекс частотной точки (внутри функции увеличивается на 1 при записи счётчика частот);nTBL_Flag(int) — какую таблицу обновлять:OFF_TBL_MAIN(1) — основная (пропускается на 2 «pascal»-строки меньше),OFF_TBL_APPR(2) — таблица коэффициентов интерполяции.- Возврат:
0при успехе;-1при ошибке позиционирования/записи.
4.9. Объединение частотных сеток — Unite_s.cpp
int Unite_two_S(FREQUENCY *frq_out1, INPUT_DATA *id1, _complex **sss1, FREQUENCY *frq_out2, INPUT_DATA *id2, _complex **sss2, FREQUENCY *frq_out, INPUT_DATA **id, _complex ***sss)
Объединить две многочастотные S-матрицы в одну: частотные точки сливаются без дубликатов, результат сортируется по частоте (qsort с компаратором cmpgle).
- Параметры:
frq_out1,id1,sss1— первая матрица (частоты, портовая структура, массив матриц);frq_out2,id2,sss2— вторая матрица;frq_out(FREQUENCY*) — выход: объединённая таблица частот;id(INPUT_DATA**) — выход: портовая структура результата;sss(_complex***) — выход: массив матриц результата.- Возврат:
0при успехе;-1при ошибке (число частот превысилоFREQ_MAX_NUMлибо нехватка памяти).
int cmpgle(const void *fs1, const void *fs2) — внутренняя
Компаратор для qsort: сравнение элементов по значению частоты (по возрастанию). Используется только внутри Unite_s.cpp.
4.10. Запись S-матрицы — Write_s.cpp
int save_S_matrix(_complex *sss, INPUT_DATA *id, char *S_filename, S_INDEX *si, int extrapol_flag)
Записать одну частотную точку S-матрицы в файл.
- Параметры:
sss(_complex*) — матрица рассеяния (id->dim * id->dimкомплексных значений);id(INPUT_DATA*) — портовая структура;S_filename(char*) — имя S-файла;si(S_INDEX*) — массив индексов сетки (extrapol_flag+1элементов);extrapol_flag(int) — флаг экстраполяции (0/1/2).- Логика:
- при первой точке (
get_current_frq_num() == 0) задаётся число «pascal»-строкS_PS_NUMBER + 2*extrapol_flagи записывается заголовок: метка/версия (Write_TITLE), две строки TITLE (MAIN_LABEL,TWP_LABEL), GRID-строка (Write_GRID), имена файлов.tpl/.sизsi, две пустые таблицы смещений (основная — наget_frq_nf()частот, и для коэффициентов интерполяции — на0); - затем для каждой точки:
update_offset_table(фиксирует позицию), запись частоты (_real), записиINPUT_DATA(num, массив мод,dim), разделитель, матрица, разделитель. - Возврат:
0при успехе;-1при ошибке (при ошибке вызываетсяput_error_messege(ERROR_WRITE_S, ...)). - Внутренние (
static) функции:Write_TITLE,Write_GRID,write_offset_table,write_string,write_CR— служебные, наружу не экспортируются.
4.11. Имена временных файлов и копирование — Wrrd_s.cpp
void make_S_matrix_name(char *S_name, S_INDEX *si)
Сформировать имя временного S-файла по имени шаблона .tpl и шагу сетки. Заполняет поля si->tpl_name, si->S_name, si->delta1..3.
- Параметры:
S_name(char*) — выходной буфер имени;si(S_INDEX*) — индекс сетки (заполняется).- Зависимость значений
delta1..3от модели: _MODEL_E,_MODEL_H— шаг изget_data_const_delta;_MODEL_IC— шаг изGet_Mesh_Size_X/Get_Mesh_Size_Y;_MODEL_M,_MODEL_W— нули.
int copy_S_matrix(void)
Скопировать временный S-файл в выходной, если установлен get_comp_file_flag().
- Возврат:
0. - Важно: в данной сборке
get_comp_file_flag()— заглушка, всегда0, поэтому функция фактически ничего не копирует и просто возвращает0.
4.12. Объединение двух S-файлов — Sadd.cpp
int S_add(char *filename, char *filename1)
Прочитать две S-матрицы из файлов, сравнить их сетки (Compare_S_ind), объединить (Unite_two_S) и записать результат в filename.
- Параметры:
filename(char*) — первый файл; в него же пишется результат объединения;filename1(char*) — второй файл.- Возврат:
0при успехе;-1при ошибке (несовместимые сетки или нехватка памяти).
void Free_S(INPUT_DATA *id, S_INDEX **si, _real *f, _complex ***sss, int max, int extrapol_flag)
Освободить память, выделенную под прочитанную S-матрицу: id, массив частот f, матрицы sss (через Free_S_read), индекс si (через Free_GRID_Index).
- Параметры:
id(INPUT_DATA*) — портовая структура;si(S_INDEX**) — индекс сетки;f(_real*) — массив частот;sss(_complex***) — массив матриц;max(int) — число частотных точек;extrapol_flag(int) — флаг экстраполяции.
int Compare_S_ind(S_INDEX *si1, int extrapol_flag1, S_INDEX *si2, int extrapol_flag2)
Сравнить параметры сеток двух S-матриц: флаги экстраполяции и шаги delta1/2/3.
- Параметры:
si1/extrapol_flag1,si2/extrapol_flag2— индексы и флаги первой и второй матриц. - Возврат:
0, если сетки совместимы;-1, если нет.
4.13. Печать таблицы S-матрицы — S_table.cpp
void put_S_table(_complex *lpxS, int inpnb, int *modnb)
Напечатать текстовую таблицу S-матрицы (модуль и фаза элементов, а также КСВН или потери в дБ) в файл листинга. Использует open_listing_file / l_printf / close_listing_file.
- Параметры:
lpxS(_complex*) — матрица рассеяния;inpnb(int) — число входов;modnb(int*) — массив числа мод по входам.- Примечание: если
get_comp_file_flag() != 0, функция ничего не делает. Поскольку в данной сборке флаг всегда0, таблица всегда печатается.
Имя параметра во внешнем прототипе (
Postpro.h) —nInp_num(число входов). В реализации может отличаться.
5. Коды ошибок
Коды раздела «S-matrix» из Error1.h (диапазон 2300–2313):
| Константа | Код | Смысл |
|---|---|---|
ERROR_WRITE_S |
2300 | Ошибка записи в S-файл |
ERROR_READ_S |
2301 | Ошибка чтения из S-файла |
ILLEGAL_CURVE_INDEX_CORR |
2302 | Недопустимый (скорректированный) индекс кривой |
ILLEGAL_CURVE_INDEX |
2303 | Недопустимый индекс кривой |
BAD_S_FILE_NAME |
2304 | Некорректное имя S-файла |
ERROR_OPEN_S |
2305 | Ошибка открытия S-файла |
SMT_LABEL_ERROR |
2306 | Неверная метка файла (это не файл матрицы рассеяния) |
SMT_VERSION_ERROR |
2307 | Несовместимая (слишком старая) версия файла |
SMT_FRQ_POINT |
2308 | Ошибка по частотной точке |
SMT_FRQ_MEMORY |
2309 | Нехватка памяти на все частотные точки |
INTERP_DIFF_MATRIX |
2310 | Разные матрицы при интерполяции |
ERROR_WRITE_S_ITP |
2311 | Ошибка записи коэффициентов интерполяции |
INTER_ROOT_ERR |
2312 | Ошибка корня при интерполяции |
SMT_INTER_TABLE |
2313 | Ошибка таблицы интерполяции |
Важное замечание о фактической обработке ошибок
Функция put_error_messege в данной сборке — заглушка (всё тело закомментировано, всегда возвращает 0). Поэтому:
- никакие сообщения об ошибках пользователю не выводятся;
- ветки, опирающиеся на её возвращаемое значение, исполняются как «успех». В частности, в
read_S_matrixветка «нехватка памяти на все частотные точки» (SMT_FRQ_MEMORY) фактически трактуется как «продолжить» (итоговыйret_code = 0), а не как фатальная ошибка.
Это следует учитывать при диагностике: реальная сигнализация об ошибках в текущей сборке отсутствует, и судить об успехе/неуспехе нужно по возвращаемым значениям функций (-1, -2, -3, либо по выходному *nPoint).
6. Формат бинарного S-файла
Формат описан в комментарии-шапке файла Write_s.cpp (и реализован функциями Write_TITLE, Write_GRID, write_offset_table, write_string, write_CR).
Обозначения: r — _real (8 байт), c — complex (16 байт), PS — «pascal»-строка (длина — байт длины, далее символы, в конце разделитель 0x0A0D). Длины приведены для двойной точности (для одинарной — делить на 2).
Общая структура файла
| Длина (байт) | Тип/значение | Описание |
|---|---|---|
| 4 | 4×char | Метка файла (SMT) |
| 4 | 4×char | Номер версии формата (102) |
| 2 | int | Разделитель строк (LF CR) |
| 2 | int NS |
Число «pascal»-строк (PS) |
| 2 | int | Разделитель строк (LF CR) |
| --- | --- | --- |
| N1 | PS | Первая строка TITLE программы |
| N2 | PS | Вторая строка TITLE программы |
| N3 | PS | Строка GRID (сетка) |
| N4 | PS | Имя файла исходных данных (*.tpl) |
| N5 | PS | Имя файла матрицы рассеяния (*.s) |
| ... | ... | (имена файлов повторяются для каждой сетки экстраполяции) |
| NS-1 | PS | Таблица смещений частот |
| NS | PS | Таблица смещений коэффициентов интерполяции |
| --- | --- | --- |
| 8 | _real |
Текущая частота |
| 2 | int NI |
Число входов |
| D1 | int-вектор | Число мод на входах (D1 = 2*NI) |
| 2 | int NS |
Размерность S-матрицы |
| 2 | int | Разделитель строк (LF CR) |
| D2 | c-матрица | Матрица рассеяния (D2 = 16*(NS*NS)) |
| 2 | int | Разделитель строк (LF CR) |
| ... | ... | (блок повторяется для каждой частотной точки) |
| D3 | c-матрица | Коэффициенты интерполяции (1, 2, 3); D3 = 16*(NS*NS)*3 |
| 2 | int | Разделитель строк (LF CR) |
Структура «pascal»-строки GRID
| Длина (байт) | Тип/значение | Описание |
|---|---|---|
| 2 | int | Длина строки |
| 2 | int NG |
Флаг экстраполяции (число сеток) |
| 8 | _real |
Шаг сетки по оси X |
| 8 | _real |
Шаг сетки по оси Y |
| 8 | _real |
Шаг сетки по оси Z |
| 2 | int | Разделитель строк (LF CR) |
Структура таблицы смещений
| Длина (байт) | Тип/значение | Описание |
|---|---|---|
| 2 | int | Длина строки |
| 2 | int NF |
Число частот в файле |
| 8 | _real |
Частота |
| 4 | long | Смещение многополюсных параметров |
| 2 | int (0a0d) |
Разделитель строк |
Замечания (из исходника):
1. Размерности всех вещественных и комплексных векторов/матриц даны для случая двойной точности; при одинарной — делить на 2.
2. Размеры типов указаны для IBM-совместимых машин.
3. «Pascal»-строка начинается с байта длины и заканчивается значением 0x0A0D.
Примечание о реализации: фактически
Write_TITLEпишет версию как 4 символа черезsprintf("%3d", 102), а длины «pascal»-строк и счётчикPSпишутся типомINT_1(один байт) с последующим разделителем — это согласуется со схемой, но числовые длины в таблицах выше приведены по комментарию-шаблону. При сомнении опираться на кодWrite_s.cpp.
7. Зависимости
Общие заголовки (src/Include/), используемые SFILE95:
typedef.h, tmclimit.h, frqdata.h, error1.h (Error1.h), s_file.h (S_file.h), proc_s.h, postpro.h (Postpro.h).
Математика комплексных чисел подключается через complex1.h / tmc_lib.h — вероятна связь с библиотекой complex пакета TMC Suite (явный #include в .vcxproj-зависимостях не подтверждён).
Прямых #include из библиотек TMCLibError, PREPR, exprint в исходниках SFILE95 не обнаружено.
The SFILE95 library — API documentation
TMC Suite package. A static library for working with binary S-files (scattering matrices). All signatures are taken from the sources in
src/libs/SFILE95/and the shared headers fromsrc/Include/.
1. Purpose of the library
SFILE95 is a static library (StaticLibrary, UseOfMfc=false, built for win32
and x64) for working with S-files — binary scattering-matrix files of the
TAMIC/TMC format.
An S-file is a file with the label "SMT" (Scattering MaTrix) of version 102,
which stores the multi-frequency scattering matrix of a multiport: for each
frequency point a complex S-matrix is written, as well as service information about
the extrapolation grid, the number of inputs and the number of modes at the inputs.
The library provides:
- opening/closing and low-level reading/writing of S-file blocks;
- reading all frequency points of the S-matrix into memory (
read_S_matrix); - writing a single frequency point (
save_S_matrix) with header formation at the first point; - working with the global frequency table
FREQUENCY(the frequency grid, the units Hz/KHz/MHz/GHz, the current point); - merging and concatenating two multi-frequency S-matrices without duplicates, with
sorting by frequency (
Unite_two_S,S_add); - saving/updating a separate column (input) of the S-matrix for a given frequency
(
save_S_matrix_element); - importing S-matrix elements from HFSS and CST text files;
- maintaining offset tables of the frequency points inside the file;
- outputting a text table of the S-matrix (magnitude/phase, VSWR/losses) into a
listing file (
put_S_table).
2. Composition
The SFILE95.vcxproj build contains 13 .cpp files:
| File | Purpose (briefly) |
|---|---|
Errors.cpp |
An error-handling stub |
Frqdata.cpp |
The global frequency table FREQUENCY |
Read_s.cpp |
Reading all frequency points of the S-matrix |
S_file.cpp |
Low-level file work (open/close/blocks) |
S_memf.cpp |
Memory and stubs (alloc_mem_err, free_mem, etc.) |
S_remt.cpp |
Reading S-matrix elements from TMC/HFSS/CST |
S_table.cpp |
Printing a text S-matrix table into a listing |
S_wemt.cpp |
Saving a single column (input) of the S-matrix |
Sadd.cpp |
Merging two S-files (S_add) |
Sofftbl.cpp |
The frequency-point offset table |
Unite_s.cpp |
Merging two frequency grids in memory |
Write_s.cpp |
Writing a single frequency point + the header |
Wrrd_s.cpp |
Forming a temporary S-file name, copying |
Legacy files outside the build (not documented)
The following files are present in the directory but are not included in
SFILE95.vcxproj and are therefore not described in this documentation:
Read_s1.cpp, S_CUT.CPP, S_DB.CPP, STXTABLE.CPP, SREAD.CPP, WRTSLST.CPP,
LISTING.CPP, OUTTRACE.CPP, MAIN_S.CPP, GTARGENV.CPP.
3. Structures and data types
The types
_real,_complex,INT_1,WORD,DWORDare defined in external headers (typedef.h,complex1.h). In most builds_realisdouble(8 bytes),_complexis a pair ofdouble(16 bytes),INT_1is a one-byte integer type,WORDis 16 bits,DWORDis 32 bits.
3.1. S_INDEX (Postpro.h)
The extrapolation-grid index: file names and discretization steps along three axes.
typedef struct {
char *tpl_name; // input-data file name (*.tpl)
char *S_name; // S-matrix file name (*.s)
double delta1; // grid step along the X axis
double delta2; // grid step along the Y axis
double delta3; // grid step along the Z axis
} S_INDEX;
| Field | Type | Meaning |
|---|---|---|
tpl_name |
char* |
The name of the input-data file (the *.tpl template) |
S_name |
char* |
The name of the S-matrix file (*.s) |
delta1 |
double |
The grid step along the X axis |
delta2 |
double |
The grid step along the Y axis |
delta3 |
double |
The grid step along the Z axis |
During extrapolation an array of extrapol_flag+1 S_INDEX elements is used.
3.2. INPUT_DATA (Postpro.h)
The description of the port structure of a multiport.
typedef struct {
INT_1 num; // the number of inputs (ports)
INT_1 array[MAX_INPUT_NUM]; // the number of modes on each input
INT_1 dim; // the S-matrix dimension (the sum of modes over all inputs)
} INPUT_DATA;
| Field | Type | Meaning |
|---|---|---|
num |
INT_1 |
The number of inputs (ports) of the device |
array[] |
INT_1[MAX_INPUT_NUM] |
The number of propagating modes on each input |
dim |
INT_1 |
The dimension of the square S-matrix (the sum of modes over all inputs); the matrix has dim × dim complex elements |
MAX_INPUT_NUM is defined in the external header tmclimit.h.
3.3. S_HEADER (S_file.h)
The header of the offset table (a service structure).
typedef struct {
WORD cPs; // number of "pascal" strings in the file
WORD cbSize; // size of the offset table in bytes
WORD cnFrqNum; // number of frequencies
} S_HEADER;
| Field | Type | Meaning |
|---|---|---|
cPs |
WORD |
The counter of "pascal" strings in the file header |
cbSize |
WORD |
The size of the offset table (bytes) |
cnFrqNum |
WORD |
The number of frequency points |
3.4. S_OFFSET / _OFFSET (S_file.h)
One record of the offset table: the frequency and the position of the block in the file.
typedef struct {
_real frq; // frequency
DWORD lOffset; // offset (position) of the parameters block in the file
} _OFFSET;
typedef _OFFSET S_OFFSET;
| Field | Type | Meaning |
|---|---|---|
frq |
_real |
The frequency value |
lOffset |
DWORD |
The offset of the multiport-parameters block in the file for this frequency |
3.5. S_OFFSET_TABLE (S_file.h)
The offset table as a whole.
typedef struct {
WORD cbSize; // table size (bytes)
WORD cnFrqNum; // number of frequencies
S_OFFSET *lpOffset; // pointer to the array of S_OFFSET records
} S_OFFSET_TABLE;
| Field | Type | Meaning |
|---|---|---|
cbSize |
WORD |
The size of the offset table (bytes) |
cnFrqNum |
WORD |
The number of frequency points in the table |
lpOffset |
S_OFFSET* |
A pointer to the array of offset records |
3.6. INTERP_COEFF (S_file.h)
The coefficients of the spline interpolation over frequency.
typedef struct {
_complex *lpxC0; // function values
_complex *lpxC1; // 1st-degree spline coefficient
_complex *lpxC2; // 2nd-degree spline coefficient
_complex *lpxC3; // 3rd-degree spline coefficient
} INTERP_COEFF;
| Field | Type | Meaning |
|---|---|---|
lpxC0 |
_complex* |
The function values (S-parameters) at the nodes |
lpxC1 |
_complex* |
The spline coefficient at the 1st degree |
lpxC2 |
_complex* |
The spline coefficient at the 2nd degree |
lpxC3 |
_complex* |
The spline coefficient at the 3rd degree |
3.7. FREQUENCY (external frqdata.h)
The global frequency table. The header frqdata.h is not found in
src/Include; the structure is reconstructed from the accesses in Frqdata.cpp.
| Field | Type | Meaning |
|---|---|---|
num |
int |
The index of the current frequency point |
max |
int |
The number of frequency points in the grid |
f |
_real* |
The array of frequency values (length up to FREQ_MAX_NUM) |
code |
int |
The code of the current unit (an index into unit[]/item[]) |
unit[4] |
_real[4] |
The unit factors: Hz = 1, KHz = 1e3, MHz = 1e6, GHz = 1e9 |
item[4] |
char*[4] |
The unit strings: "_Hz", "KHz", "MHz", "GHz" |
The default values (from Frqdata.cpp): num = 0, max = 0, the array f is the
static buffer frq_buff[FREQ_MAX_NUM], code = 3 (the current unit is GHz).
3.8. Constants (S_file.h)
| Constant | Value | Meaning |
|---|---|---|
S_WR |
0 |
The open-for-writing mode |
S_RD |
1 |
The open-for-reading mode |
S_PS_NUMBER |
7 |
The base number of "pascal" strings in the header |
OFF_TBL_MAIN |
1 |
The main offset table |
OFF_TBL_APPR |
2 |
The interpolation-coefficient offset table |
SMT_LABEL |
"SMT" |
The scattering-matrix file label |
SMT_VERSION |
102 |
The format version number |
S_UNKNOWN |
-1 |
The unitarity of the matrix is undefined |
S_UNITARY |
0 |
The matrix is unitary |
S_NOT_UNITARY |
1 |
The matrix is not unitary |
UNITARY_THRESH |
1.0e-12 |
The unitarity-check threshold |
4. Public functions
About the
_far,_near,_fortranmacros. These are memory-model and calling-convention attributes from old 16/32-bit code (Microsoft C / early Visual C++). In the modern 32/64-bit build they usually expand to nothing or to the standard calling convention and do not affect the semantics. For brevity these macros are omitted from the signatures below (a "clean" C prototype is shown). See the headerS_file.hfor the full prototypes with_far/_fortran.
4.1. Error handling — Errors.cpp
int put_error_messege(int err_num, ...)
Handling (output) of an error message.
- Parameters:
err_num(int) — the error code (see section 5);...— a variable number of arguments for message formatting.- Return: always
0. - Important: in this build the function is a stub — the entire body is
commented out. No messages are output, and there is in fact no error handling. The
return value is always
0(see section 5 for the consequences).
4.2. The frequency table — Frqdata.cpp
All functions work with the single global static structure FREQUENCY frq.
int set_frequency(_real f0, _real df, int nf)
Set a uniform frequency grid: the first frequency, the step, the number of points.
- Parameters:
f0(_real) — the first frequency (in the current units; multiplied byunit[code]);df(_real) — the frequency step (in the current units);nf(int) — the number of points.- Return:
0.
int set_frequency_arr(_real *ftmp, int nf)
Set the frequency grid directly from an array.
- Parameters:
ftmp(_real*) — the array of frequency values (in the current units);nf(int) — the number of points.- Return:
0.
_real get_frq_f0(int unit_flag)
Get the first frequency.
- Parameters:
unit_flag(int) — if1, the result is in the current units (divided byunit[code]); otherwise in the base units (Hz). - Return: the value of the first frequency
frq.f[0].
_real get_frq_df(int unit_flag)
Get the frequency step (f[1] - f[0]; when max == 1 returns 0).
- Parameters:
unit_flag(int) —1→ in the current units, otherwise in the base units. - Return: the frequency step.
int get_frq_nf(void)
- Return: the number of grid points (
frq.max).
int set_frq_nf(int nMax)
Set the number of points.
- Parameters:
nMax(int) — the number of points;0 < nMax <= FREQ_MAX_NUMis allowed. - Return:
0on success;-1on a range violation (in which caseput_error_messege(BAD_NF_PARM, ...)is called).
char* get_frq_item(int num)
- Parameters:
num(int) — the unit index (0..3). - Return: the unit string (
"_Hz","KHz","MHz","GHz").
char* get_current_frq_item(void)
- Return: the current-unit string (
frq.item[frq.code]).
_real get_frq_unit(int num)
- Parameters:
num(int) — the unit index (0..3). - Return: the unit factor (
1,1e3,1e6,1e9).
void set_frq_item_num(int num)
Set the code of the current unit.
- Parameters:
num(int) — the unit index (0..3).
int get_frq_item_code(void)
- Return: the code of the current unit (
frq.code).
_real get_frq_element(int index)
- Parameters:
index(int) — the point index. - Return: the frequency value
frq.f[index](in base units).
void set_frq_element(_real fValue, int index)
Write a frequency by index as is (without unit conversion).
- Parameters:
fValue(_real) — the value;index(int) — the point index.
void set_frq_element_unit(_real fValue, int index)
Write a frequency by index converting from the current units to base (multiplying by
unit[code]).
- Parameters:
fValue(_real) — the value in the current units;index(int) — the point index.
_real get_current_frq(void)
- Return: the value of the current frequency
frq.f[frq.num].
double get_current_dbl_frq(void)
- Return: the current frequency cast to
double(used when writing to the file).
int get_current_frq_num(void)
- Return: the index of the current frequency point (
frq.num).
void set_current_frq_num(int num)
Set the index of the current frequency point.
- Parameters:
num(int) — the index.
FREQUENCY* GetPointerToFrq(void)
- Return: a pointer to the global structure
frq.
4.3. Low-level file work — S_file.cpp
FILE* Get_S_FILE(void)
- Return: the
FILE*pointer to the open S-file (NULLif the file is not open).
void Set_PS_Number(int nNum)
Set the number of "pascal" strings in the header (stored in a static variable).
- Parameters:
nNum(int) — the number of strings.
int Get_PS_Number(void)
- Return: the previously set number of "pascal" strings.
int Open_S_file(char *szFile, int nOpenMode)
Open an S-file.
- Parameters:
szFile(char*) — the file name;nOpenMode(int) — the mode:S_RD(1) → opening"rb"; otherwise (S_WR) →"wb+"if the current frequency point == 0 (a new file), or"rb+"if != 0 (appending to an existing one).- Return:
0on success;-1on error (put_error_messege(ERROR_OPEN_S, ...)is called). - Note: on successful opening a
BUFSIZbuffer is allocated viaalloc_mem_errand assigned to the file viasetbuf(if_NDP2is not set).
void Close_S_file(void)
Close the S-file (fclose), null the pointer, free the I/O buffer.
int skip_string(void)
Skip one "pascal" string: reads the length (INT_1), then fseeks over the string
length + the separator.
- Return:
0on success;-1on a read/seek error.
int write_S(void *ptr, size_t size)
Write a data block to the file (fwrite as a single element of size size).
- Parameters:
ptr(void*) — the data;size(size_t) — the block size (bytes). - Return:
0on success;-1on a write error.
int read_S(void *string, size_t size)
Read a data block from the file (fread as a single element of size size).
- Parameters:
string(void*) — the receiving buffer;size(size_t) — the block size (bytes). - Return:
0on success;-1on a read error.
4.4. Memory and service stubs — S_memf.cpp
void* alloc_mem_err(long size)
Allocate memory (malloc). On failure calls
put_error_messege(FATAL_MEM_ALLOC_ERROR) (a stub).
- Parameters:
size(long) — the block size (bytes). - Return: a pointer to the block or
NULLon failure.
int free_mem(void *mem_ptr)
Free memory (free).
- Parameters:
mem_ptr(void*) — a pointer to the block. - Return:
0.
int free_mem_null(void **ptr)
Free memory and null the pointer.
- Parameters:
ptr(void**) — the address of the pointer; after the call*ptr == NULL. - Return:
0.
void stat_messege(int num, char *mes)
An empty stub (the body is return;). It does nothing.
int get_comp_file_flag(void)
A stub. Always returns 0.
- Return:
0. - Important: many branches (
copy_S_matrix, disablingput_S_table) check this flag; since it is always0, the corresponding logic is in fact inactive.
4.5. Reading the S-matrix — Read_s.cpp
int read_S_matrix(char *szFileName, S_INDEX **si, int *extrapol_flag, _complex ***sss, FREQUENCY *frq_out, INPUT_DATA **id)
Read all frequency points of the S-matrix from a file into memory.
- Parameters:
szFileName(char*) — the S-file name;si(S_INDEX**) — output: the array of grid indices (extrapol_flag+1elements), allocated inside;extrapol_flag(int*) — output: the extrapolation flag (0 — one grid, 1 — two, 2 — three);sss(_complex***) — output: the array of matrices by frequency (frq_out->maxpointers to arrays ofdim*dimcomplex values);frq_out(FREQUENCY*) — output: the filled frequency table;id(INPUT_DATA**) — output: the port structure.- Return:
0— success;-1— a read error;-2— a file-opening error;-3— out of memory.- Internal (
static) functions:Read_TITLE,Read_GRID,read_string,read_CR— service ones, not exported.
void Free_GRID_Index(S_INDEX **si, int extrapol_flag)
Free the S_INDEX array (extrapol_flag+1 elements together with the file names).
- Parameters:
si(S_INDEX**) — the address of the array;extrapol_flag(int) — the extrapolation flag.
void Free_S_read(_complex ***sss, int nFrqNum)
Free the array of matrices for nFrqNum frequency points.
- Parameters:
sss(_complex***) — the address of the array;nFrqNum(int) — the number of frequency points.
4.6. Reading S-matrix elements (TMC / HFSS / CST) — S_remt.cpp
int read_S_matrix_element_TMC(...)
Read one S-matrix element from a TMC/TAMIC-format file (via read_S_matrix). Fills
the array of complex values sss and the array of frequencies f1 (double) over
nPoint points.
- Return:
0on success,-1on error.
int read_S_matrix_element(int *in1, int *mod1, int *in2, int *mod2, char *filename, _complex **sss, double **f1, int *nPoint)
Read one S-matrix element, automatically trying the formats in turn: first TMC, then HFSS, then CST.
- Parameters:
in1,mod1(int*) — the number of input 1 and mode 1;in2,mod2(int*) — the number of input 2 and mode 2;filename(char*) — the file name;sss(_complex**) — output: the array of complex values (allocated inside);f1(double**) — output: the array of frequencies;nPoint(int*) — output: the number of points.- Return: always
0. The result is determined from*nPoint: a value<= 0means failure (no format matched).
int read_S_matrix_element_HFSS(int *in1, int *mod1, int *in2, int *mod2, char *filename, _complex **sss, double **f1, int *nPoint)
Read an S-matrix element from an HFSS text file.
- Parameters: similar to
read_S_matrix_element. - Return:
0/-1.
int SMatrixElementHFSS_InpMod(int *in1, int *mod1, int *in2, int *mod2, char *filename)
Determine the input/mode numbers for an element from an HFSS file.
- Return: the result code (see the implementation).
int SMatrixElementHFSS_ModMax(char *filename, int *pnInp)
Determine the maximum number of modes (for input *pnInp) in an HFSS file.
int SMatrixElementHFSS_InpMax(char *filename)
Determine the number of ports (inputs) in an HFSS file.
int ChooseString(char *pszBuf, char *pszIdentifInput, char *pszIdentifMode, int *pnInp, int *pnMod)
Parse a line of an HFSS file, extracting the port number and the mode number.
- Parameters:
pszBuf(char*) — the line being parsed;pszIdentifInput(char*) — the input-identifier marker;pszIdentifMode(char*) — the mode-identifier marker;pnInp(int*) — output: the input number;pnMod(int*) — output: the mode number.
int SMatrixElementHFSS_FreqArray(int *in1, int *mod1, int *in2, int *mod2, char *filename, double **f1, _complex **sss, int *nPoint, int *nMatrixSize)
Form the array of frequencies and values for an element from an HFSS file (an aggregating function).
void SMatrixElementHFSS_FreqArrayCalculation(char *filename, double **f1, int *nPoint, int *nMatrixSize)
Count the number of points and the matrix size from an HFSS file.
void SMatrixElementHFSS_FreqArrayAllocation(double **f1, _complex **sss, int *nPoint)
Allocate memory for the arrays of frequencies and values.
void SMatrixElementHFSS_FreqArrayRead(int *in1, int *mod1, int *in2, int *mod2, char *filename, double **f1, _complex **sss, int *nPoint, int *nMatrixSize)
Read the frequencies and values of an element from an HFSS file into the allocated arrays.
The CST analogues — read_S_matrix_element_CST(...) and SMatrixElementCST_*(...)
A fully analogous set of functions for importing S-matrix elements from CST text files.
Internal function: ChooseString1 — static, absent from the headers, used only
inside S_remt.cpp. Not exported.
4.7. Saving a single column (input) — S_wemt.cpp
int save_S_matrix_element(int in1, char *filename, _complex *sss, double f1, int nInput)
Save one column of the S-matrix (corresponding to input in1) for the frequency
f1.
- Parameters:
in1(int) — the input (column) number;filename(char*) — the S-file name;sss(_complex*) — the array of complex values of the column;f1(double) — the frequency;nInput(int) — the number of inputs.- Logic:
- if the file does not exist — a new matrix is created;
- if that frequency is not in the file — the data is written to the temporary file
<filename>$and merged with the main one viaS_add; - if the frequency already exists — the corresponding record is updated and the file is rewritten.
- Return:
0on success;-1on error.
4.8. The offset table — Sofftbl.cpp
int update_offset_table(_real frq, int num, int nTBL_Flag)
Write (update) an offset-table record for the frequency frq and move to the end of
the file.
- Parameters:
frq(_real) — the frequency value;num(int) — the frequency-point index (increased by 1 inside the function when writing the frequency counter);nTBL_Flag(int) — which table to update:OFF_TBL_MAIN(1) — the main one (skipped by 2 fewer "pascal" strings),OFF_TBL_APPR(2) — the interpolation-coefficient table.- Return:
0on success;-1on a seek/write error.
4.9. Merging frequency grids — Unite_s.cpp
int Unite_two_S(FREQUENCY *frq_out1, INPUT_DATA *id1, _complex **sss1, FREQUENCY *frq_out2, INPUT_DATA *id2, _complex **sss2, FREQUENCY *frq_out, INPUT_DATA **id, _complex ***sss)
Merge two multi-frequency S-matrices into one: the frequency points are merged
without duplicates, the result is sorted by frequency (qsort with the
cmpgle comparator).
- Parameters:
frq_out1,id1,sss1— the first matrix (frequencies, port structure, array of matrices);frq_out2,id2,sss2— the second matrix;frq_out(FREQUENCY*) — output: the merged frequency table;id(INPUT_DATA**) — output: the port structure of the result;sss(_complex***) — output: the array of result matrices.- Return:
0on success;-1on error (the number of frequencies exceededFREQ_MAX_NUM, or out of memory).
int cmpgle(const void *fs1, const void *fs2) — internal
A comparator for qsort: comparison of elements by frequency value (ascending). Used
only inside Unite_s.cpp.
4.10. Writing the S-matrix — Write_s.cpp
int save_S_matrix(_complex *sss, INPUT_DATA *id, char *S_filename, S_INDEX *si, int extrapol_flag)
Write one frequency point of the S-matrix into a file.
- Parameters:
sss(_complex*) — the scattering matrix (id->dim * id->dimcomplex values);id(INPUT_DATA*) — the port structure;S_filename(char*) — the S-file name;si(S_INDEX*) — the array of grid indices (extrapol_flag+1elements);extrapol_flag(int) — the extrapolation flag (0/1/2).- Logic:
- at the first point (
get_current_frq_num() == 0) the number of "pascal" stringsS_PS_NUMBER + 2*extrapol_flagis set and the header is written: the label/version (Write_TITLE), two TITLE strings (MAIN_LABEL,TWP_LABEL), the GRID string (Write_GRID), the.tpl/.sfile names fromsi, two empty offset tables (the main one — forget_frq_nf()frequencies, and for the interpolation coefficients — for0); - then for each point:
update_offset_table(records the position), writing the frequency (_real), writingINPUT_DATA(num, the array of modes,dim), a separator, the matrix, a separator. - Return:
0on success;-1on error (on errorput_error_messege(ERROR_WRITE_S, ...)is called). - Internal (
static) functions:Write_TITLE,Write_GRID,write_offset_table,write_string,write_CR— service ones, not exported.
4.11. Temporary file names and copying — Wrrd_s.cpp
void make_S_matrix_name(char *S_name, S_INDEX *si)
Form a temporary S-file name from the .tpl template name and the grid step. Fills
the fields si->tpl_name, si->S_name, si->delta1..3.
- Parameters:
S_name(char*) — the output name buffer;si(S_INDEX*) — the grid index (filled).- Dependence of the
delta1..3values on the model: _MODEL_E,_MODEL_H— the step fromget_data_const_delta;_MODEL_IC— the step fromGet_Mesh_Size_X/Get_Mesh_Size_Y;_MODEL_M,_MODEL_W— zeros.
int copy_S_matrix(void)
Copy the temporary S-file into the output one, if get_comp_file_flag() is set.
- Return:
0. - Important: in this build
get_comp_file_flag()is a stub, always0, so the function in fact copies nothing and simply returns0.
4.12. Merging two S-files — Sadd.cpp
int S_add(char *filename, char *filename1)
Read two S-matrices from files, compare their grids (Compare_S_ind), merge them
(Unite_two_S) and write the result into filename.
- Parameters:
filename(char*) — the first file; the merge result is also written into it;filename1(char*) — the second file.- Return:
0on success;-1on error (incompatible grids or out of memory).
void Free_S(INPUT_DATA *id, S_INDEX **si, _real *f, _complex ***sss, int max, int extrapol_flag)
Free the memory allocated for a read S-matrix: id, the array of frequencies f,
the matrices sss (via Free_S_read), the index si (via Free_GRID_Index).
- Parameters:
id(INPUT_DATA*) — the port structure;si(S_INDEX**) — the grid index;f(_real*) — the array of frequencies;sss(_complex***) — the array of matrices;max(int) — the number of frequency points;extrapol_flag(int) — the extrapolation flag.
int Compare_S_ind(S_INDEX *si1, int extrapol_flag1, S_INDEX *si2, int extrapol_flag2)
Compare the grid parameters of two S-matrices: the extrapolation flags and the steps
delta1/2/3.
- Parameters:
si1/extrapol_flag1,si2/extrapol_flag2— the indices and flags of the first and second matrices. - Return:
0if the grids are compatible;-1if not.
4.13. Printing the S-matrix table — S_table.cpp
void put_S_table(_complex *lpxS, int inpnb, int *modnb)
Print a text table of the S-matrix (the magnitude and phase of the elements, as well
as the VSWR or the losses in dB) into a listing file. Uses open_listing_file /
l_printf / close_listing_file.
- Parameters:
lpxS(_complex*) — the scattering matrix;inpnb(int) — the number of inputs;modnb(int*) — the array of mode counts per input.- Note: if
get_comp_file_flag() != 0, the function does nothing. Since in this build the flag is always0, the table is always printed.
The parameter name in the external prototype (
Postpro.h) isnInp_num(the number of inputs). In the implementation it may differ.
5. Error codes
The "S-matrix" section codes from Error1.h (the range 2300–2313):
| Constant | Code | Meaning |
|---|---|---|
ERROR_WRITE_S |
2300 | An error writing to an S-file |
ERROR_READ_S |
2301 | An error reading from an S-file |
ILLEGAL_CURVE_INDEX_CORR |
2302 | An invalid (corrected) curve index |
ILLEGAL_CURVE_INDEX |
2303 | An invalid curve index |
BAD_S_FILE_NAME |
2304 | An incorrect S-file name |
ERROR_OPEN_S |
2305 | An error opening an S-file |
SMT_LABEL_ERROR |
2306 | A wrong file label (this is not a scattering-matrix file) |
SMT_VERSION_ERROR |
2307 | An incompatible (too old) file version |
SMT_FRQ_POINT |
2308 | An error at a frequency point |
SMT_FRQ_MEMORY |
2309 | Not enough memory for all frequency points |
INTERP_DIFF_MATRIX |
2310 | Different matrices during interpolation |
ERROR_WRITE_S_ITP |
2311 | An error writing the interpolation coefficients |
INTER_ROOT_ERR |
2312 | A root error during interpolation |
SMT_INTER_TABLE |
2313 | An interpolation-table error |
Important note on the actual error handling
The function put_error_messege in this build is a stub (the entire body is
commented out, it always returns 0). Therefore:
- no error messages are output to the user;
- the branches that rely on its return value execute as "success". In particular, in
read_S_matrixthe "not enough memory for all frequency points" branch (SMT_FRQ_MEMORY) is in fact treated as "continue" (the finalret_code = 0) rather than as a fatal error.
This should be taken into account when diagnosing: real error signaling is absent in
the current build, and success/failure must be judged by the return values of the
functions (-1, -2, -3, or by the output *nPoint).
6. The binary S-file format
The format is described in the header comment of the file Write_s.cpp (and
implemented by the functions Write_TITLE, Write_GRID, write_offset_table,
write_string, write_CR).
Notation: r — _real (8 bytes), c — complex (16 bytes), PS — a "pascal"
string (a length byte, then the characters, ending with the separator 0x0A0D). The
lengths are given for double precision (for single — divide by 2).
The overall file structure
| Length (bytes) | Type/value | Description |
|---|---|---|
| 4 | 4×char | The file label (SMT) |
| 4 | 4×char | The format version number (102) |
| 2 | int | The line separator (LF CR) |
| 2 | int NS |
The number of "pascal" strings (PS) |
| 2 | int | The line separator (LF CR) |
| --- | --- | --- |
| N1 | PS | The first program TITLE string |
| N2 | PS | The second program TITLE string |
| N3 | PS | The GRID string (the grid) |
| N4 | PS | The input-data file name (*.tpl) |
| N5 | PS | The scattering-matrix file name (*.s) |
| ... | ... | (the file names repeat for each extrapolation grid) |
| NS-1 | PS | The frequency offset table |
| NS | PS | The interpolation-coefficient offset table |
| --- | --- | --- |
| 8 | _real |
The current frequency |
| 2 | int NI |
The number of inputs |
| D1 | int vector | The number of modes at the inputs (D1 = 2*NI) |
| 2 | int NS |
The S-matrix dimension |
| 2 | int | The line separator (LF CR) |
| D2 | c-matrix | The scattering matrix (D2 = 16*(NS*NS)) |
| 2 | int | The line separator (LF CR) |
| ... | ... | (the block repeats for each frequency point) |
| D3 | c-matrix | The interpolation coefficients (1, 2, 3); D3 = 16*(NS*NS)*3 |
| 2 | int | The line separator (LF CR) |
The structure of the GRID "pascal" string
| Length (bytes) | Type/value | Description |
|---|---|---|
| 2 | int | The string length |
| 2 | int NG |
The extrapolation flag (the number of grids) |
| 8 | _real |
The grid step along X |
| 8 | _real |
The grid step along Y |
| 8 | _real |
The grid step along Z |
| 2 | int | The line separator (LF CR) |
The structure of the offset table
| Length (bytes) | Type/value | Description |
|---|---|---|
| 2 | int | The string length |
| 2 | int NF |
The number of frequencies in the file |
| 8 | _real |
The frequency |
| 4 | long | The offset of the multiport parameters |
| 2 | int (0a0d) |
The line separator |
Notes (from the source):
1. The dimensions of all real and complex vectors/matrices are given for the
double-precision case; for single — divide by 2.
2. The type sizes are given for IBM-compatible machines.
3. A "pascal" string starts with a length byte and ends with the value 0x0A0D.
A note on the implementation: in fact
Write_TITLEwrites the version as 4 characters viasprintf("%3d", 102), and the "pascal"-string lengths and thePScounter are written asINT_1(one byte) followed by a separator — this is consistent with the scheme, but the numeric lengths in the tables above are given according to the template comment. When in doubt, rely on theWrite_s.cppcode.
7. Dependencies
Shared headers (src/Include/) used by SFILE95:
typedef.h, tmclimit.h, frqdata.h, error1.h (Error1.h), s_file.h
(S_file.h), proc_s.h, postpro.h (Postpro.h).
Complex-number math is included through complex1.h / tmc_lib.h — a connection
with the complex library of TMC Suite is likely (an explicit #include in the
.vcxproj dependencies is not confirmed).
No direct #includes from the TMCLibError, PREPR, exprint libraries were
found in the SFILE95 sources.