нефтехимическое производство

Оглавление сайта

Главная

  Приветствие

  Что нового

  Системные требования

  Общая блок-схема

  Запуск программы

  Панель "Расчет"

  Панель "Аппараты"

  Панель "Потоки"

  Панель "Схема"

  Встроенный Паскаль

  Работа с AutoCAD

  Объектная модель

  Оглавление банка ФХС

  Как создать библиотеку

  Подключение библиотеки

  Как собрать схему

  Выполнение расчета

  Структурный анализ

  Отладка

  Загрузка и сохранение

  Итерационные расчеты

  Работа с ФХС

  Использование в учебном процессе

  Синтез аммиака

  Синтез метанола

  Производство бензола

  Производство азотной кислоты

  Производство серной кислоты

  Процесс Клауса

  Контакты

  Как получить программу

  Лицензия

Скачать

Видеоурок

Как создать библиотеку расчетных модулей
Предыдущий Начало Следующий

Как создать библиотеку расчетных модулей
            Библиотека расчетных моделей оформляется как пакет (package) Delphi 7. Пакет .BPL - это динамическая библиотека .DLL с возможностью использования классов Delphi.
Для создания нового пакета  запустите Delphi 7 и закройте предыдущий проект File/Close All.  Затем выполните File/New/Other и на странице New выберите Package:
создание библиотеки расчета аппаратов схемы
Откроется графический режим работы с пакетом
переключение режимов библиотеки расчета аппаратов
Для переключения в обычный текстовый редактор нажмите иконку Toggle Form/Unit (F12).
Основные действия с пакетом:
            Ctrl-F9  - Compile - компиляция
            F9        - Run - запуск на выполнение/отладку
            Ctrl-S   - Save - сохранить текущий модуль
            Shift-F1 - Add file to project - добавить новый модуль в пакет
            Допустим, мы создаем библиотеку расчетных модулей с именем KomfortUserPack02.bpl.Тогда создаваемый проект мы должны сохранить (File/Save Project as) под именем  KomfortUserPack02.dpk. Целесообразно сохранять модули - файлы .pas, относящиеся к проекту вместе с ним в одном каталоге.
Дальнейшеее описание ведется для следующей структуры каталогов:
            C:
                        MyDelphi7                                - каталог разработчика Delphi7
                                    Komfort2001                 - каталог с программой Komfort2001.exe
                                    KomfortCommonUser    - каталог модулей общего назначения
                                    KomfortUserPack02      - каталог библиотеки расчетных модулей
Сохраним проект KomfortUserPack02.dpk в каталоге C:\MyDelphi7\KomfortUserPack02, подключим к нему модуль общего назначения KomfortCommonUnit.pas и другие модули, в которых будем описывать типы аппаратов и потоков.
            Текст KomfortUserPack02.dpk может выглядить так:
package KomfortUserPack02;

{$R *.res}
{$ALIGN 8}
{$ASSERTIONS ON}
{$BOOLEVAL OFF}
{$DEBUGINFO ON}
{$EXTENDEDSYNTAX ON}
{$IMPORTEDDATA ON}
{$IOCHECKS ON}
{$LOCALSYMBOLS ON}
{$LONGSTRINGS ON}
{$OPENSTRINGS ON}
{$OPTIMIZATION OFF}
{$OVERFLOWCHECKS ON}
{$RANGECHECKS ON}
{$REFERENCEINFO ON}
{$SAFEDIVIDE OFF}
{$STACKFRAMES OFF}
{$TYPEDADDRESS OFF}
{$VARSTRINGCHECKS ON}
{$WRITEABLECONST ON}
{$MINENUMSIZE 1}
{$IMAGEBASE $400000}
{$RUNONLY}
{$IMPLICITBUILD OFF}

requires
  rtl;

contains
  ShareMem,
  KomfortCommonUnit in '..\KomfortCommonUser\KomfortCommonUnit.pas',
  UserCommonUnit in 'UserCommonUnit.pas',
  UserUtils in 'UserUtils.pas',
  UserMixersUnit in 'UserMixersUnit.pas',
  UserPolimerUnit in 'UserPolimerUnit.pas',
  UserDemonomerUnit in 'UserDemonomerUnit.pas',
  UserDummyUnit in 'UserDummyUnit.pas';

