Совместные вычисления Engee и ЛОГОС
作者
#!/usr/bin/python
# -*- coding: utf-8 -*-
import socket
import struct
from typing import List
# Абстракция для взаимодействия Engee и LOGOS
class EngeeSim:
def __init__(self):
self.sock_comm = None
self.sock_snd = None
self.engee_model_time = 0.0
self.engee_sample_time = 0.0
def __del__(self):
if self.sock_comm:
self.sock_comm.close()
if self.sock_snd:
self.sock_snd.close()
def init_intercommunicate(self):
self.sock_comm = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock_snd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock_snd.settimeout(0.05)
self.sock_comm.connect(("127.0.0.1", 6849))
self.sock_snd.bind(("127.0.0.1", 6848))
self.sock_comm.send(b"INIT")
def cosimulate(self, logos_model_time: float, signals: List[float]):
if logos_model_time <= engee_sim.engee_model_time + engee_sim.engee_sample_time:
return []
try:
recv_data = self.sock_snd.recv(2048)
except socket.timeout:
return []
engee_data = []
for i in range(0, len(recv_data), 8):
chunk = recv_data[i:i+8]
engee_data.append(struct.unpack('d', chunk)[0])
engee_sim.engee_sample_time = engee_data[0]
engee_sim.engee_model_time = engee_data[1]
engee_data = engee_data[2:]
packed_data = b""
for sig in signals:
packed_data += struct.pack("d", sig)
self.sock_comm.send(packed_data)
return engee_data
##################################################################
# Инициализация передачи данных между Engee и LOGOS
engee_sim = EngeeSim()
engee_sim.init_intercommunicate()
##################################################################
""" Cоединитель "функция описания пользовательского критерия разрушения" """
def erosion_user(nsh, nip, ncmr, nhv, Cmr, strainVelF, strain, stress,
pu, eu, epsp, rou, divU, ts, loc, tt, time, eraseFlag):
# Получаем сигналы signals из Engee и отправляем в Engee сигналы из LOGOS
# Первым аргументом обязательна передача модельного времени LOGOS на
# каждом шаге интегратора
signals = engee_sim.cosimulate(time, [pu, eu, rou])
# Если массив сигналов пуст - значит на текущем шаге интегрирования модельное
# время Engee опережает модельное время LOGOS и момент обмена данными
# сдвигается до корректировки модельного времени, а на текущем шаге интегрирования
# LOGOS воспользуется массивом значений по умолчанию
if len(signals) == 0:
return nsh, nip, ncmr, nhv, Cmr, strainVelF, strain, stress, \
pu, eu, epsp, rou, divU, ts, loc, tt, time, eraseFlag
# Воспользуемся сигналами strain и epsp из Engee в качестве критериев разрушения
strain = signals[0]
epsp = signals[1]
# epsp (epsilon plastic) — текущая накопленная пластическая деформация в материале
# strain — критическое значение пластической деформации (предел разрушения)
# eraseFlag — флаг, указывающий на необходимость удаления элемента (эрозии)
if epsp >= strain:
eraseFlag = True
# Возвращаем выходные сигналы расчёта
return nsh, nip, ncmr, nhv, Cmr, strainVelF, strain, stress, \
pu, eu, epsp, rou, divU, ts, loc, tt, time, eraseFlag