首页/文章/ 详情

ANSA二次开发-如何创建常驻

4月前浏览920

在回家后继续卷的时候,机缘巧合发现的。

想起以前项目中,花费那么多时间都没解决的问题,答案居然就在帮助文档中躺着,分享一下,虽然不是所需要的效果,但好歹迈出了第一步。

做了二次开发的小伙伴可能清楚,通过BCWindowCreate创建的window窗口会占用当前进程,在点击界面上其他命令的时候,窗口就会被摧毁。例如上述图片,编辑器也会变为灰色。这的确很苦恼,这就得要求在开发命令的时候,涉及到的操作全都得写在界面上,这很麻烦,很麻烦,很麻烦。。。。。怎么就不能像HyperWork一样,所创建的窗口互不干涉。

现在解决办法来了,这是23.1.0帮助文档里写的,监控ABAQUS计算进程的案例,低版本的能否运行,大家自行判断。重点来了,修改create_options_frame函数内的功能就可以实现创建控件,但是当控件所绑定的函数需要修改模型的操作,例如创建点,程序就会闪退。目前还不知道怎么解决。






















































































































































































































































































































































































from __future__ import annotationsimport osimport reimport shleximport subprocessfrom ansa import base, session, guitk, constants, analysis_tools

_RE_FLOAT = r"[-+]?(?:(?:\d*\.?\d+)|(?:\d+\.?\d*))(?:[eE][-+]?\d+)?"

def _show_msg_win_critical(msg):    msg_win = guitk.BCMessageWindowCreate(guitk.constants.BCMessageBoxCritical, msg, False)    guitk.BCMessageWindowSetRejectButtonVisible(msg_win, False)    guitk.BCMessageWindowExecute(msg_win)

def _show_msg_win_information(msg):    msg_win = guitk.BCMessageWindowCreate(guitk.constants.BCMessageBoxInformation, msg, False)    guitk.BCMessageWindowSetRejectButtonVisible(msg_win, False)    guitk.BCMessageWindowExecute(msg_win)

def _show_msg_win_question(msg):    msg_win = guitk.BCMessageWindowCreate(guitk.constants.BCMessageBoxQuestion, msg, False)    return guitk.BCMessageWindowExecute(msg_win) == guitk.constants.BCRetKey

def _get_path_from_line_edit_path(ledit_path):    file_path = guitk.BCLineEditPathLineEditText(ledit_path)    if not file_path:        return ""    return os.path.abspath(file_path)

class AbqTextViewer(analysis_tools.RunSolverTextViewer):    def __init__(self, run_abq: RunAbq, name, is_console=False):        super().__init__(name=name, is_console=is_console, supports_errors=True,            supports_warnings=True, supports_notes=True)        self._run_abq = run_abq

   def get_file_path(self):        dir_name = self._run_abq.get_output_dir_name()        job_name = self._run_abq.get_job_name()        file_path = os.path.join(dir_name, job_name) + "." + self.name.lower()        return file_path

   def has_error_in_line(self, text):        return text.startswith(" ***ERROR") or text.startswith("***ERROR")

   def has_warning_in_line(self, text):        return text.startswith(" ***WARNING") or text.startswith("***WARNING")

   def has_note_in_line(self, text):        return text.startswith(" ***NOTE") or text.startswith("***NOTE")

class AbqTotalIterationsPlotViewer(analysis_tools.RunSolverPlotViewer):    def __init__(self, run_abq: RunAbq):        super().__init__(name="Total Iterations")        self._run_abq = run_abq        self._numbers_pattern = r"^\s*" + 5*(r"\d+\s+") + r"(\d+)\s+" + "("+_RE_FLOAT+")" +\             r"\s+" + _RE_FLOAT + r"\s+" + _RE_FLOAT + r"\s*"

   def get_file_path(self):        return os.path.join(self._run_abq.get_output_dir_name(),            self._run_abq.get_job_name()) + ".sta"

   def set_plot_options(self):        self.set_axis_title(pos="yleft", title="Total Iterations")        self.set_axis_title(pos="xbottom", title="Total Time")
       self.set_curve_name(name="Total Iterations")        self.set_curve_color(r=0, g=0, b=255)

   def file_updated(self, new_text, file_index):        points = []
       for line in new_text.splitlines():            match = re.search(self._numbers_pattern, line)            if match:                total_iters = float(match.group(1))                total_time = float(match.group(2))                points.append((total_time, total_iters))
       if len(points) > 0:            self.append_points_to_curve(points)

