Архитектура программного комплекса «Электродизайнер»

 

Введение. 2

1. Создание кнопки на палитре компонентов. 3

2. Создание нового типа компонента – объекта. 5

3. Создание нового типа компонента связи. 5

4. Удаление объекта. 7

5. Создание редакторов свойств. 8

6. Интерфейс редактора формул. 10

6.1 Вычислительный интерфейс. 10

6.1.1 Интерфейс класса MathFormula. 11

6.1.2 Интерфейс класса ObjectFormulaTree. 11

6.1.3 Интерфейс класса ElementaryObjectArgument. 12

6.2 Графический интерфейс редактора формул. 13

6.2.1 Графический интерфейс класса MathFormula. 14

6.2.2 Интерфейс класса FormulaEditorUI.FormulaEditorForm.. 14

7. Выполнение однотипных операций со всеми элементами рабочего поля. 15

8. Источники и потребители информации. 16

8.1 Введение. 16

8.2 Краткое описание интерфейса DataPerformer.IMeasurements. 17

8.3 Краткое описание интерфейса DataPerformer.IMeasure. 18

8.4 Краткое описание интерфейса DataPerformer.IDataConsumer 20

8.5 Краткое описание интерфейса DataPerformer.IDifferentialEquationSolver 21


 

 

Введение.

 

Программный комплекс «Электродизанер» позволяет строить сценарии, построенные при помощи объектов и связей. Объекты и связи редактируются при помощи графического конфигуратора. Использование конфигуратора заключается в следующем. Мы нажимаем кнопку нужного нам объекта на палитре (см. рис. 1). Далее мы делаем щелчок мышью на рабочем поле. После этого на рабочем поле появляется прямоугольный компонент, соответствующего объекта.  Для установки связи надо выбрать кнопку связи на палитре нажать мышку на компоненте первого из связываемых объектов, перетащить её, не отпуская кнопки, на компонент второго объект и затем отпустить кнопку мыши. Вызов редакторов свойств объектов и связей осуществляется путём нажатия правой кнопки мыши на квадрате соответствующего компонента. Щелчок мышью в верхней части компонента позволяет редактировать имя соответствующего объекта или связи. Направление стрелки связи совпадает с направлением ассоциации. Например, если нам надо задать положение объекта B относительно объекта A, то соответствующая стрелка направлена от B к A, поскольку положение A не зависит от положения B, но не наоборот. Аналогично если B является результатом трансформации A или, B находится под воздействием электромагнитного излучения A, то стрелка должна идти от B к А.

Рис 1. Графический конфигуратор объектов и связей.

 

Создание нового типа объекта и или связи состоит из следующих операций:

-          создание кнопки на палитре компонентов;

-          создание класса соответствующего компонента;

-          создание редактора свойств;

Ниже будет приведено подробное описание этих операций.

 

1. Создание кнопки на палитре компонентов.

 

Для создания кнопки необходимо сделать её идентификационный номер. Номера кнопок находятся в перечислении ElectromagneticUI.ButtonKinds Это перечисление выглядит следующим образом

/// <summary>

/// Kinds of buttons

/// </summary>

public enum ButtonKinds

{

Multifacets, Dipole, Camera, RelativeMeasure, CameraLink, Frame, MovedFrame, RadiationLink,

      RelativeMeasureLink, MeasureLink, GraphConsumer, FunctionConsumer, Volt, VoltLink,

      DirectionDiagram, SphericalHarmonics, Mirror, MirrorLink, FormulaFigure, Earth,

      FormulaTransformer, FormulaTransformerLink, FileFigure, TemplateFigure, FrameFormula,

      FlatWave, Turbine, PhaseSensor, PhaseSensorLink, SwitchLink, DifferentialEquation, FrameData,

      FrameDataLink, StateMachine, Nulling, NullingLink, Doppler, DopplerObject, DopplerFrame,

      VectorFormulaConsumer, MultiFacesSpectrum, SpectrumFigure, SpectrumRadiator, MultiFacesSpectrumSum,

      MultiFacesSpectrumSumLink, FlatWavesConsumer, FlatRadiatorLink, FlatConsumerLink, Series,

      UnaryLink, Regression, RegressionLink

};

 

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

В функцию FormsDiagramUI.FormDiagramUI.Prepare() добавляется код, который имеет примерно следующий вид

 

imageListSh.Images.Add(Image.FromFile("Turbine.ico"));

 

 

