Создание сложных компонентов на языке физического моделирования Engee
Язык физического моделирования Engee позволяет не только разрабатывать свои компоненты но и объединять разные компоненты в единое целое. Такие компоненты называются составными.
Это как конструктор, когда есть детали (компоненты) и наша задача - соединить их в правильном порядке.
Зачем делать составные компоненты?
"Упаковка" множества компонентов в один (как подсистема в обычном моделировании)
Массивы компонентов
Пример составного компонента
В качестве примера составного компонента рассмотрим двигатель постоянного тока с внешней нагрузкой вала.
Что бы удостовериться в том, что компонент был собран правильно, возьмем эталонную реализацию на примитивах из библиотеки ненаправленных блоков:
Для тестирования будем моделировать следующий сценарий: в первые 0.1 секунды работы двигатель работает без нагрузки на вал, и достигает максимальной скорости, а затем на вале возникает нагрузка.
Создание составного компонента
Составные компоненты создаются точно также как и пользовательские компоненты при помощи языка физического моделирования Engee. Поэтому, код компонента должен содержаться в файле *.ngpc, расположенном по пути поиска Engee.
Посмотрим на код компонента из файла DCMotorComosite.ngpc:
@engeemodel DCMotorComposite begin
@components begin
p = EngeePhysicalFoundation.Electrical.Pin(), [view = ("+" , "left" )]
n = EngeePhysicalFoundation.Electrical.Pin(), [view = ("-" , "left" )]
r = EngeePhysicalFoundation.Mechanical.Rotational.Flange(), [view = ("R" , "right" )]
c = EngeePhysicalFoundation.Mechanical.Rotational.Flange(), [view = ("C" , "right" )]
end
@parameters begin
rotor_resistance = 3.9 , [unit="Ohm" ]
rotor_inductance = 12e-6 , [unit="H" ]
motor_inertia = 0.01 , [unit="g*cm^2" ]
breakaway_torque = 0.02e-3 , [unit="N*m" ]
coulomb_torque = 0.02e-3 , [unit="N*m" ]
breakaway_velocity = 0.03347 , [unit="rad/s" ]
back_emf_constant = 0.072e-3 *60 /(2 *pi ), [unit="V/(rad/s)" ]
viscous_coefficient = 0.0 , [unit="N*m/(rad/s)" ]
end
@components [gui = None] begin
rotorResistor = EngeePhysicalFoundation.Electrical.Elements.Resistor(R=default(rotor_resistance))
rotorInductor = EngeePhysicalFoundation.Electrical.Elements.Inductor(L=default(rotor_inductance))
motorInertia = EngeePhysicalFoundation.Mechanical.Rotational.Elements.Inertia(I=default(motor_inertia))
friction = EngeePhysicalFoundation.Mechanical.Rotational.Elements.Friction(w_breakaway=default(breakaway_velocity),T_breakaway=default(breakaway_torque),T_coulomb=default(coulomb_torque), viscous_coefficient=default(viscous_coefficient))
rotEMechConverter = EngeePhysicalFoundation.Electrical.Elements.RotationalConverter(k=default(back_emf_constant))
end
@equations begin
connect(p, rotorResistor.p)
connect(rotorResistor.n, rotorInductor.p)
connect(rotorInductor.n, rotEMechConverter.p)
connect(rotEMechConverter.n, n)
connect(rotEMechConverter.rod_flange, friction.rod_flange, motorInertia.flange, r)
connect(rotEMechConverter.case_flange, friction.case_flange, c)
end
end
Обратите внимание на то, как мы создаем подкомпоненты - они содержатся в секции @components. Мы инициализируем их параметры значениями из секции @parameters
Сборка подкомпонентов в единый компонент происходит в секции @equations с помощью функции connect(). Обратим внимание, что можно указывать сразу несколько портов для соединения!
Тестирование составного компонента
Проверим результаты моделирования нашего составного компонента относительно той же модели, но на примитивах
Давайте построим графики результатов симуляции:
Найдем максимальную абсолютную ошибку:
Максимальная абсолютная ошибка: 2.093656803481281e-9
Результаты моделирования фактически совпадают, а значит наш компонент работает правильно!
Выводы
Язык физического моделирования Engee - это не просто язык написания пользовательских компонентов для 1-d моделирования, но и язык для создания и описания сложных физических систем. При этом была сохранена читаемость кода, что важно для сложных систем!
{"id": "id_2df664c7_831d_45ee_a1a8_4640b4256142", "data": [{"xaxis": "x", "colorbar": {"y": 0.513888888888889, "title": {"text": ""}, "len": 0.9525371828521435, "x": 0.9934383202099737}, "yaxis": "y", "x": [0, 0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009, 0.01, 0.011, 0.012, 0.013, 0.014, 0.015, 0.016, 0.017, 0.018, 0.019, 0.02, 0.021, 0.022, 0.023, 0.024, 0.025, 0.026, 0.027, 0.028, 0.029, 0.03, 0.031, 0.032, 0.033, 0.034, 0.035, 0.036, 0.037, 0.038, 0.039, 0.04, 0.041, 0.042, 0.043, 0.044, 0.045, 0.046, 0.047, 0.048, 0.049, 0.05, 0.051, 0.052, 0.053, 0.054, 0.055, 0.056, 0.057, 0.058, 0.059, 0.06, 0.061, 0.062, 0.063, 0.064, 0.065, 0.066, 0.067, 0.068, 0.069, 0.07, 0.071, 0.072, 0.073, 0.074, 0.075, 0.076, 0.077, 0.078, 0.079, 0.08, 0.081, 0.082, 0.083, 0.084, 0.085, 0.086, 0.087, 0.088, 0.089, 0.09, 0.091, 0.092, 0.093, 0.094, 0.095, 0.096, 0.097, 0.098, 0.099, 0.1, 0.101, 0.102, 0.103, 0.104, 0.105, 0.106, 0.107, 0.108, 0.109, 0.11, 0.111, 0.112, 0.113, 0.114, 0.115, 0.116, 0.117, 0.118, 0.119, 0.12, 0.121, 0.122, 0.123, 0.124, 0.125, 0.126, 0.127, 0.128, 0.129, 0.13, 0.131, 0.132, 0.133, 0.134, 0.135, 0.136, 0.137, 0.138, 0.139, 0.14, 0.141, 0.142, 0.143, 0.144, 0.145, 0.146, 0.147, 0.148, 0.149, 0.15, 0.151, 0.152, 0.153, 0.154, 0.155, 0.156, 0.157, 0.158, 0.159, 0.16, 0.161, 0.162, 0.163, 0.164, 0.165, 0.166, 0.167, 0.168, 0.169, 0.17, 0.171, 0.172, 0.173, 0.174, 0.175, 0.176, 0.177, 0.178, 0.179, 0.18, 0.181, 0.182, 0.183, 0.184, 0.185, 0.186, 0.187, 0.188, 0.189, 0.19, 0.191, 0.192, 0.193, 0.194, 0.195, 0.196, 0.197, 0.198, 0.199, 0.2], "showlegend": true, "mode": "lines", "name": "Пользовательский компонент", "legendgroup": "Пользовательский компонент", "line": {"color": "rgba(0, 154, 250, 1.000)", "shape": "linear", "dash": "solid", "width": 1}, "y": [0, 2192.2557620091607, 4141.014309487773, 5867.2376389968385, 7396.337786984283, 8750.8249049635, 9950.638635402493, 11013.441646698484, 11954.87964841778, 12788.81171453079, 13527.51430527121, 14181.861991060567, 14761.487538967123, 15274.923718359567, 15729.728913301713, 16132.598390850313, 16489.46286325574, 16805.575795017474, 17085.590740056497, 17333.629847499007, 17553.34454455667, 17747.969289827357, 17920.369188327175, 18073.082169204346, 18208.356347039313, 18328.183116733882, 18434.32646918452, 18528.348959302566, 18611.63470865841, 18685.40978137821, 18750.76023324915, 18808.648099737075, 18859.925558279298, 18905.347473337955, 18945.582508892596, 18981.222971959647, 19012.79353204797, 19040.758944910747, 19065.530894296422, 19087.47405241741, 19106.911448353734, 19124.129223420776, 19139.380843505453, 19152.890830382497, 19164.85806693864, 19175.45872496253, 19184.848858600497, 19193.166701657115, 19200.53470255904, 19207.06132694009, 19212.84265438266, 19217.963792822207, 19222.50013143606, 19226.518450460706, 19230.077904275386, 19233.23089222414, 19236.023829995655, 19238.497832916786, 19240.689321218528, 19242.6305561846, 19244.35011507549, 19245.873311819232, 19247.222569662354, 19248.417751266195, 19249.47645110886, 19250.414254496394, 19251.244966997012, 19251.980817675154, 19252.632639117717, 19253.210026902525, 19253.721480856406, 19254.17453018276, 19254.57584430021, 19254.931331024247, 19255.2462235373, 19255.525157427288, 19255.77223892897, 19255.991105372446, 19256.18497872904, 19256.356713042416, 19256.50883644354, 19256.643588367686, 19256.762952521603, 19256.868686085916, 19256.96234558295, 19257.04530979062, 19257.118800039563, 19257.183898192627, 19257.241562571162, 19257.292642062584, 19257.337888617047, 19257.377968316985, 19257.413471182765, 19257.444919858226, 19257.472777304898, 19257.49745361712, 19257.51931205918, 19257.538674413066, 19257.55582571543, 19257.57101845346, 19257.58447628229, 17098.24592142444, 15185.702929660854, 13491.559581146514, 11990.876094461168, 10661.560644747346, 9484.044146081145, 8440.992171525682, 7517.049769991248, 6698.615423306817, 5973.640815885027, 5331.453469354916, 4762.599631135661, 4258.705104086446, 3812.3519684813646, 3416.9693815118717, 3066.736846757137, 2756.498529635218, 2481.6873574577407, 2238.257786751678, 2022.6262481042309, 1831.6183918088643, 1662.4223577064456, 1512.547381298571, 1379.7871267664523, 1262.1872071143177, 1158.01641329567, 1065.74122878094, 984.003254391966, 911.5992110692911, 847.463226190041, 790.6511426700664, 740.3266198618935, 695.7488216373345, 656.2615104088839, 621.283386541081, 590.2995309366053, 562.8538248219131, 538.5422351427634, 517.0068667227495, 497.93069362562346, 481.03289216088064, 466.0647068289424, 452.8057883478203, 441.0609498526729, 430.65729351573293, 421.4416652870544, 413.2784002868775, 406.04732565913184, 399.64199148574954, 393.9681037187401, 388.94213606096895, 384.49010036089567, 380.5464574199967, 377.0531521787501, 373.9587590779031, 371.217725013795, 368.78969874314004, 366.6389368652845, 364.7337776373365, 363.0461748760942, 361.5512850852733, 360.2271017300294, 359.0541312749022, 358.015106216061, 357.09473088334516, 356.2794562700326, 355.55728057552244, 354.91757252473167, 354.3509148632261, 353.84896572416903, 353.4043358262322, 353.0104796946924, 352.6615993043453, 352.35255872576636, 352.07880851838485, 351.83631875737893, 351.62151970843564, 351.4312492770781, 351.2627064589072, 351.1134101055315, 350.98116239914424, 350.86401649805987, 350.76024787691955, 350.6683289396478, 350.58690653144436, 350.5147820187553, 350.4508936439774, 350.3943008951384, 350.3441706604547, 350.29976496394806, 350.2604301015697, 350.22558701791104, 350.19472278182553, 350.1673830354793, 350.14316530567066, 350.12171307894954, 350.10271055332447, 350.08587798928147, 350.0709675916941, 350.05775986198324], "type": "scatter"}, {"xaxis": "x", "colorbar": {"y": 0.513888888888889, "title": {"text": ""}, "len": 0.9525371828521435, "x": 0.9934383202099737}, "yaxis": "y", "x": [0, 0.001, 0.002, 0.003, 0.004, 0.005, 0.006, 0.007, 0.008, 0.009, 0.01, 0.011, 0.012, 0.013, 0.014, 0.015, 0.016, 0.017, 0.018, 0.019, 0.02, 0.021, 0.022, 0.023, 0.024, 0.025, 0.026, 0.027, 0.028, 0.029, 0.03, 0.031, 0.032, 0.033, 0.034, 0.035, 0.036, 0.037, 0.038, 0.039, 0.04, 0.041, 0.042, 0.043, 0.044, 0.045, 0.046, 0.047, 0.048, 0.049, 0.05, 0.051, 0.052, 0.053, 0.054, 0.055, 0.056, 0.057, 0.058, 0.059, 0.06, 0.061, 0.062, 0.063, 0.064, 0.065, 0.066, 0.067, 0.068, 0.069, 0.07, 0.071, 0.072, 0.073, 0.074, 0.075, 0.076, 0.077, 0.078, 0.079, 0.08, 0.081, 0.082, 0.083, 0.084, 0.085, 0.086, 0.087, 0.088, 0.089, 0.09, 0.091, 0.092, 0.093, 0.094, 0.095, 0.096, 0.097, 0.098, 0.099, 0.1, 0.101, 0.102, 0.103, 0.104, 0.105, 0.106, 0.107, 0.108, 0.109, 0.11, 0.111, 0.112, 0.113, 0.114, 0.115, 0.116, 0.117, 0.118, 0.119, 0.12, 0.121, 0.122, 0.123, 0.124, 0.125, 0.126, 0.127, 0.128, 0.129, 0.13, 0.131, 0.132, 0.133, 0.134, 0.135, 0.136, 0.137, 0.138, 0.139, 0.14, 0.141, 0.142, 0.143, 0.144, 0.145, 0.146, 0.147, 0.148, 0.149, 0.15, 0.151, 0.152, 0.153, 0.154, 0.155, 0.156, 0.157, 0.158, 0.159, 0.16, 0.161, 0.162, 0.163, 0.164, 0.165, 0.166, 0.167, 0.168, 0.169, 0.17, 0.171, 0.172, 0.173, 0.174, 0.175, 0.176, 0.177, 0.178, 0.179, 0.18, 0.181, 0.182, 0.183, 0.184, 0.185, 0.186, 0.187, 0.188, 0.189, 0.19, 0.191, 0.192, 0.193, 0.194, 0.195, 0.196, 0.197, 0.198, 0.199, 0.2], "showlegend": true, "mode": "lines", "name": "Библиотека блоков", "legendgroup": "Библиотека блоков", "line": {"color": "rgba(227, 111, 71, 1.000)", "shape": "linear", "dash": "solid", "width": 1}, "y": [0, 2192.255762009718, 4141.014309488829, 5867.237638998264, 7396.337786985973, 8750.824904965382, 9950.63863540452, 11013.441646700616, 11954.879648419916, 12788.811714532903, 13527.514305273276, 14181.861991062551, 14761.487538969015, 15274.923718361391, 15729.728913303474, 16132.598390851977, 16489.462863257282, 16805.57579501893, 17085.59074005787, 17333.629847500335, 17553.344544557942, 17747.96928982852, 17920.369188328237, 18073.082169205347, 18208.356347040284, 18328.18311673469, 18434.326469185362, 18528.34895930328, 18611.634708659058, 18685.4097813788, 18750.76023324973, 18808.64809973767, 18859.925558279778, 18905.347473338334, 18945.582508892847, 18981.22297195995, 19012.79353204832, 19040.75894491114, 19065.530894296855, 19087.474052417845, 19106.911448354123, 19124.129223420954, 19139.380843505463, 19152.890830382363, 19164.85806693856, 19175.458724962496, 19184.848858600522, 19193.16670165713, 19200.534702559078, 19207.061326940126, 19212.842654382708, 19217.963792822266, 19222.50013143613, 19226.51845046078, 19230.077904275466, 19233.230892224212, 19236.023829995735, 19238.497832916863, 19240.6893212186, 19242.630556184668, 19244.35011507556, 19245.873311819305, 19247.222569662412, 19248.417751266254, 19249.476451108923, 19250.414254496463, 19251.24496699707, 19251.98081767521, 19252.63263911777, 19253.21002690256, 19253.721480856442, 19254.174530182794, 19254.575844300238, 19254.931331024272, 19255.246223537324, 19255.525157427306, 19255.772238928985, 19255.99110537246, 19256.184978729052, 19256.35671304243, 19256.50883644355, 19256.64358836769, 19256.76295252161, 19256.868686085923, 19256.962345582953, 19257.04530979062, 19257.11880003956, 19257.183898192627, 19257.241562571162, 19257.292642062584, 19257.337888617043, 19257.37796831698, 19257.41347118276, 19257.444919858222, 19257.472777304894, 19257.49745361712, 19257.51931205918, 19257.538674413066, 19257.55582571543, 19257.571018453462, 19257.584476282293, 17098.245921423826, 15185.702929659765, 13491.55958114506, 11990.876094459447, 10661.560644745445, 9484.044146079124, 8440.992171523596, 7517.049769989154, 6698.615423304738, 5973.640815882975, 5331.453469352921, 4762.599631133739, 4258.705104084604, 3812.35196847961, 3416.9693815102055, 3066.7368467555607, 2756.4985296337427, 2481.687357456356, 2238.2577867503833, 2022.62624810302, 1831.6183918077375, 1662.422357705398, 1512.5473812976024, 1379.7871267655605, 1262.187207113496, 1158.0164132949153, 1065.741228780244, 984.0032543913297, 911.5992110687072, 847.463226189503, 790.6511426695756, 740.3266198614449, 695.7488216369239, 656.2615104085082, 621.2833865407396, 590.299530936294, 562.8538248216307, 538.5422351425063, 517.0068667225146, 497.93069362541024, 481.0328921606862, 466.0647068287662, 452.8057883476611, 441.06094985252804, 430.65729351560253, 421.4416652869362, 413.2784002867703, 406.0473256590355, 399.64199148566337, 393.96810371866115, 388.94213606089795, 384.49010036083007, 380.5464574199391, 377.0531521786979, 373.9587590778552, 371.21772501375324, 368.78969874310235, 366.638936865251, 364.733777637303, 363.0461748760641, 361.551285085248, 360.22710173001, 359.05413127488583, 358.01510621604217, 357.09473088332635, 356.2794562700127, 355.55728057550357, 354.9175725247148, 354.3509148632138, 353.84896572416136, 353.40433582622836, 353.0104796946914, 352.66159930434515, 352.35255872576573, 352.0788085183839, 351.836318757377, 351.62151970843337, 351.43124927707606, 351.26270645890565, 351.11341010553093, 350.98116239914356, 350.86401649805913, 350.7602478769194, 350.6683289396478, 350.58690653144436, 350.51478201875557, 350.4508936439774, 350.39430089513866, 350.3441706604552, 350.29976496394903, 350.2604301015697, 350.2255870179113, 350.1947227818269, 350.16738303548027, 350.1431653056715, 350.121713078951, 350.1027105533261, 350.0858779892831, 350.070967591696, 350.0577598619847], "type": "scatter"}], "config": {"showlegend": true, "xaxis": {"showticklabels": true, "gridwidth": 0.5, "tickvals": [0, 0.05000000000000001, 0.10000000000000002, 0.15000000000000002, 0.20000000000000004], "range": [-0.006000000000000005, 0.20600000000000002], "domain": [0.12508019830854475, 0.9934383202099737], "mirror": false, "tickangle": 0, "showline": true, "ticktext": ["0.00", "0.05", "0.10", "0.15", "0.20"], "zeroline": false, "tickfont": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "zerolinecolor": "rgba(0, 0, 0, 1)", "anchor": "y", "visible": true, "ticks": "inside", "tickmode": "array", "linecolor": "rgba(0, 0, 0, 1)", "showgrid": true, "title": {"text": "", "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}}, "gridcolor": "rgba(0, 0, 0, 0.1)", "tickcolor": "rgb(0, 0, 0)", "type": "linear"}, "paper_bgcolor": "rgba(255, 255, 255, 1.000)", "annotations": [], "height": 400, "margin": {"l": 0, "b": 20, "r": 0, "t": 20}, "plot_bgcolor": "rgba(255, 255, 255, 1.000)", "yaxis": {"showticklabels": true, "gridwidth": 0.5, "tickvals": [0, 5000, 10000, 15000], "range": [-577.7275342884695, 19835.312010570764], "domain": [0.03762029746281716, 0.9901574803149606], "mirror": false, "tickangle": 0, "showline": true, "ticktext": ["0", "5.00×10³", "1.00×10⁴", "1.50×10⁴"], "zeroline": false, "tickfont": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "zerolinecolor": "rgba(0, 0, 0, 1)", "anchor": "x", "visible": true, "ticks": "inside", "tickmode": "array", "linecolor": "rgba(0, 0, 0, 1)", "showgrid": true, "title": {"text": "", "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}}, "gridcolor": "rgba(0, 0, 0, 0.1)", "tickcolor": "rgb(0, 0, 0)", "type": "linear"}, "legend": {"yanchor": "middle", "xanchor": "lower", "bordercolor": "rgba(0, 0, 0, 1)", "bgcolor": "rgba(255, 255, 255, 1.000)", "borderwidth": 1, "tracegroupgap": 0, "y": -0.15, "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "title": {"font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}, "text": ""}, "traceorder": "normal", "x": 0.5}, "width": 1307}}