class RunAbq(analysis_tools.RunSolver):    def __init__(self):        super().__init__(window_caption="Run Abaqus", query_status_interval=1.0,            initial_actions="Start")        self._out_ledit_path = None        self._exec_ledit_path = None        self._scratch_dir = None        self._data_check_cbox = None        self._cpus_ledit = None        self._mem_size_ledit = None        self._mem_unit_combo = None        self._log_file = None        self._process = None        self._suspend_process = None        self._resume_process = None

   def _get_output_file_path(self):        return _get_path_from_line_edit_path(self._out_ledit_path)

   def get_output_dir_name(self):        return os.path.dirname(self._get_output_file_path())

   def get_job_name(self):        return os.path.splitext(os.path.basename(self._get_output_file_path()))[0]

   def _get_lock_file(self):        dir_name = self.get_output_dir_name()        job_name = self.get_job_name()        file_path = os.path.join(dir_name, job_name) + ".lck"        return file_path

   def _get_exec_file_path(self):        return _get_path_from_line_edit_path(self._exec_ledit_path)

   def _get_log_file_path(self):        return os.path.join(self.get_output_dir_name(), self.get_job_name()) + ".log"

   def _get_mem_size(self):        mem_size = guitk.BCLineEditGetText(self._mem_size_ledit).strip()        if not mem_size:            return ""
       mem_unit = guitk.BCComboBoxCurrentText(self._mem_unit_combo)        return mem_size + mem_unit

   def _get_solver_args(self):        args = []
       args.append(f"job={self.get_job_name()}")        args.append("interactive")
       if guitk.BCCheckBoxIsChecked(self._data_check_cbox):            args.append("datacheck")
       cpus_num = guitk.BCLineEditGetInt(self._cpus_ledit)        if cpus_num != guitk.constants.blank:            args.append(f"cpus={cpus_num}")
       mem_size = self._get_mem_size()        if mem_size:            args.append(f"memory={mem_size}")
       scratch_dir_name = _get_path_from_line_edit_path(self._scratch_dir)        if scratch_dir_name:            args.append(f"scratch={scratch_dir_name}")
       additional_args = guitk.BCLineEditGetText(self._additional_args_ledit).strip()        if additional_args:            for arg in shlex.split(additional_args):                args.append(arg)
       return args

   def _check_user_input(self):        if not os.path.exists(self._get_exec_file_path()):            _show_msg_win_critical("Executable does not exist")            return False
       if not self._get_output_file_path():            _show_msg_win_critical("Output file is empty")            return False
       return True

   def _init(self):        if not self._check_user_input():            return False
       if os.path.exists(self._get_lock_file()):            ret = _show_msg_win_question("Lock file detected. Delete and continue?")            if not ret:                return False            os.remove(self._get_lock_file())
       if base.OutputAbaqus(self._get_output_file_path()) == 0:            _show_msg_win_critical("Output failed")            return False
       self._log_file = open(self._get_log_file_path(), "w")
       return True

   def handle_action(self, action):        if action == "Start":            if not self._init():                return            self.initialize()            self.set_busy()
           args = [self._get_exec_file_path()] + self._get_solver_args()            self._process = subprocess.Popen(args, cwd=self.get_output_dir_name(),                stdout=self._log_file, stderr=subprocess.STDOUT)        elif action == "Terminate":            args = [self._get_exec_file_path(), "terminate", f"job={self.get_job_name()}"]            subprocess.Popen(args, cwd=self.get_output_dir_name(),                stdout=self._log_file, stderr=subprocess.STDOUT)        elif action == "Suspend":            args = [self._get_exec_file_path(), "suspend", f"job={self.get_job_name()}"]            self._suspend_process = subprocess.Popen(args, cwd=self.get_output_dir_name(),                stdout=self._log_file, stderr=subprocess.STDOUT)        elif action == "Resume":            self.set_busy()
           args = [self._get_exec_file_path(), "resume", f"job={self.get_job_name()}"]            self._resume_process = subprocess.Popen(args, cwd=self.get_output_dir_name(),                stdout=self._log_file, stderr=subprocess.STDOUT)        else:            raise Exception("Invalid action:", action)

   def query_status(self):        if self._process is not None:            ret = self._process.poll()            if ret is not None:                self._process = None                if ret == 0:                    return "Completed"                else:                    return "Failed"
       if self._suspend_process is not None:            ret = self._suspend_process.poll()            if ret is not None:                self._suspend_process = None                if ret == 0:                    return "Suspended"                else:                    return "Running"
       if self._resume_process is not None:            ret = self._resume_process.poll()            if ret is not None:                self._resume_process = None                if ret == 0:                    return "Resumed"                else:                    return "Suspended"
       return "Running"

   def status_changed(self, new_status):        if new_status == "Running":            self.show_only_actions(actions=("Terminate", "Suspend"))        elif new_status == "Resumed":            self.show_only_actions(actions=("Terminate", "Suspend"))        elif new_status == "Suspended":            self.set_idle()            self.show_only_actions(actions="Resume")        elif new_status == "Completed":            self.set_idle()            self.show_only_actions(actions="Start")
           self._log_file.close()            _show_msg_win_information("Job was completed")        elif new_status == "Failed":            self.set_idle()            self.show_only_actions(actions="Start")
           self._log_file.close()            _show_msg_win_critical("Job failed")        else:            raise Exception("Invalid new_status:", new_status)

   def create_analysis_top_frame(self, parent):        g_layout = guitk.BCGridLayoutCreate(parent)        guitk.BCGridLayoutSetColStretch(g_layout, 0, 0)        guitk.BCGridLayoutSetColStretch(g_layout, 1, 1)
       label = guitk.BCLabelCreate(g_layout, "Output file")        guitk.BCGridLayoutAddWidget(g_layout, label, 0, 0, guitk.constants.BCAlignAuto)
       self._out_ledit_path = guitk.BCLineEditPathCreate(g_layout, guitk.constants.BCHistoryFiles,            "", guitk.constants.BCHistorySaveAs, "RunAbq_OutputPath")        guitk.BCLineEditPathAddFilter(self._out_ledit_path, "ABAQUS", "inp")        guitk.BCGridLayoutAddWidget(g_layout, self._out_ledit_path, 0, 1, guitk.constants.BCAlignAuto)

   def create_options_frame(self, parent):        g_layout = guitk.BCGridLayoutCreate(parent)        guitk.BCGridLayoutSetColStretch(g_layout, 0, 0)        guitk.BCGridLayoutSetColStretch(g_layout, 1, 1)
       label = guitk.BCLabelCreate(g_layout, "Executable")        guitk.BCGridLayoutAddWidget(g_layout, label, 0, 0, guitk.constants.BCAlignAuto)        self._exec_ledit_path = guitk.BCLineEditPathCreate(g_layout, guitk.constants.BCHistoryFiles,            "", guitk.constants.BCHistorySelect, "RunAbq_Executable")        guitk.BCGridLayoutAddWidget(g_layout, self._exec_ledit_path, 0, 1, guitk.constants.BCAlignAuto)
       label = guitk.BCLabelCreate(g_layout, "Scratch directory")        guitk.BCGridLayoutAddWidget(g_layout, label, 1, 0, guitk.constants.BCAlignAuto)        self._scratch_dir = guitk.BCLineEditPathCreate(g_layout, guitk.constants.BCHistoryFiles,            "", guitk.constants.BCHistorySelect, "RunAbq_ScratchDirectory")        guitk.BCGridLayoutAddWidget(g_layout, self._scratch_dir, 1, 1, guitk.constants.BCAlignAuto)
       self._data_check_cbox = guitk.BCCheckBoxCreate(g_layout, "Data check")        guitk.BCGridLayoutAddMultiCellWidget(g_layout, self._data_check_cbox, 2, 2, 0, 1,            guitk.constants.BCAlignAuto)
       label = guitk.BCLabelCreate(g_layout, "Number of CPUs")        guitk.BCGridLayoutAddWidget(g_layout, label, 3, 0, guitk.constants.BCAlignAuto)        self._cpus_ledit = guitk.BCLineEditCreateInt(g_layout)        guitk.BCGridLayoutAddWidget(g_layout, self._cpus_ledit, 3, 1, guitk.constants.BCAlignAuto)
       label = guitk.BCLabelCreate(g_layout, "Memory size")        guitk.BCGridLayoutAddWidget(g_layout, label, 4, 0, guitk.constants.BCAlignAuto)        frame = guitk.BCFrameCreate(g_layout)        h_layout = guitk.BCBoxLayoutCreate(frame, guitk.constants.BCHorizontal)        guitk.BCBoxLayoutSetMargin(h_layout, 0)        guitk.BCBoxLayoutSetSpacing(h_layout, 0)        self._mem_size_ledit = guitk.BCLineEditCreateInt(h_layout)        guitk.BCBoxLayoutSetStretchFactor(h_layout, self._mem_size_ledit, 1)        self._mem_unit_combo = guitk.BCComboBoxCreate(h_layout, ("MB", "GB", "%"))        guitk.BCBoxLayoutSetStretchFactor(h_layout, self._mem_unit_combo, 0)        guitk.BCGridLayoutAddWidget(g_layout, frame, 4, 1, guitk.constants.BCAlignAuto)
       label = guitk.BCLabelCreate(g_layout, "Additional arguments")        guitk.BCGridLayoutAddWidget(g_layout, label, 5, 0, guitk.constants.BCAlignAuto)        self._additional_args_ledit = guitk.BCLineEditCreate(g_layout, "")        guitk.BCGridLayoutAddWidget(g_layout, self._additional_args_ledit, 5, 1,            guitk.constants.BCAlignAuto)
       guitk.BCSpacerCreate(parent)

