#Программа Elcut должна быть запущена и открыта задача coil.pbm. use Win32::OLE; #=============================================== #Расчет сил в Elcut #=============================================== sub getELCForceX { $x_position = $_[0]; #входной параметр #0. открыть модель #1. проверить положение якоря, передвинуть якорь #2. рассчитать силу # 0. открыть модель $ELC = Win32::OLE->new("ELCUT.Application"); #подключить Elcut $pbm = $ELC->Problems->Item(1); #доступ к первой открытой задаче $pbm->LoadModel(); #загрузить модель $mdl = $pbm->Model; #подключить модель #1. проверить положение якоря по оси x, координату вершины "R" якоря #Метод Invoke() позволяет изменить свойства с аргументами, которые не поддерживаются стандартным синтаксисом $theVertex = $mdl->Shapes->Vertices->Invoke("LabeledAs","R","","")->Item(1); $theXposition = $theVertex->Point->X; #расчет координаты x вершины "R" $theVector = $ELC->PointXY($x_position - $theXposition, 0); #расчет вектора перемещения #якорь состоит из 2-ух блоков: "изоляция" (внешний), "сердечник" (внутренний) #если передвигать внешний блок, то внутренний блок также будет передвинут $theBlock = $mdl->Shapes->Blocks->Invoke("LabeledAs","","","изоляция")->Item(1); #выбор блока "сердечник" $theBlock->Move(0, $theVector); #перемещение сердечника . 0=qfShift, перемещение #2. Solve problem $mdl->Shapes->BuildMesh(True, False); #построение сетки $mdl->Save(); #сохранение модели if (!($pbm->Solved())) #проверка, решена ли задача { $pbm->SolveProblem(); #решение задачи }; $pbm->AnalyzeResults(); #открыть результаты $res = $pbm->Result; #ссылка на объект результатов $theFieldWindow = $res->GetFieldWindow(1); #подключение окна показа результатов $theContour = $theFieldWindow->Contour; #построение контура интегрирования #якорь состоит из 2-ух блоков: "изоляция" (внешний), "сердечник" (внутренний) $theContour->AddBlock1("изоляция"); #добавление к контуру блок "изоляция" $theContour->AddBlock1("сердечник"); #добавление к контуру блокa "сердечник" #Расчет интеграла магнитной силы $theForce = $res->GetIntegral(15, $theContour)->Value; #15=qfInt_MaxwellForce return $theForce->X; #вывод x-компоненты силы } #=============================================== # основная программа начинается здесь #=============================================== #физические параметры реле $x_out = 0.01; # максимально возможное положение, м $x_in = 0.006; # минимально возможное положение, м $m_mass = 0.0045; # масса сердечника, кг $k = 4.0; # коэффициент упругости пружины, Н/м $x_spring_free = 0.015; # положение без влияния пружины, м #начальные условия $t_time = 0.0; # время, с $x_position = $x_out; # положение сердечника, м $v_speed = 0.0; # скрость сердечника, м/с $dt_time_step = 0.005; # шаг интегрирования, с $max_time = 0.2; # максимальное время интегрирования print "t [s] x [m] v [m/s]\n"; while (($t_time < $max_time) and ($x_position > $x_in)) { $theForce = getELCForceX($x_position); # электромагнитная сила $theForce += ($x_spring_free - $x_position) * $k; # добавление упругой силы $v_speed += $theForce / $m_mass * $dt_time_step; # расчет ускорения и скорости $x_position += $v_speed * $dt_time_step; # расчет положения сердечника $t_time += $dt_time_step; # приращение времени print "$t_time $x_position $v_speed\n"; # выходные результаты }; print "Done.\n"; exit();