Здесь imageListSh является списком икон соответствующей панели. При этом “Turbine.ico” представляет имя файла иконы.

 

Далее в рассмотренной функции добавляется кнопка. Для этого в ту же функцию добавляется код.

 

 

new PaletteButton(ObjectsToolSh, (int)ButtonKinds.Turbine, "Turbine", PanelDesktop.GetResourceString("Turbine"), imageListSh.Images[9], 9, false);

 

 

 

Здесь

-          ObjectsToolSh является панелью на которую устанавливается кнопка;

-          (int)ButtonKinds.Turbineномер соответствующего компонента;

-          "Turbine" – представляет собой дополнительный текст (в ряде случаев он связан с именем вспомогательного файла).

-          PanelDesktop.GetResourceString("Turbine") – является хинтом соответствующей кнопки.

-          imageListSh.Images[9] – икона кнопки.

-          9 - номер иконы.

-          falseозначает что кнопка не используется для компонента – связи (она используется для компонента – объекта).

 

2. Создание нового типа компонента – объекта

 

            Новый тип компонента – объекта представляет собой класс, реализующий интерфейсы CategoryTheory.ICategoryObject и ISerializable.

Класс должен иметь атрибут [Serializable()] . Для того, чтобы создавались объекты данного класса необходимо добавить необходимый код в фабрику объектов. В нашем случае фабрикой объектов является класс ElectromagneticUI.ElectromagneticUIFactory . Объекты создаются функцией

ICategoryObject ElectromagneticUI.ElectromagneticUIFactory.CreateObject(PaletteButton button)

Данная функция имеет входным параметром соответствующую объекту кнопку и возвращает нужный объект. В приведённом ниже фрагменте данной функции показано, как создаётся объект – турбина.

 

                  else if (button.Kind == (int)ButtonKinds.Turbine)

                  {

                        return new Turbine();

                  }

 

3. Создание нового типа компонента связи.

 

Новый тип компонента – связи представляет собой класс, реализующий интерфейсы CategoryTheory.ICategoryArrow и ISerializable.

Класс должен иметь атрибут [Serializable()] . Для того, чтобы создавались объекты данного класса необходимо добавить необходимый код в фабрику объектов Объекты создаются функцией

ICategoryArrow ElectromagneticUI.ElectromagneticUIFactory.CreateArrow(PaletteButton button)

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

 

                  if (button.Kind == (int)ButtonKinds.Frame)

                  {

                        return new ReferenceFrameArrow();

                  }


 

Интерфейс ICategoryArrow    имеет два ключевых свойства.

/// <summary>

            /// The source of this arrow

            /// </summary>

            ICategoryObject Source

            {

                  get;

                  set;

            }

 

            /// <summary>

            /// The target of this arrow

            /// </summary>

            ICategoryObject Target

            {

                  get;

                  set;

            }

 

 

Они представляют собой начало и конец связи соответственно. Их надо реализовать таким образом, чтобы происходила проверка корректности выбора начала и конца связи, а также другие действия, обусловленные логикой связи. Пример реализации связи представлен следующим кодом (Данный пример иллюстрирует добавление в поле зрения 3D визуализатора нового трёхмерного объекта).

 

                        /// <summary>

            /// The source of this arrow

            /// </summary>

            public ICategoryObject Source

            {

                  get

                  {

                        return camera;

                  }

                  set

                  {

                        if (visible == value)

                        {

throw new Exception("Target of visible link should not concide with source");

                        }

                        if (! (value is CameraUI))

                        {

                             throw new Exception("Illegal source");

                        }

                        camera = value as CameraUI;

                  }

            }

           

            /// <summary>

            /// The target of this arrow

            /// </summary>

            public ICategoryObject Target

            {

                  get

                  {

                        return visible as ICategoryObject;

                  }

                  set

                  {

                        if (camera == null)

                        {

                             throw new Exception("Camera is missing");

                        }

                        if (camera == value)

                        {

throw new Exception("Target of visible link should not concide with source");

                        }

                        if (! (value is IVisible))

                        {

                             throw new Exception("Illegal target");

                        }

                        visible = value as IVisible;

                        camera.Add(visible);         //Adding visible object

                        if (visible is SphereUI)

                        {

 

                        }

                  }

            }

 