@session.defbutton("Run Abaqus", "Run Abaqus")def create_run_abq_win():    run_abq = RunAbq()
   run_abq.add_viewer(AbqTextViewer(run_abq, name="LOG", is_console=True))    run_abq.add_viewer(AbqTextViewer(run_abq, name="DAT"))    run_abq.add_viewer(AbqTextViewer(run_abq, name="MSG"))    run_abq.add_viewer(AbqTextViewer(run_abq, name="STA"))    run_abq.add_viewer_group(group="Plots")    run_abq.add_viewer(AbqTotalIterationsPlotViewer(run_abq), group="Plots")
   run_abq.add_action(action="Start", icon="run_small.svg")    run_abq.add_action(action="Resume", icon="run_small.svg")    run_abq.add_action_group(group="Stop", icon="rect_red_small.svg")    run_abq.add_action(action="Terminate", icon="rect_red_small.svg", group="Stop")    run_abq.add_action(action="Suspend", icon="media_pause.svg", group="Stop")
   run_abq.create_window()create_run_abq_win ()


来源:TodayCAEer
ACTAbaqus二次开发ANSAUM
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2024-08-14
最近编辑:4月前
TodayCAEer
本科 签名征集中
获赞 22粉丝 40文章 257课程 0
点赞
收藏
作者推荐

