Библиотека 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). В большинстве сборок _realdouble (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.

Внутренняя функция: ChooseString1static, в заголовках отсутствует, используется только внутри 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 байт), ccomplex (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 from src/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, DWORD are defined in external headers (typedef.h, complex1.h). In most builds _real is double (8 bytes), _complex is a pair of double (16 bytes), INT_1 is a one-byte integer type, WORD is 16 bits, DWORD is 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, _fortran macros. 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 header S_file.h for 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 by unit[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) — if 1, the result is in the current units (divided by unit[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_NUM is allowed.
  • Return: 0 on success; -1 on a range violation (in which case put_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 (NULL if 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: 0 on success; -1 on error (put_error_messege(ERROR_OPEN_S, ...) is called).
  • Note: on successful opening a BUFSIZ buffer is allocated via alloc_mem_err and assigned to the file via setbuf (if _NDP2 is 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: 0 on success; -1 on 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: 0 on success; -1 on 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: 0 on success; -1 on 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 NULL on 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, disabling put_S_table) check this flag; since it is always 0, 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+1 elements), 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->max pointers to arrays of dim*dim complex 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: 0 on success, -1 on 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 <= 0 means 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: ChooseString1static, 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 via S_add;
  • if the frequency already exists — the corresponding record is updated and the file is rewritten.
  • Return: 0 on success; -1 on 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: 0 on success; -1 on 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: 0 on success; -1 on error (the number of frequencies exceeded FREQ_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->dim complex values);
  • id (INPUT_DATA*) — the port structure;
  • S_filename (char*) — the S-file name;
  • si (S_INDEX*) — the array of grid indices (extrapol_flag+1 elements);
  • extrapol_flag (int) — the extrapolation flag (0/1/2).
  • Logic:
  • at the first point (get_current_frq_num() == 0) the number of "pascal" strings S_PS_NUMBER + 2*extrapol_flag is 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/.s file names from si, two empty offset tables (the main one — for get_frq_nf() frequencies, and for the interpolation coefficients — for 0);
  • then for each point: update_offset_table (records the position), writing the frequency (_real), writing INPUT_DATA (num, the array of modes, dim), a separator, the matrix, a separator.
  • Return: 0 on success; -1 on error (on error put_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..3 values on the model:
  • _MODEL_E, _MODEL_H — the step from get_data_const_delta;
  • _MODEL_IC — the step from Get_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, always 0, so the function in fact copies nothing and simply returns 0.

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: 0 on success; -1 on 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: 0 if the grids are compatible; -1 if 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 always 0, the table is always printed.

The parameter name in the external prototype (Postpro.h) is nInp_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_matrix the "not enough memory for all frequency points" branch (SMT_FRQ_MEMORY) is in fact treated as "continue" (the final ret_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), ccomplex (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_TITLE writes the version as 4 characters via sprintf("%3d", 102), and the "pascal"-string lengths and the PS counter are written as INT_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 the Write_s.cpp code.


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.