Есть две версии этого примера:
"..\ActiveField\Tutorial\Lesson1\VB_Code\" - на Visual Basic 6.0
"..\ActiveField\Tutorial\Lesson1\VBA_Code\" - на VBA (MS Excel)
Работая с параметрической моделью, обычно приходится делать следующие шаги:
Шаг 1: Создание нового проекта Visual Basic.
Подготовка и создание нового проекта в Basic.
Шаг 2: Запуск ELCUT.
Запуск ELCUT и подготовка его для работы.
Шаг 3: Открытие существующей задачи ELCUT:
Задача Magh1.pbm в папке ELCUT/Examples.
Шаг 4: Изменение геометической модели.
Перемещение стального якоря, построение сетки конечных элементов и сохранение модели.
Шаг 5: Изменение физических свойств.
Если потребуется, то изменить физические свойства сред, источники поля и граничные условия. В данном примере требуется поменять коэрцитивную силу магнита из сплава АЛНИКО.
Шаг 6: Решение задачи.
Решение задачи и получение результатов.
Шаг 7: Анализ результатов: вычисление локальных и интегральных величин.
Построение замкнутого контура вокруг якоря для вычисления механической силы.
Заключение
Пользовательский интерфейс, конечный код и ссылки.
Начальные шаги в Visual Basic такие же, как и при создании любого другого проекта. Запустите Visual Basic 6.0 и выберите New Standard EXE в диалоговом окне New Project.

Новый проект содержит одну форму Form. В этом уроке показано, как создать очень простой проект с минимальным интерфейсом пользователя. Весь код помещается в функцию Form_Load ().

Sub Form_Load ()
' Здесь мы напишем код
End Sub
Процедура Form_Load () вызывается исполняющей средой VB сразу после запуска нашего приложения, до того, как форма появится на экране.
Если создавать проект в Visual Basic for Application, который является частью Microsoft Office, то сначала надо запустить какое-нибудь приложение MS Office, например MS Excel. Потом надо запустить редактор VBA (команда Tools->Macro->Visual Basic Editor).

Не имеет значение, к какому обекту Excel написать код. Например, напишем код в модуле ThisWorkbook. В отличии от VB, здесь необходимо написать начальные строки самим, так как это показано на картинке.
Когда проект создан, необходимо сказать Basic об объектах, которые будут использоваться. Вся информация необходимая для работы с объектами ELCUT хранится в библиотеке типов ELCUT (файл ActiveField.dll). Эта библиотека регистрируется в системе при установке ELCUT (версии 5.1 и выше). Чтобы добавить в проект ссылку на библиотеку типов, выберите команду Project->References в VB или Tools->References в VBA. Потом в диалоговом окне в списке библиотек найдите строку ELCUT Object Library и установите ей флажок.