end.
где
            ShareMem - модуль управления общей памятью программы и библиотки
                        стандартый модуль Delphi7
            KomfortCommonUnit - модуль классов Komfort, на базе которых стоится описание
                        типов аппаратов и потоков библиотек, подкключаемых к программе
                        Komfort2011.exe - стандартный модуль Komfort.
            UserCommonUnit - рекомендуется в модуль с этим именем помещать
            процедуры пользователя общего назначения, например, печати
            и описание типов потоков
      UserUtils - рекомендуется в модуль с этим именем помещать
            процедуры пользователя, которые используются в расчете
            аппаратов, например, пересчет состава потоков
Далее мы подключаем в проект модули расчета аппаратов, в нашем случае,
      UserMixersUnit - расчет аппаратов-смесителей потоков
      UserPolimerUnit - расчет полимеризации
      UserDemonomerUnit - расчет демономеризации

      Далее, удобно задать, чтобы скомпилированная Delphi библиотека создавалась в том же каталоге. Для Этого в Project/Options на странице Directories/Conditions укажите
      Output directory = C:\MyDelphi7\KomfortUserPack02

      Удобно также для отладки процедур библиотеки во время расчета ХТС указать параметры запуска Run/Parameters:
      Host application = c:\MyDelphi7\Komfort2011\Komfort2011.exe
      Parameters = /LIB=..\KomfortUserPack02\KomfortUserPack02.bpl
Тогда, при нажатии иконки Run (F9) запускается программа Komfort2011.exe, к которой подключается библиотека KomfortUserPack02.bpl, а Вы можете ставить в исходном коде процедуры расчета аппарата точки останова и проверять значение переменных.

Классы Komfort
      Описание аппаратов и потоков ХТС строится на базе классов, общих для программы Komfort2011.exe и библиотеки расчетых модулей .BPL. Эти классы находятся в модуле KomfortCommonUnit , подключаемом к пакету.     
            Важнейшие из этих классов
            TDescriptor       - класс описания типа потока
            TAppType         - класс описания типа аппарата
            TFlow               - класс описания  входного/выходного потока в процедуре расчета
                                      аппарата
            TApparat          - класс описания параметров расчета аппарата
            TAppDebug      - класс отладочной печати из процедуры расчета аппарата
            TAppConv        - класс блока сходимости для использования внутри процедуры
                                      расчета аппарата
Опишем использование этих классов в проекте.

Описание типов потоков
            В одном из модулей пакета (рекомендуется UserCommonUnit) следует разместить описание типов потоков. Например:
unit UserCommonUnit;
interface
   uses Windows, SysUtils, Variants, Classes, KomfortCommonUnit;
var
   Desc01: TDescriptor; //Декларация  переменной типа потока
...
implementation
...
initialization
   Desc01:=TDescriptor.Create('Flow',[
      P('Коксующаяся фракция', 0, varDouble, 11)  //  1
     ,P('Тяжелый газойль'    , 0, varDouble, 12)  //  2
     ,P('Легкий газойль'     , 0, varDouble, 13)  //  3
     ,P('Бензин'             , 0, varDouble, 14)  //  4
   ]);
   Desc01.HelpAsText:=
          'Поток крекинга газойля'
   ;
finalization
   FreeAndNil(Desc01);
end.
            В интерфейсной секции находится описание переменной - описателя типа потока Desc01, а в инициализационной секции этой переменной присваиваются значения - имя типа потока 'Flow' и описание 4 параметров потока 
            Для описания каждого из параметров потока, служит функция P (лат. Parametr)
P(
            'наименование параметра'
             ,значение по умолчанию
            ,тип параметра
   [
            ,номер компонента в базе физико-химических свойств веществ
            ,режим ReadOnly(только чтение): True/False, по умолчанию, False
            ,'формат представления плавающих чисел'
   ]
)
            Тип параметра = varDouble - плавающее число двойной точности
                                       varInteger - целое число
                                       varString   - строка
                                         и другие типы типов Variant (см.документацию Delphi)
            Номер компонента может - целое число. Если это - ноль или отрицательное число, данный параметр потока описывает общую характеристику потока: его температуру, давление, общий расход и т.п. Если номер - положительное число, данный параметр описывает компонент/вещество - его мольный или весовой расход, концентрацию и т.п. Имеются функции "встроенного Паскаля" Total - расчет общего расхода потока и Part/Total - вычисление доли/процента компонента - они суммируют только те параметры потока, которые имеют номер компонента - положительное число.
            Предполагается, что положительное число - номер вещества в базе данных.
            Формат представления параметров - плавающих чисел, например, '%.7g' - общий формат с семью значащими цифрами.