На данном примере мы видим, что производится проверка корректности. При некорректном выборе начала или конца стрелки выбрасываются исключения. Кроме того, в строке помеченной красным цветом происходит добавление в поле видимости 3D  визуализатора нового объекта.

 

4. Удаление объекта.

 

В ряде случаев при удалении объекта или связи необходимо осуществить ряд дополнительных операций. В подобной ситуации объект или связь должны реализовывать интерфейс CategoryTheory.IRemovableObject В приведённом ниже коде показано как это делается для рассмотренной выше связи с 3D  визуализатором


 

            /// <summary>

            /// The post remove operation

            /// </summary>

            public void RemoveObject()

            {

                  if (camera == null)

                  {

                        return;

                  }

                  if (visible == null)

                  {

                        return;

                  }

                  camera.Remove(visible);

            }

 

Данный код осуществляет удаление объекта из поля видимости визуализатора.

 

5. Создание редакторов свойств.

 

            Редакторы свойств и связей объектов представляют собой формы Windows.  создаются в фабрике объектов. Редакторы свойств связаны с визуальными компонентами рабочего поля. Последние представляют собой объекты типа ObjectLabel и ArrowLabel, причём оба этих типа являются наследниками класса NamedComponent. Класс ObjectLabel имеет свойство ICategoryObject Object, представляющее собой ассоциированный с компонентом объект. Класс ArrowLabel имеет свойство ICategoryArrow, представляющее собой ассоциированную связь, ассоциированную с компонентом. Кроме того сам класс NamedComponent имеет свойство ComponentName, которое должно отображаться в заголовке редактора свойств.

Для создания экземпляров редакторов свойств, служит следующая функция фабрики классов


 

 

Form CreateForm(NamedComponent comp)

 

Ниже приведен пример создания форм в данной функции

public Form CreateForm(NamedComponent comp)

{

      if (comp is ArrowLabel) //Создание редакторов свойств связей

      {

            ArrowLabel lab = comp as ArrowLabel;

            ICategoryArrow arrow = lab.Arrow;

            if (arrow is LinearMovedReferenceFrameArrow)

            {

                  return new FormMovedFrame(lab);

            }

            if (arrow is FrameFormula)

            {

                  return new FormFormulaFrame(lab);

            }

            if (arrow is ReferenceFrameArrow)

            {

                  return new FormFrame(lab);

            }

            return new DefaultForm(comp);

      }

      if (comp is ObjectLabel)//Создание редакторов свойств объектов

      {

            ObjectLabel objLabel = comp as ObjectLabel;

            ICategoryObject obj = objLabel.Object;

            if (obj is CameraUI)

            {

                  CameraUI camera = obj as CameraUI;

                  return new FormCamera(camera, objLabel);

            }

            if (obj is DipoleUI)

            {

                  return new FormDipole(objLabel);

            }

 

            return new DefaultForm(comp);

                  }

                  return null;

            }

 

Конструктор редактора свойств выглядит примерно следующим образом.

 

/// <summary>

/// Constructor

/// </summary>

/// <param name="label">Desktop component</param>

public FormDipole(ObjectLabel label)

{

InitializeComponent();    // Инициализация компонент формы

      DiagramUI.DefaultForm.LoadControlResources(this); // Загрузка ресурсов      this.label = label;                           // Присвоение компонента

      dipole = label.Object as DipoleUI; // Связанный с компонентом объект

// Дополнительные операции

      UpdateFormUI();                    // Присвоение имени заголовка формы

}

 

 

Для того чтобы заголовок свойств редактора совпадал с именем соответствующего объекта, редактор должен реализовывать интерфейс DiagramUI.IUpdatableForm.

 

Ниже приведён пример реализации данного интерфейса.

 

           

/// <summary>

/// Updates form UI

/// </summary>

public void UpdateFormUI()

{

Text = label.ComponentName;

      labelSource.Text = label.Source.ComponentName;

      labelTarget.Text = label.Target.ComponentName;

}

 

В данном примере осуществляется не только изменение заголовка формы, но и текстов меток.

 

Для того, чтобы при уничтожении редакторов уничтожались ссылки на них, необходима модификация метода Dispose. Ниже приведён соответствующий фрагмент кода.

 

/// <summary>

/// Clean up any resources being used.

/// </summary>

protected override void Dispose( bool disposing )

{

if( disposing )

      {

            if(components != null)

            {

                  components.Dispose();

            }

      }

      label.RemoveForm(false);

      base.Dispose( disposing );

}

 