Теперь сохраним проект. Чтобы сделать это в VB, сохраните проект и все сопутствующие файлы. В VBA надо сохранить документ MS Office, который является контейнером для VBA кода (в нашем случае это Magn1_VBA.xls).
Теперь всё готово для работы с объектами ELCUT. Самый первый объект, который всегда используется это ELCUT.Application. Объект Application предоставляет доступ ко всем другим объектам, поэтому его можно объявить как глобальную переменную.
Public ELC As ELCUT.Application
Sub MyMacro()
' Здесь мы напишем код
Set ELC = CreateObject("ELCUT.Application")
ELC.MainWindow.Visible = True
End Sub
В первой строчке описывается глобальная переменная ELC, которая представляет объект Application. Если ELCUT уже запущен, то стандартная функция Visual Basic CreateObject возвращает запущенный ELCUT. Если же ELCUT еще не запущен, то функция его запустит.
Попробуйте запустить написанный выше код. В учебных целях наиболее походящий способ работы это выполнение кода строчка за строчкой в режиме отладки. Пожалуйста, выберите Debig->Step Into или просто нажмите F8, чтобы перейти к следующей строке кода.
Если ELCUT не был запущен до этого или находился в невидимом режиме, то на экране окна видно не будет. Последняя строчка кода делает ELCUT видимым. При запуске этой строчки окно ELCUT появляется на экране. Заметьте, что используется свойство Visibe объекта, представляющего главное окно ELCUT, который в свою очередь доступен через свойство MainWindow объекта Application.
Если Вы не знакомы с такими понятиями как объекты их методы и свойства, возможно лучшим для Вас будет просмотреть книгу или файл помощи по программированию в Microsoft Excel (или любому другому приложению поддерживающего программирование на VB). Вы увидите, как такие хорошо знакомые вещи, как книга, лист, и ячейка могут быть представлены как объекты, и как ими можно управлять.
Когда у нас есть объект Application, то открыть документ ELCUT это очень простая задача. Есть несколько коллекций документов, по одной для каждого типа документа. Взгляните на следующий код:
Public ELC As ELCUT.Application
Sub MyMacro()
' Здесь мы напишем код
Set ELC = CreateObject("ELCUT.Application")
ELC.MainWindow.Visible = True
' Октрываем задачу Magn1.pbm
Dim prb As ELCUT.Problem
Set prb = ELC.Problems.Open ("H:\ELCUT\Examples\Magn1.pbm")
End Sub
В первой выделенной жирно строке описывается переменная prb типа ELCUT.Problem. Она становится новой задачей, загружаемой из файла Magn1.pbm.
Параметр метода Open задает полное имя задачи. Другая возможность сначала задать путь к папке в свойстве DefaultFilePath:
ELC.DefaultFilePath = "H:\ELCUT\Examples"
Set prb = ELC.Problems.Open ("Magn1.pbm")
Через графический интерфейс пользователя модель загружается для редактирования из дерева задачи. Работая с объектной моделью, мы делаем почти тоже самое. Метод LoadModel загружает модель (объект Model), связанную с задачей. Теперь модель доступна через свойство Model.
Стоит поместить код, в котором происходит изменение геометрической модели, в отдельную процедуру, чтобы запускать его с различными параметрами.
Объявим переменную типа ELCUT.Model, которая будет хранить модель (объект Model). Потом получим геометрическую модель, используя метод LoadModel и свойство Model объекта Problem.
Sub MoveKeeper(prb As ELCUT.Problem, _
ByVal left As Double, ByVal bottom As Double)
Dim mdl As ELCUT.Model ' геометрическая модель
prb.LoadModel
Set mdl = prb.Model
' Коллекция Shapes, содержащая
' все геометрические объекты в модели и
' предоставляющая методы для добавления рёбер и вершин
With mdl.Shapes
.RemoveMesh
' Удаление старого блока Steel Keeper
.LabeledAs(Block:="Steel Keeper").Delete
' и создание нового:
.AddEdge ELC.PointXY(left, bottom), _
ELC.PointXY(left, bottom +
skHigh)
.AddEdge ELC.PointXY(left, bottom + skHigh), _
ELC.PointXY(left + skWidth,
bottom + skHigh)
.AddEdge ELC.PointXY(left + skWidth, bottom + skHigh), _
ELC.PointXY(left + skWidth,
bottom)
.AddEdge ELC.PointXY(left + skWidth, bottom), _
ELC.PointXY(left, bottom)
' Определение позиции нового блока и присвоение еу метки
.Nearest(ELC.PointXY(left + skWidth / 2, _
bottom + skHigh /
2)).Blocks.Label = "Steel Keeper"
.BuildMesh
End With
mdl.Save
mdl.Close
End Sub
Большинство операций с моделью проводятся через коллекцию Shapes, которая содержит все геометрические объекты модели. Чтобы сделать текст программы более простым, поместим несколько строчек в оператор With. Метод Delete удаляет блок, помеченный как "Steel Keeper". Обратите внимание на то, как был указан блок: свойство LabeledAs возвращает коллекцию объектов с одинаковой меткой - точно так же, как если щелкнуть мышкой по метке в дереве задачи.
Потом мы добавили 4 ребра и получили прямоугольный блок. Для обозначения размеров использовались параметры left и bottom (тип Double), задающие позицию блока и локальные переменные skWidth и skHigh, задающие размеры блока. Заметьте, что метод AddEdge требует два параметра типа Point. Мы задействовали дополнительный метод PointXY объекта Application, чтобы создать новую точку (объект Point) с нужными координатами.
Когда ребра построены, необходимо присвоить метку вновь созданному блоку. Самый удобный способ указать блок это использовать свойство Nearest, которое возвращает ближайший блок (объект Block), ребро (объект Edge) и вершину (объект Vertex) к данной точке. Свойство Label возвращает и устанавливает метку геометрическому объекту.
Перед тем как закончить с геометрической моделью, мы построим сетку конечных элементов (метод BuildMesh) и потом сохраним и закроем модель.
Представим, то надо изучить влияние коэрцитивной силы магнита АЛНИКО на механическую силу. В этом случае потребуется изменить свойства метки. Процедура, устанавливающая заданную величину коэрцитивной силы для обеих меток магнитов "ALNICO up" и "ALNICO down", показана ниже.
Sub SetCoerciveForce(prb As ELCUT.Problem, ByVal Hc As Double)
' Переменные для хранения метки и её содержимого
Dim lab As ELCUT.Label
Dim labCnt As LabelBlockMS
' Получение желаемой метки
Set lab = prb.Labels(qfBlock).Item("ALNICO up")
' Получение содержимого метки для редактирования
Set labCnt = lab.Content
' Изменение содержимого метки
labCnt.Coercive = ELC.PointRA(Hc, PI / 2)
' Возвращение измененного содержимого метки обратно метке
lab.Content = labCnt
' Тоже самое для другой метки
Set lab = prb.Labels(qfBlock).Item("ALNICO down")
Set labCnt = lab.Content
labCnt.Coercive = ELC.PointRA(Hc, -PI / 2)
lab.Content = labCnt
' Сохраниние файла описания свойств
lab.DataDoc.Save
End Sub
Самый главный объект здесь это объект Label и его содержимое (в нашем случае LabelBlockMS). Чтобы изменить физические данные, необходимо найти метку в одной из коллекций Labels, получить содержимое метки, используя свойство Contents, изменить это содержимое (объект Content) и вернуть его обратно объекту Label.
Точный тип объекта Content зависит от типа задачи (электростатика, теплопередача и другие). В нашем примере решается задача магнитостатики, так что содержимое имеет тип LabelBlockMS.
Закончив редактирование меток, следует сохранить соответствующий файл описания свойств. Каждая метка "знает" к какому документу она принадлежит (свойство DataDoc).
Когда модель и физические свойства готовы, а соответствующие файлы сохранены, можно запустить процесс решения. Самый простой способ сделать это использовать метод SolveProblem объекта Problem. Можно проверить, готовы ли модель и физически свойства, перед тем как решать задачу. Свойство CalSolve объекта Problem возвращает True если всё нормально. Свойство Solved позволяет узнать решена ли задача или нет.
If prb.CanSolve Then prb.SolveProblem
If prb.Solved Then prb.AnalyzeResults
Этот подход можно использовать, если время решения короткое. Когда процесс решения занимает несколько минут и более, удобнее использовать асинхронную версию метода SolveProblem:
prb.SolveProblem True
Установим параметру NoWait значение True, вместо False, используемого по умолчанию. В этом случае метод SolveProblem возвращает управление сразу после запуска процесса решения. Можно проконтролировать процесс решения, используя специальный объект SolvingState:
Dim state As ELCUT.SolvingState
Set state = prb.SolveProblem(True)
Когда задача решена, можно посмотреть результаты. Для этого используйте метод AnalyzeResults объекта Problem. После этого можно получить объект Result, позволяющий работать с графиками, таблицами и окнами для показа результатов. Объект Result содержит коллекцию окон. Это окна картины поля (объект FieldWindow), окна графиков (объект XYPlotWindow) и окна таблиц (объект TableWindow).
Как и при работе с графическим интерфейсом пользователя, можно построить контур (объект Contour) в окне картины поля (объект FieldWindow), который может быть использован для вычисления интегралов, построения графиков и таблиц.
Код, вычисляющий силу, помещен в отдельную функцию CalculateForce:
..........
If prb.Solved Then prb.AnalyzeResults
force = CalculateForce(prb.Result, xPos, yPos)
...........
Function CalculateForce(res As ELCUT.Result, _
ByVal left As Double, ByVal bottom As Double) As Double
Dim win As FieldWindow
Set win = res.Windows(1)
With win.Contour
.AddLineTo ELC.PointXY(left - 5, bottom - 0.5)
.AddLineTo ELC.PointXY(left + skWidth + 5, bottom
- 0.5)
.AddLineTo ELC.PointXY(left + skWidth + 5, bottom
+ skHigh + 5)
.AddLineTo ELC.PointXY(left - 5, bottom + skHigh +
5)
.AddLineTo
End With
CalculateForce = res.GetIntegral(qfInt_MaxwellForce).Abs
End Function
У объекта Result мы получили первое окно с картиной поля (активное окно всегда первое в коллекции) и построили в нем контур (объект Contour), окружающий якорь. Чтобы добавить линию к контуру, использовался метод AddLineTo. Последний вызов этого метода без параметров замыкает контур.
Замкнув контур можно вычислить силу, действующую на тела внутри контура. Чтобы сделать это, используем метод GetIntegral объекта Problem. Метод возвращает интегральную величину типа Quantity, которая объединяет физические величины нескольких типов. Свойство Abs объекта Quantity возвращает абсолютную величину.
Наша программа почти закончена. Для удобства пользования добавим простую форму, где можно будет ввести начальную и конечную позиции якоря, величину шага и коэрцитивную силу магнита.
При нажатии на кнопку Start запускается процедура DoCalculation:
Public Sub DoCalculation(Hc As Double, _
Ymin As Double, YMax As Double, Step As Double)
Set ELC = CreateObject("ELCUT.Application")
ELC.MainWindow.Visible = True
' Открываем задачу Magn1.pbm
Dim prb As ELCUT.Problem
' Предполагается, что файлы находятся
' в папке Magn1 внутри рабочей папки проекта
ELC.DefaultFilePath = VB.App.Path & "\Magn1"
Set prb = ELC.Problems.Open("Magn1.pbm")
' Изменение физических свойств
' смотрите Шаг 5
SetCoerciveForce prb, Hc
Dim yPos As Double, xPos As Double ' Позиция якоря
Dim force As Double ' Механическая сила
Dim i As Integer ' Счетчик цикла
For i = 1 To (YMax - Ymin) / Step + 1
' Изменение позиции якоря
xPos = XposBase
yPos = YposBase + Ymin + Step * (i - 1)
'
Изменение геометрической модели.
' смотрите шаг 4
MoveKeeper prb, xPos, yPos
'
Решение задачи
' смотрите шаг 6
If prb.CanSolve Then prb.SolveProblem
If prb.Solved Then
' Анализ результатов
' смотрите шаг 7
prb.AnalyzeResults
force =
CalculateForce(prb.Result, xPos, yPos)
End If
' Печать строки результатов на экране
MainDialog.DisplayStepResult yPos, force
Next
' Завершение работы ELCUT
ELC.Quit
Set ELC = Nothing
End Sub
Закончив работу с ELCUT, надо закрыть приложение. Метод Quit объекта Application, работает почти также, как команда Файл->Выход.