Описание типа аппарата
            Описание каждого типа аппарата рекомендуется в отдельном модуле - файле .pas.
Рассмотрим простой пример - расчет сепаратора, когда коэффициенты разделения компонентов одинаковы. Мы должны:
            1) Описать собственно расчетную процедуру Separator. Это процедура-функция, которая возвращает целочисленное значение - код возврата. Нулевой код означает нормальное завершение расчета. Ненулевой код вызовет остановку во время расчета схемы, чтобы пользователь принял решение о возможности продолжения расчета.
            Процедура имеет список параметров, все типа TFlow - массивы значений. Сначала идет обязательный параметр Parm - массив параметров расчета, затем списки входных и выходных потоков: Out1, Out1, Out2.
            2) Описать переменную типа аппарата  TAppType.
            3) В инициализационной секции заполнить переменную типа аппарата значениями - описаниями: наименование типа, адрес расчетной процедуры, описание списка параметров, описания входных и выходных потоков.
            
unit SeparatorUnit;

interface
uses Windows, SysUtils, Variants, Classes
    ,KomfortCommonUnit, UserCommonUnit, UserUtils;

implementation

//описание функции расчета аппарата
function Separator(
    Parm:   TApparat  //параметры расчета
  ; Inp1:   TFlow     //1-ый входной поток
  ; Out1:   TFlow     //1-ый выходной поток
  ; Out2:   TFlow     //2-ой выходной поток
): Integer;
var
   Alfa: Double;   //доля отбора в первый выходной поток
   I:    Integer;
begin
   Result:=0;
// код завершения расчета аппарата, если >0, расчет будет прерван

   Alfa:=Parm[1]/100;
   for I:=1 to Inp1.Count do begin
      Out1[I]:=Inp1[I]*Alfa;
      Out2[I]:=Inp1[I]*(1-Alfa);
   end;
end; {Separator}

var  //переменная типа аппарата
   SeparatorAppType: TAppType;
initialization
   SeparatorAppType:=TAppType.Create(
      'Separator'           //наименование типа аппарата
      ,Addr(Separator)      //адрес функции расчета
      ,[ //описание списка параметров расчета
         P('% отбора в первый выходной поток',0.5,varDouble)
       ]
      ,[ //описание списка входных потоков
         F('входной поток',Desc01)          //Inp1
       ]
      ,[ //описание списка выходных потоков
         F('первый выходной поток',Desc01)  //Out1
        ,F('второй выходной поток',Desc01)  //Out2
       ]
   );
finalization
   SeparatorAppType.Free;
end.

Примечание: для описания параметров расчета аппарата, также, как и потока, служит функция P (от Parameter)
P(
            'наименование параметра'
             ,значение по умолчанию
            ,тип параметра
   [
            ,номер компонента в базе физико-химических свойств веществ
            ,режим ReadOnly(только чтение): True/False, по умолчанию, False
            ,'формат представления плавающих чисел'
   ]
)
            Тип параметра = varDouble - плавающее число двойной точности
                                       varInteger - целое число
                                       varString   - строка
                                         и другие типы типов Variant (см.документацию Delphi)
            В описании параметра аппарата номер компонента не имеет значения.
Для описания входных и выходных потоков аппарата служит функция F (от Flow):
F(
   'наименование входного или выходного потока'
  ,дескриптор типа потока
)

            Таким образом, классы TDescriptor и TAppType служат для создания объектов - описателей типов потоков и типов аппаратов (их расчетных процедур). Классы TApparat и TFlow - для описания параметров расчета аппарата и его входных и выходных потоков. Внутри процедур расчета аппаратов разработчик может использовать готовые экземпляры объектов TAppDebug и TAppConv:
            Dbg: TAppDebug
и          Conv: TAppConv

Отладка и передача информации в процедурах
расчета аппаратов
Объект Dbg имеет методы для отладочной печати
            Dbg.Write([  <список значений> ]);        //вывод в протокол без перевода строки
            Dbg.WriteLn([  <список значений> ]);    //вывод в протокол с переводом строки