Красной строкой отмечен оператор уничтожение ссылки.

 

6. Интерфейс редактора формул.

 

6.1 Вычислительный интерфейс.

 

            Классы вычислительного интерфейса редактора формул расположен в пространстве имён FormulaEditor. Основными его классами являются

 

MathFormula – собственно формула.

ObjectFormulaTree – вычислительное дерево.

 

ElementaryObjectArgument – аргумент формулы.

 

6.1.1 Интерфейс класса MathFormula.

 

Конструкция формулы из строки.

 

public static MathFormula FromString(int[] sizes, string str)

 

 

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

FormulaEditorUI.FormulaEditorPanel.sizes.

str - строковое представление формулы. В программном комплексе строковое представление создаётся при помощи графического интерфейса.

 

Преобразование формулы в строку.

 

public string FormulaString

{

      get;

}

 

Данное преобразование является обратным предыдущему. Оба этих преобразования служат для импорта/экспорта формул, записи/чтения их в потоки/из потоков.

 

Преобразование формулы для построения дерева.

 

public MathFormula FullTransform

{

      get;

}

 

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

 

6.1.2 Интерфейс класса ObjectFormulaTree.

 

Конструктор.

 

public ObjectFormulaTree(MathFormula formula, IFormulaObjectCreator creator)

 

 

formula – формула из которой строится дерево.

 

creator – интерпретатор формулы (обычно ElementaryFunctionsCreator.Object)

 

 

Вычисление значения функции.

 

public object Result

 

 

Данное свойство возвращает вычисленное значение.

 

Построение частной производной.

 

DerivationPerformer.Derivation(ObjectFormulaTree tree, string s)

 

s – строка в которой содержится переменная дифференцирования, например Deriv(“y”) вычисляет производную по y.

Данная  функция строит дерево производной.

 

Построение формулы из дерева.

 

public MathFormula FormulaCreator.CreateFormula(ObjectFormulaTree tree, byte level, int[] sizes)

 

level – уровень формулы равный нулю для основной формулы, единице для формулы – степени и т.д.

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

FormulaEditorUI.FormulaEditorPanel.sizes.

 

Переменные формулы (формул).

 

static public string ElementaryObjectDetector.GetVariables(MathFormula formula)

static public string ElementaryObjectDetector.GetVariables(MathFormula[] formulas)

 

 

Возвращает строку переменных формулы.

 

 

6.1.3 Интерфейс класса ElementaryObjectArgument.

 

Данный класс представляет собой аргумент формулы.

 

 

 

 

 

 

 

 

Конструктор

 

public ElementaryObjectArgument()

 

 

 

Строка аргументов.

 

public string Variables

{

      get;

}

 

Связывание с деревом (деревьями).

 

public void Add(ObjectFormulaTree tree)

public void Add(ObjectFormulaTree[] trees)

 

 

 

Доступ до значения аргумента

 

public object this[char s]

{

      set;

}

 

++++++++++++++++++++++++++++++++++++++++

 

Ниже приведён пример вычисления формулы при x = 2 и y = 5

 

MathFormula f = formula.FullTransform;

ObjectFormulaTree tree = new ObjectFormulaTree(f, ElementaryFunctionsCreator.Object);

ElementaryObjectArgument arg = new ElementaryObjectArgument();

arg.Add(tree);

arg[‘x’] = 2;

arg[‘y’] = 5;

double a = (double)tree.Result;

 

 

 

6.2 Графический интерфейс редактора формул.

 

Графический интерфейс позволяет строить визуальные изображения объектов класса MathFormula, а также включает формы редактора и панели отображения формул.

 

6.2.1 Графический интерфейс класса MathFormula.

 

Положение формулы.

 

public Point Position

{

      set;

      get;

}

 

Расчёт прямоугольника формулы.

 

public virtual void CalculateFullRelativeRectangle()

 

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

 

Расчёт позиций символов формулы.

 

public void CalculatePositions()

 

 

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

 

Рисование формулы.

 

public void Draw(Graphics g)

 

gГрафический элемент, на котором производится рисование.

 

+++++++++++++++++++++++++

 

Ниже приводится пример рисования формулы.

 

///Построение формулы из строки

formula = MathFormula.FromString(FormulaEditorPanel.Sizes, str);

formula.Position = pointFormula;   // Задание позиции формулы

 

