iT邦幫忙

2022 iThome 鐵人賽

DAY 16
0
Software Development

或躍在淵的CAE: 讓咱們用Python會一會ANSA + LS-DYNA系列 第 16

[Day16] - Box Drop Project精進計畫(8) - 使用base.ImportV1

  • 分享至 

  • xImage
  •  

今天我們來介紹如何使用base.ImportV1,首先我們來看看手冊是如何描述這個功能。

With ImportV1 the user can import whichever FE format into ANSA in a very fast way.
The API supports creation of Nodes, Shells and Solids (1st and 2nd order), Shell Properties and Solid Properties.

原來是可以快速產生下面七種Entityfunction

  • nodes
  • shells
  • shells2
  • solids
  • solids2
  • pshells
  • psolids

Remarks
It is very important to follow all steps in the correct order while you use this custom import.
start() => create_*() => build() => finish()

使用起來有一定步驟,較不直觀。而且手冊也有說明,所產生的Entities只能在呼叫build與finish中存取...

好像沒有很好用捏...But...

沒錯!就是這個But,生成速度真的非常快,所以我們還是硬著頭皮分享給大家啦!

核心概念

由於base.ImportV1creator function接受的參數格式會是像下面這樣:

ids, xs, ys, zs  = [...], [...], [...], [...]
n1s, n2s, n3s, n4s, n5s, n6s, n7s, n8s  = 
[...], [...], [...], [...], [...], [...], [...], [...]

import_v1.create_nodes(ids, xs, ys, zs)
import_v1.create_shells(ids, types, pids, n1s, n2s, n3s, n4s)
import_v1.create_solids(ids, types, pids, n1s, n2s, n3s, n4s, 
                        n5s, n6s, n7s, n8s)

是將每一項都獨立出來,不像我們之前是把每個座標都先擺好。

此外import_v1creator function不接受lazyiterable(如我們的generator...哭哭),需要先將參數轉換為listtuple

因此我們的code,需要做些變化:

  • 刪除

    • gen_shell_grids
    • gen_solid_grids
    • create_plate_nodes
    • create_box_nodes
    • create_plate_q4shells
    • create_box_h8solids
  • 新增

    • create_plate_nodes_v1
    • create_plate_q4shells_v1
    • create_plate_v1
    • create_box_nodes_v1
    • create_box_h8solids_v1
    • create_box_v1
  • 主程式box_drop.py需配合base.ImportV1的使用步驟。

Plate-Nodes

  • 透過_gen_one_layer_grids得到xyz座標後,分別轉換為list型態的xsyszs
  • 透過get_fit_id_range得到node_start_id, node_end_id後放入range,再轉換為list型態的ids
  • idsxsyszs傳入base.ImportV1.create_nodes ,最後回傳node_start_id, node_end_id
#creators.py
def create_plate_nodes_v1(import_v1,
                          l,
                          w,
                          en1,
                          en2,
                          z_elv=None,
                          move_xy=None,
                          rot_angle=None,
                          deck=None):
    deck = deck or constants.LSDYNA
    x, y, z = _gen_one_layer_grids(l, w, en1, en2,
                                   z_elv=z_elv,
                                   move_xy=move_xy,
                                   rot_angle=rot_angle)
    xs, ys, zs = list(x), list(y), list(z)
    n = len(xs)
    node_start_id, node_end_id = get_fit_id_range(n, LSDYNAType.NODE, deck)
    ids = list(range(node_start_id, node_end_id))
    import_v1.create_nodes(ids, xs, ys, zs)
    return node_start_id, node_end_id

Plate-Shells

  • 透過gen_shell_seqs得到n1sn2sn3sn4s
  • 透過get_fit_id_range得到shell_start_id, shell_end_id後放入range,再轉換為list型態的ids
  • 準備typespids兩個list
  • idstypespidsn1sn2sn3sn4s傳入base.ImportV1.create_shells ,最後回傳shell_start_id, shell_end_id
#creators.py
def create_plate_q4shells_v1(import_v1,
                             en1,
                             en2,
                             node_start_id,
                             pid,
                             deck=None):
    deck = deck or constants.LSDYNA
    n1s, n2s, n3s, n4s = zip(*gen_shell_seqs(en1, en2, start=node_start_id))
    n = len(n1s)
    shell_start_id, shell_end_id = get_fit_id_range(
        n, LSDYNAType.ELEMENT, deck)
    ids = list(range(shell_start_id, shell_end_id))
    types = [import_v1.QUAD]*n
    pids = [pid]*n
    import_v1.create_shells(ids, types, pids, n1s, n2s, n3s, n4s)
    return shell_start_id, shell_end_id

Plate

create_plate_v1內呼叫create_plate_nodes_v1create_plate_q4shells_v1,幫助我們一次建立好plate

#creators.py
def create_plate_v1(import_v1,
                    l,
                    w,
                    en1,
                    en2,
                    pid,
                    z_elv=None,
                    move_xy=None,
                    rot_angle=None,
                    deck=None):
   # nodes
    node_start_id, _ = create_plate_nodes_v1(import_v1,
                                             l,
                                             w,
                                             en1,
                                             en2,
                                             z_elv=z_elv,
                                             move_xy=move_xy,
                                             rot_angle=rot_angle,
                                             deck=deck)
    # shells
    create_plate_q4shells_v1(import_v1,
                             en1,
                             en2,
                             node_start_id,
                             pid=pid,
                             deck=deck)

Box-Nodes

  • 透過_gen_one_layer_grids得到layer_grids後,使用zip得到xyz座標,最後分別轉換為list型態的xsyszs
  • 透過get_fit_id_range得到node_start_id, node_end_id後放入range,再轉換為list型態的ids
  • idsxsyszs傳入base.ImportV1.create_nodes ,最後回傳node_start_id, node_end_id