code分享

procCreateImageFile{args}{setpython_script{fromPILimportImage,ImageSequenceimg=Image.open(r"C:\Users\jintian\Downloads\5.gif")black_pixels=[]forframeinImageSequence.Iterator(img):frame=frame.resize((300,300))frame=frame.convert('1')black_pixels_frame=[y*frame.width+x+1foryinrange(frame.height)forxinrange(frame.width)ifframe.getpixel((x,y))==0]black_pixels.append(black_pixels_frame)#Openthefilewithopen(r"C:\Users\jintian\Downloads\5.txt",'w')asf:forblack_pixels_frameinblack_pixels:positions_str=[str(id)foridinblack_pixels_frame]line=''.join(positions_str)f.write(line+'\n')print(r"C:\Users\jintian\Downloads\5.txt")}cd"D:/Users/jintian/anaconda3"setresult[execpython<<$python_script]return$result}#CreateImageFilesetImageInfoPath[CreateImageFile]for{seti0}{$i<10}{incri}{setf[open$ImageInfoPath]while{1}{setline[gets$f]if{[eof$f]}{close$fbreak}*createmarkelem1{*}$linehm_highlightmarkElements1high;*window00000after10}}来源:TodayCAEer

未登录
还没有评论
课程
培训
服务
行家
VIP会员 学习计划 福利任务
下载APP
联系我们
帮助与反馈