//Подготовительные операции

formula.CalculateFullRelativeRectangle();

formula.CalculatePositions();

 

formula.Draw(g); //Рисование формулы

 

6.2.2 Интерфейс класса FormulaEditorUI.FormulaEditorForm

 

Рассматриваемый класс является формой, позволяющей редактировать формулу

 

Конструктор

 

public FormulaEditorForm(string s)

 

s – переменные редактора формул

 

Строковое представление формулы.

 

public string Formula { get; set;}

В приведённом ниже примере рассмотрено редактирование формулы и рисование её на экране.

 

string s = formula.FormulaString;  // Преобразование формулы в строку                        

FormulaEditorForm form = new FormulaEditorForm("xy"); // Создание экземпляра //редактора с переменными x и y

 

form.Formula = s;                          // Экспорт формулы в редактор

form.ShowDialog(this);                     // Редактирование формулы

s = form.Formula;                          // Импорт формулы из редактора

formula = MathFormula.FromString(FormulaEditorPanel.sizes, s); // Создние ///новой формулы

 

formula.Position = pointFormula;   // Задание позиции формулы

 

//Подготовительные операции

formula.CalculateFullRelativeRectangle();

formula.CalculatePositions();

Graphics g = Graphics.FromHwnd(this.Handle);

 

formula.Draw(g); //Рисование формулы

 

 

 

7. Выполнение однотипных операций со всеми элементами рабочего поля.

 

При решении ряда задач возникает необходимость выполнения однотипных операций со всеми элементами рабочего поля. Например, нужно для всех радиационных произвести подсветку всех облучаемых объектов. Рабочее поле имеет тип DiagramUI.PanelDesktop и является наследником стандартного класса Panel. Последний имеет свойство – коллекцию Controls. Это свойство содержит все компоненты, находящиеся на данной панели. Используя его можно производить однотипные операции со всеми компонентами. Ниже приведён фрагмент кода, который выполняет операции обновления  всех компонент, которые реализуют интерфейс обновления IUpdatableObject.

 

foreach (Control c in desktop.Controls) // Цикл по компонентам рабочего поля

{

      if (c is ObjectLabel)// Операция для компонент, соответствующих объектам

      {

            ObjectLabel label = c as ObjectLabel;

            ICategoryObject obj = label.Object;

            if (obj is IUpdatableObject) // Выбор нужных объектов

            {

                  IUpdatableObject updatable = obj as IUpdatableObject;

                  if (updatable.ShouldUpdate) // Проверка условия

                  {

                        updatable.UpdateObject();// Проведение операции

                  }

            }

      }

else if (c is ArrowLabel)// Операция для компонент, соответствующих //стрелкам

      {

            ArrowLabel label = c as ArrowLabel;

            ICategoryArrow arr = label.Arrow;

            if (arr is IUpdatableObject)

            {

                  IUpdatableObject updatable = arr as IUpdatableObject;

                  if (updatable.ShouldUpdate)

                  {

                        updatable.UpdateObject();

                  }

            }

      }

}

 

 

8. Источники и потребители информации.

 

 

Источниками информации являются объекты, реализующие интерфейс    DataPerformer.IMeasurements, а потребителями – объекты, реализующие интерфейс DataPerformer.IDataConsumer. Почти все потребители являются наследниками класса DataPerformer.DataConsumer, реализующего указанный выше интерфейс. Потребители связываются с источниками стрелками типа DataPerformer.DataLink. Логика работы источников/потребителей информации заключается в следующем. Потребитель, используя метод “void UpdateChildrenData()” опрашивает связанные источники информации которые в свою очередь вызывают метод «void UpdateMeasurements()» производя, необходимые операции по подготовке нужной информации. Следует отметить, что потребитель информации может быть одновременно и источником (см. Version 1.0). Во избежание порочного круга, мы можем связывать источник информации с потребителем, только в том случае, если потребитель создан позднее, чем источник.

 

8.1 Введение

 

Работа с источниками измерений, включающими формулы, разбивается на этапы. Если произошли изменения на этапе n, то необходимо повторить этапы n+1, n+2, … .

 

Этап 1.

 

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

 

Этап 2.

 

Выбор констант. На данном этапе выбирается состав констант. Рассмотрим следующий сценарий.

Редактор свойств компонента First выглядит следующим образом (Загрузить сценарий).

 

 