#creators.py
def create_box_nodes_v1(import_v1,
                        l,
                        w,
                        h,
                        en1,
                        en2,
                        en3,
                        z_elv=None,
                        move_xy=None,
                        rot_angle=None,
                        deck=None):
    deck = deck or constants.LSDYNA
    layer_grids = [_gen_one_layer_grids(l,
                                        w,
                                        en1,
                                        en2,
                                        z_elv=z_elv+i*h/en3,
                                        move_xy=move_xy,
                                        rot_angle=rot_angle)
                   for i in range(en3+1)]
    x, y, z = zip(*layer_grids)
    xs = list(chain.from_iterable(x))
    ys = list(chain.from_iterable(y))
    zs = list(chain.from_iterable(z))
    n = len(xs)
    node_start_id, node_end_id = get_fit_id_range(n, LSDYNAType.NODE, deck)
    ids = list(range(node_start_id, node_end_id))
    import_v1.create_nodes(ids, xs, ys, zs)
    return node_start_id, node_end_id

Box-Solids

  • 透過gen_solid_seqs得到n1s~n4s
  • 透過get_fit_id_range得到solid_start_id, solid_end_id後放入range,再轉換為list型態的ids
  • 準備typespids兩個list
  • idstypespidsn1s~n8s傳入base.ImportV1.create_solids ,最後回傳solid_start_id, solid_end_id
#creators.py
def create_box_h8solids_v1(import_v1,
                           en1,
                           en2,
                           en3,
                           node_start_id,
                           pid,
                           deck=None):
    deck = deck or constants.LSDYNA
    n1s, n2s, n3s, n4s, n5s, n6s, n7s, n8s = zip(
        *gen_solid_seqs(en1, en2, en3, start=node_start_id))
    n = len(n1s)

    solid_start_id, solid_end_id = get_fit_id_range(
        n, LSDYNAType.ELEMENT, deck)
    ids = list(range(solid_start_id, solid_end_id))
    types = [import_v1.HEXA]*n
    pids = [pid]*n
    import_v1.create_solids(ids, types, pids,  n1s, n2s,
                            n3s, n4s, n5s, n6s, n7s, n8s)
    return solid_start_id, solid_end_id

Box

create_box_v1內呼叫create_box_nodes_v1create_box_h8solids_v1,幫助我們一次建立好box

#creators.py
def create_box_v1(import_v1,
                  l,
                  w,
                  h,
                  en1,
                  en2,
                  en3,
                  pid,
                  z_elv=None,
                  move_xy=None,
                  rot_angle=None,
                  deck=None):
    # nodes
    node_start_id, _ = create_box_nodes_v1(import_v1,
                                           l,
                                           w,
                                           h,
                                           en1,
                                           en2,
                                           en3,
                                           z_elv=z_elv,
                                           move_xy=move_xy,
                                           rot_angle=rot_angle,
                                           deck=deck)

    # solids
    create_box_h8solids_v1(import_v1,
                           en1,
                           en2,
                           en3,
                           node_start_id,
                           pid=pid,
                           deck=deck)

主程式

我們分別建立了plate_import_v1box_import_v1來建立platebox。要注意的是,如果要取得所產生的nodesshellssolids,唯一的機會只有在呼叫buildfinish之間。

# box_drop.py
def main():
    deck = constants.LSDYNA
    set_deck_to(deck)

    # plate
    plate_prop = create_sec()
    plate_mat_prop_id = plate_prop._id
    plate_set = create_set(plate_prop, 'plate', deck=deck)

    l_p, w_p, en1_p, en2_p = 100, 100, 10, 10
    z_elv_p, move_xy_p, rot_angle_p = 0, None, None

    plate_import_v1 = base.ImportV1()
    plate_import_v1.start()
    create_plate_v1(plate_import_v1,
                    l_p,
                    w_p,
                    en1_p,
                    en2_p,
                    plate_mat_prop_id,
                    z_elv=z_elv_p,
                    move_xy=move_xy_p,
                    rot_angle=rot_angle_p,
                    deck=deck)
    plate_import_v1.build()
    plate_nodes = plate_import_v1.nodes
    plate_shells = plate_import_v1.shells
    plate_import_v1.finish()

    # box
    box_prop = create_sec(sec_type=SecType.SECTION_SOLID)
    box_mat_prop_id = box_prop._id
    box_set = create_set(box_prop, 'box', deck=deck)

    l_b, w_b, h_b, en1_b, en2_b, en3_b = 50, 50, 50, 10, 10, 10
    z_elv_b, move_xy_b, rot_angle_b = 5, (50, 20), 45

    box_import_v1 = base.ImportV1()
    box_import_v1.start()
    create_box_v1(box_import_v1,
                  l_b,
                  w_b,
                  h_b,
                  en1_b,
                  en2_b,
                  en3_b,
                  box_mat_prop_id,
                  z_elv=z_elv_b,
                  move_xy=move_xy_b,
                  rot_angle=rot_angle_b,
                  deck=deck)
    box_import_v1.build()
    box_nodes = box_import_v1.nodes
    box_solids = box_import_v1.solids
    box_import_v1.finish()

提醒

每天一篇文章,真的是寫昏頭了,現在才發現[Day13]~[Day15]沒有說明主程式的變化。好在這幾天的變動應該很直觀,大家參考當天的box_drop.py,應該很容易了解吧(心虛...)。

Code

本日程式碼傳送門


上一篇
[Day15] - Box Drop Project精進計畫(7) - Housekeeping
下一篇
[Day17] - Box Drop Project精進計畫(9) - 實作Context Manager用以簡化base.ImportV1使用流程
系列文
或躍在淵的CAE: 讓咱們用Python會一會ANSA + LS-DYNA30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言