Свойство Dbg.Active (True/False) позволяет узнать и/или установить режим отладочной печати - при Dbg.Active=False вывод отладочной печати подавлен, это то же самое, что галочка "отладочная печать" на диалоговой форме "Расчет".
Функция Dbg.MsgBox позволяет организовать диалог с пользователем:
Dbg.MsgBox(
            'Текст сообщения'
     [
            ,коды кнопок и иконок
            ,'Заголовок сообщения'
    ]
) - возвращает код нажатой кнопки.
Список мнемонических кодов кнопок, например, vbYesNo, vbOKOnly, иконок, например, vbQuestion, кодов результата, например, vbYes, vbNo - см. в модуле KomfortCommonUnit.pas.
Например:
            if Dbg.MsgBox(
                                     'Да - включить отладочную печать'
                        +#13#10'Нет - выключить отладочную печать'
                        ,vbYesNo+vbQuestion
                        ,'Подтвердите'
            )=vbYes then
                        Dbg.Active:=True
            else
                        Dbg.Active:=False;        

Функция Dbg.InputBox позволяет запросить от пользователя ввести некототорую строку:
Dbg.InputBox ( <заголовок> , <текст> , <строка-результат по умолчанию> ) -> строка, введенная пользователем.
Например,
            S:=Dbg.InputBox('Введите число','элементов нагрева','10');
            N:=StrToIntDef(S,10);

            Объект Dbg позволяет узнать и/или изменить значение параметра любого потока и аппарата схемы из любого расчетного модуля с помощью свойств App и Flow:
Dbg.App  [  <номер или наименование аппарата> , <номер параметра> ]
Dbg.Flow [  <номер или наименование потока>     , <номер параметра> ]

            Свойство Dbg.Common позволяет передать значение любого типа (Variant) между любыми аппаратами схемы.
Например, в аппарате номер 2 мы присваиваем некоторое значение
            Dbg.Common[ 'расход воды подпитки' ] := X;    
            //или Dbg.SetCommon('расход воды подпитки',X);
а в аппарате 6 считываем это значение
            Y := Dbg.Common[ 'расход воды подпитки' ] ;
            //или Y := Dbg.GetCommon( 'расход воды подпитки')] ;

Обратите внимание, в свойствах App, Flow и Common используются квадратные, а не круглые скобки.
 
Организация сходимости в процедурах
расчета аппаратов
Иногда требуется организовать сходимость - решить одно или систему уравнений - не только на уровне схемы, но и внутри отдельного аппарата. Для этой цели используется готовый экземпляр объекта Conv класса  TAppConv, используемый таким образом:
   //идентификатор в Open/Close используется для проверки парности этих "скобок"
   Conv.Open('Test1');     //открыть 1-ый уровень вложенности блоков сходимости
      Conv.Arg(X1,'X1');   //задать переменные поиска
      Conv.Arg(X2,'X2');
      repeat

         Conv.Open('Test2');  //открыть 2-о1 уровень вложенности блоков сходимости
            Conv.Arg(X3,'X3');
            repeat
               Conv.DisBal( F3(X1,X2,X2) - Y3 );
            until Conv.Finish;
         Conv.Close('Test2'); //закрыть 2-ой уровень вложенности блоков сходимости

         Conv.DisBal( F1(X1,X2,X3) - Y1 );  //вычислить невязки уравнений
         Conv.DisBal( F2(X1,X2,X3) - Y2 );
      until Conv.Finish;                    //условие продолжения итераций
      if not Conv.Success then              //проверка успешности поиска решения
         MsgBox('Решение не найдено!');
   Conv.Close('Test1');    //закрыть 1-ой уровень вложенности блоков сходимости

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

            Необязательная функция описания предметной области
function PackComments: String;
exports PackComments;
возвращает многострочный текст описания назначения и области применения.

            Необязательная функция возвращает версию пакета
            для сохранения в файле-схеме .XTC
function GetPackVersion: String;
exports  GetPackVersion;
возвращает строку-идентификатор, позволяющую различать между собой версии библиотек, на базе которых создана та или иная схема. Этот идентификатор будет сохранен в файле .XTC при записи.

            Необязательная функция проверки при чтении файла-схемы
            соответствия версии пакета, с которым была записана эта схема
            pFileVersion, с версией текущего пакета