В данном сценарии обе переменных формулы представляют собой константы. Редактор свойств компонента Second имеет вид.

 

Редактор свойств компонента Second имеет вид.

 

 

Здесь только одна переменная является константой. Остальные две берутся из внешнего источника.

 

 

 

Этап 3.

 

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

 

 

 

 

В данном сценарии имеется одна константа “z”. Остальные переменные связываются с параметрами Formula_1 и Formula_2 компонента First.

 

 Рассмотрим другой пример с той же диаграммой, что и выше. (Загрузить сценарий) Редакторы свойств компонентов First и Second выглядят следующим образом

 

Редактор свойств компонента First

 

Редактор свойств компонента Second.

 

В редакторе свойств First результат второй формулы является булевым. Соответственно первая переменная x первой формулы компонента должна быть булевой (иначе интерпретатор формулы выдаст ошибку) Соответственно она связывается с булевым результатом компонента First.

 

Этап 4.

 

Задание значений констант.

 

 

 

 

 

8.2 Краткое описание интерфейса DataPerformer.IMeasurements

 

Данный интерфейс имеет свойство Count представляющее собой количество измеряемых параметров.

 

Свойство

 

IMeasure this[int n]

 

 

осуществляет доступ к n – му измеряемому параметру.  См. 8.3

 

Свойство

 

Control HeaderControl

 

 

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

 

 

 

public Control HeaderControl

{

      get

      {

            ObjectLabel lab = Object as ObjectLabel;

            return new ObjectPanel(lab);

      }

}

 

 

 

 

Свойство

 

string SourceName

 

представляет собой имя источника измерений

Обычно его можно задать следующим образом

 

NamedComponent nc = Object as NamedComponent;

return  nc.ComponentName;

 

 

Свойство

bool IsUpdated

 

предназначено для того, чтобы не было многократного пересчёта. После вызова метода UpdateMeasurements() нужно это свойство сделать равным false.

 

Метод

void UpdateMeasurements();

 

Данный метод осуществляет вычисление всех измеряемых параметров. Обычно данный метод заполняет рассчитывает значения измеряемых параметров и их производных, а затем заполняет двумерный массив result этими значениями. (В случае когда класс реализует интерфейс IDifferentialEquationSolver данная операция осуществляется в методе CalculateDerivations.)

 

8.3 Краткое описание интерфейса DataPerformer.IMeasure

 

 

Свойство

 

MeasureParameter Parameter

 

Возвращает делегат – функцию вычисления параметра

 

Свойство

 

MeasureParameter Derivation

 

Возвращает делегат – функцию вычисления производной.

 

 

Свойство

 

string Name

 

возвращает имя параметра

 

     

Свойство

 

double Factor

 

Чаще всего равно единице

 

 

Свойство

 

object Type

 

Возвращает объект – тип параметра. Для вещественных параметров этот тип равен

 

Double a = 0;

 

Чаще всего интерфейс реализован в виде класса DataPerformer.Measure

 

При этом функция UpdateMeasurements(); интерфейса IMeasurements

имеет вид

 

public void UpdateMeasurements()

{

      result[0, 0] = ... /// Первый параметр

      result[0, 1] = ... /// Производная первого параметра

}

 

 

Далее в классе, реализующем интерфейс IMeasurements определяются делегаты, имеющие примерно следующий вид.

 

private object getFirstParameter()

{

      return result[0, 0];

}

 

private object getFirstDerivation()

{

      return result[0, 1];

}

 

 

И, наконец,  создаётся объект типа DataPerformer.Measure следующим конструктором.

 

Double a = 0;

measures[0]  = new Measure(a, new MeasureParameter(getFirstParameter), new MeasureParameter(getFirstDerivation), “First”);

 

 

8.4 Краткое описание интерфейса DataPerformer.IDataConsumer

 

 

 

 

 

Метод

 

void AddTargetArrow(DataLink arrow);

 

 

Добавляет связь с источником измерений. Обычно осуществляется добавление к объекту типа ArrayList.

 

Метод

 

void RemoveTargetArrow(DataLink arrow)

 

Очевидно.

 

Метод

void UpdateChildrenData();

 

Осуществляет обновление источников измерений. Обычно имеет вид

 

public void UpdateChildrenData()

{

      try

      {

            foreach (DataLink arrow in arrows)             /// arrows представляет собой ArrayList связей с источниками измерений

            {

                  IMeasurements m = arrow.Measurements;

                  m.UpdateMeasurements();

            }

      }

      catch (Exception e)

      {

            NamedComponent.ThrowException(this, e);

      }

}

 

 

Свойство

 

int Count

 

Количество источников измерений.

 

 

Свойство

 

DataLink this[int n]

 

Связь с n – м источником измерений. Сам источник измерений представляет собой свойство Measurements объекта типа DataLink.

 

Метод

void Reset();

 

Данный метод рекурсивно ставит значение свойства IsUpdated всех источников измерений в положение false. Данную операцию можно осуществить следующим образом

DataConsumer.Reset(this);

8.5 Краткое описание интерфейса DataPerformer.IDifferentialEquationSolver

 

IDifferentialEquationSolver имеет следующие методы.

 

Метод

 

void CalculateDerivations();

 

 

Вычисляет значения производных и записывает их значения в элементы массива result.

 

Метод

 

void SetVariables(int b, double[] x);

 

Считывает  переменные из вспомогательного массива. Обычно это выглядит примерно следующим образом.

 

 

public void SetVariables(int b, double[] x)

{

      int i = b;

      foreach (object[] o in variables.Values)

      {

            o[3] = x[i];

            ++i;

            }

}

}

 

 

8.6 Класс DataPerformer.DynamicalParameter

 

 

Данный класс осуществляет связь переменных формулы с внешними внешними параметрами. Интерфейс данного класса представлен ниже.

 

 

8.7       Сериализация и десериализация информации о внешних источниках информации.

 

 

Информация о внешних источниках информации содержится в объекте типа ArrayList, который обычно называется arguments. Этот объект должен быть сериализован. Каждый элемент данного объекта является строкой, примерный вид которой приведён ниже.

 

"y = First.Formula_1"

Данная строка означает что переменная “y” формулы связана с выходным параметром “Formula_1” компонента First. После десериализации связей РМП вызывает метод PostSetArrow() который имеет вид.

 

 

 

public void PostSetArrow()

{

      DynamicalParameter parameter = new DynamicalParameter();

      foreach (DataLink arrow in arrows)

      {

      IMeasurements measurements = arrow.Measurements;

            IAssociatedObject ass = measurements as IAssociatedObject;

            NamedComponent nc = ass.Object as NamedComponent;

            string name = nc.ComponentName;

            for (int i = 0; i < measurements.Count; i++)

            {

                  IMeasure measure = measurements[i];

                  string p = name + "." + measure.Name;

                  foreach (string s in arguments)

                  {

                        if (s.Substring(4).Equals(p))

                        {

                             char c = s[0];

                             parameter.Add(c, measure);

                        }

                  }

            }

      }

      foreach (string s in arguments)

      {

            if (s.Substring(4).Equals("Time"))

            {

                  parameter.Add(s[0], ElectromagneticUIFactory.Object.TimeMeasure);

            }

      }

      Parameter = parameter;

      string argStr = AllVariables;

      foreach (string key in parameters.Keys)

      {

            arg[key[0]] = parameters[key];

      }

postSetUnary();

}

 

 

8.8       Константы, псевдонимы.

 

Помимо переменных формул взятых из внешних источников имеются также псевдонимы. Они, как правило, хранятся в таблице Hashtable parameters. Ключами данной таблицы являются соответствующие переменные формул. Значениями являются соответствующие значения этих параметров. Данная таблица должна быть сериализована.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Задание.

 

 

На приведённом рисунке изображён сценарий

 

 

 

 

 

с источниками и потребителями информации. Когда обновляются данные потребителя объекта Graph обновление источников информации. Данная схема вместо однократного обновления компонентов F1 и F2 осуществляет двукратное. Необходима доработка программы с целью исключения многократного обновления. Для этого в интерфейс DataPerformer.IMeasurements должно быть добавлено свойство IsUpdated. После обновления источника Это свойство должно становиться равным true. В классе DataPerformer.DataConsumer необходимо реализовать статическую функцию

 

void ResetMeasurements(PanelDesktop desktop).

 

Данная функция должна у всех источников измерений ставит значение свойству IsUpdated значение false.

 

 

Задание 2.

 

 

 

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

 

 

В проекте метод Рунге Кутта реализован в классах

 

DataPerformer.DifferentialEquationProcessor и

 

DataPerformer.RungeProcessor

 

 

Метод Рунге Кутта описан в