function TestPackVersion(pFileVersion: String): Boolean;
exports  TestPackVersion;
сравнивает считанный из файла идентификатор pFileVersion с текущей версией пакета.
Позволяет запрещать загрузку файлов .XTC, если они несовместимы с текущей версией пакета.

            Процедура BeforeRunSchema запускается перед каждым расчетом
procedure BeforeRunSchema(
      Apparats: array of TApparat; Flows: array of TFlow);
exports   BeforeRunSchema;
позволяет провести обработку всех аппаратов и потоков схемы, проверить и скорректировать их параметры перед расчетом.

            Процедура AfterRunSchema запускается после каждого расчета
procedure AfterRunSchema(
      Apparats: array of TApparat; Flows: array of TFlow);
exports   AfterRunSchema;
позволяет обработать все аппараты и потоки схемы,  проверить и скорректировать их параметры после расчета.

            Процедура UserProcessing обработки схемы по кнопке "Внешняя обработка"
procedure UserProcessing(Apparats: array of TApparat; Flows: array of TFlow);
exports   UserProcessing;
позволяет обработать все аппараты и потоки схемы, например, сохранить всю информацию о схеме в файле своего собственного формата.
Пример такой процедуры, которая автоматически заполняет описания аппаратов и потоков:
procedure UserProcessing(Apparats: array of TApparat; Flows: array of TFlow);
var
   I, J: Integer;
   App:  TApparat;
   Flow: TFlow;
   S:    String;
begin
   if Dbg.MsgBox(
      'Выполнить нестандартную обработку'
     ,vbYesNo+vbQuestion
     ,'Подтвердите'
   )=vbNo then
      Exit;
   for I:=0 to High(Apparats) do begin
      App:=Apparats[I];
      S:=App.Caption;
      for J:=1 to App.Count do
         S:=S+Format(#13#10'%-20s = %s',[App.Descriptor.ItemName[J],VarToStr(App.Value[J])]);
      App.Text:=S;
   end;
   for I:=0 to High(Flows) do begin
      Flow:=Flows[I];
      S:=Flow.Caption;
      for J:=1 to Flow.Count do
         S:=S+Format(#13#10'%-20s = %s',[Flow.Descriptor.ItemName[J],VarToStr(Flow.Value[J])]);
      Flow.Text:=S;
   end;
end; {UserProcessing}

            Функция PrintFlow печати потока
function PrintFlow(Flow: TFlow): Boolean;
exports PrintFlow;
позволяет выполнить нестандартный вывод. Вывод производится командами печати
Dbg.WriteLn([ список переменных через запятую ]);
аналогичными командам вывода Delphi: WriteLn( список переменных через запятую]);
Функция PrintFlow возвращает True, если сама успешно выполнила печать. Если она вернула False, будет использована стандартная печать моделирующей программы.

            Функция PrintApparat печати аппарата
function PrintApparat(Apparat: TApparat): Boolean;
exports PrintApparat;
аналогична печати PrintFlow.

            Функция User подключается к встроенному Паскалю
function User(const Args: Variant): Variant;
exports User;
и может быть использована в кодах начала/конца сходимости:
   Y:=User(X1,X2,...);
Список параметров может быть произвольным, в том числе пустым:
   Y:=User();
Разработчик должен проанализировать входную переменную Args, которая является вариант-массивом с индексом  от 0 до VarArrayHighBound(Args,1).
Пример функции, которая может вычислять сумму всех своих параметров
            Y:=User(11,12,13);
function User(const Args: Variant): Variant;
var
   I: Integer;
begin
   Result:=0;
   for I:=VarArrayLowBound(Args,1) to VarArrayHighBound(Args,1) do
      Result:=Result+Args[I];
end;


Как получить заготовку библиотеки
расчетных модулей быстро
            Поскольку создавать библиотеку расчетных модулей вручную "с нуля" хлопотно, в комплект поставки входит утилита KomfortCreatePack.exe, создающая заготовку библиотеки расчетных модулей. Запустите эту программу
graphic
и укажите имя нового проекта - и, одновременно, подкаталога в C:\MyDelphi7\  .
Затем откройте проект .dpk в этом каталоге и отредактируйте его.
  

Как создать библиотеку расчетных модулей
Предыдущий Начало Следующий