GiD - The personal pre and post processor

Real example: meshio GiD plugin

This plugin uses the features of the meshio Python module to allow GiD import/export meshes in all formats supported by this module.

The module is written in python, but GiD uses Tcl as main scripting language. The Tohil package is the bridge to allow its use in GiD.

The plugin is placed at

<GiDdirectory>/plugins/Import/meshio

and like the rest of plugins it is automatically loaded from Tcl when GiD starts.

It adds a new “meshio” entry to the Files Import/Export menu.

To import meshes, for example, the Python file gid_meshio.py defines the function my_meshio_read_mesh.

import numpy as np import meshio def my_meshio_read_mesh(filename): #to avoid that numpy truncate the printed representation of its arrays np.set_printoptions(threshold=np.inf) mesh=meshio.read(filename) return [mesh.points,mesh.cells,mesh.cells_dict]

and the Tcl file meshio.tcl calls GiD_Python_Import_File to import this file in the Python interpreter to define the function, and then calls the function to obtain the mesh data from the mesh file regardless of the mesh file format used.

set filename_python [file join [gid_filesystem::get_folder_standard plugins] Import/meshio/gid_meshio.py] GiD_Python_Import_File $filename_python ... set m [GiD_Python_Call gid_meshio.my_meshio_read_mesh $filename_mesh] ...

 

Here GiD_Python_Import_File is an auxiliary proc (see <GiDdirectory>/scripts/gid_python.tcl) that decorates the tohil syntax and basically does the following:

package require tohil
tohil::import $module_name

And GiD_Python_Call is like an alias of the command tohil::call.

The variable m contains the data that defines a collection of meshes (element type, coordinates of nodes and element connectivities), and this data is processed at Tcl level to have the desired final data for GiD_MeshPre_Create.

This is the code of the proc that creates GiD meshes from a file in a format supported by the meshio Python module:

proc MeshIo::Init { } { variable meshio_num_nodes_per_cell variable meshio_gid_element #linear and serendipit set meshio_num_nodes_per_cell(vertex) 1 set meshio_num_nodes_per_cell(line) 2 set meshio_num_nodes_per_cell(triangle) 3 set meshio_num_nodes_per_cell(quad) 4 set meshio_num_nodes_per_cell(quad8) 8 set meshio_num_nodes_per_cell(tetra) 4 set meshio_num_nodes_per_cell(hexahedron) 8 set meshio_num_nodes_per_cell(hexahedron20) 20 set meshio_num_nodes_per_cell(hexahedron24) 24 set meshio_num_nodes_per_cell(wedge) 6 set meshio_num_nodes_per_cell(pyramid) 5 #quadratic set meshio_num_nodes_per_cell(line3) 3 set meshio_num_nodes_per_cell(triangle6) 6 set meshio_num_nodes_per_cell(quad9) 9 set meshio_num_nodes_per_cell(tetra10) 10 set meshio_num_nodes_per_cell(hexahedron27) 27 set meshio_num_nodes_per_cell(wedge15) 15 set meshio_num_nodes_per_cell(wedge18) 18 set meshio_num_nodes_per_cell(pyramid13) 13 set meshio_num_nodes_per_cell(pyramid14) 14 #degree 3 set meshio_num_nodes_per_cell(line4) 4 set meshio_num_nodes_per_cell(triangle10) 10 set meshio_num_nodes_per_cell(quad16) 16 set meshio_num_nodes_per_cell(tetra20) 20 set meshio_num_nodes_per_cell(wedge40) 40 set meshio_num_nodes_per_cell(hexahedron64) 64 #degree 4 set meshio_num_nodes_per_cell(line5) 5 set meshio_num_nodes_per_cell(triangle15) 15 set meshio_num_nodes_per_cell(quad25) 25 set meshio_num_nodes_per_cell(tetra35) 35 set meshio_num_nodes_per_cell(wedge75) 75 set meshio_num_nodes_per_cell(hexahedron125) 125 #degree 5 set meshio_num_nodes_per_cell(line6) 6 set meshio_num_nodes_per_cell(triangle21) 21 set meshio_num_nodes_per_cell(quad36) 36 set meshio_num_nodes_per_cell(tetra56) 56 set meshio_num_nodes_per_cell(wedge126) 126 set meshio_num_nodes_per_cell(hexahedron216) 216 #degree 6 set meshio_num_nodes_per_cell(line7) 7 set meshio_num_nodes_per_cell(triangle28) 28 set meshio_num_nodes_per_cell(quad49) 49 set meshio_num_nodes_per_cell(tetra84) 84 set meshio_num_nodes_per_cell(wedge196) 196 set meshio_num_nodes_per_cell(hexahedron343) 343 #degree 7 set meshio_num_nodes_per_cell(line8) 8 set meshio_num_nodes_per_cell(triangle36) 36 set meshio_num_nodes_per_cell(quad64) 64 set meshio_num_nodes_per_cell(tetra120) 120 set meshio_num_nodes_per_cell(wedge288) 288 set meshio_num_nodes_per_cell(hexahedron512) 512 #degree 8 set meshio_num_nodes_per_cell(line9) 9 set meshio_num_nodes_per_cell(triangle45) 45 set meshio_num_nodes_per_cell(quad81) 81 set meshio_num_nodes_per_cell(tetra165) 165 set meshio_num_nodes_per_cell(wedge405) 405 set meshio_num_nodes_per_cell(hexahedron729) 729 #degree 9 set meshio_num_nodes_per_cell(line10) 10 set meshio_num_nodes_per_cell(triangle55) 55 set meshio_num_nodes_per_cell(quad100) 100 set meshio_num_nodes_per_cell(tetra220) 220 set meshio_num_nodes_per_cell(wedge550) 550 set meshio_num_nodes_per_cell(hexahedron1000) 1000 set meshio_num_nodes_per_cell(hexahedron1331) 1331 #degree 10 set meshio_num_nodes_per_cell(line11) 11 set meshio_num_nodes_per_cell(triangle66) 66 set meshio_num_nodes_per_cell(quad121) 121 set meshio_num_nodes_per_cell(tetra286) 286 #linear and serendipit set meshio_gid_element(vertex) point set meshio_gid_element(line) line set meshio_gid_element(triangle) triangle set meshio_gid_element(quad) quadrilateral set meshio_gid_element(tetra) tetrahedra set meshio_gid_element(hexahedron) hexahedra set meshio_gid_element(wedge) prism set meshio_gid_element(pyramid) pyramid #quadratic set meshio_gid_element(line3) line set meshio_gid_element(triangle6) triangle set meshio_gid_element(quad8) quadrilateral set meshio_gid_element(quad9) quadrilateral set meshio_gid_element(tetra10) tetrahedra set meshio_gid_element(hexahedron20) hexahedra set meshio_gid_element(hexahedron27) hexahedra set meshio_gid_element(wedge15) prism set meshio_gid_element(pyramid13) pyramid ... } proc MeshIo::ReadPreUnstructuredMesh { filename } { set fail 0 variable meshio_gid_element variable meshio_num_nodes_per_cell MeshIo::Import_gid_meshio_py ;#to load in python the file gid_meshio.py to define its python functions before be called set m [GiD_Python_Call gid_meshio.my_meshio_read_mesh $filename] set nodes_coordinates [lindex [MeshIo::PythonArrayToTclList [lindex $m 0]] 0] #e.g.[lindex $m 1] == {<meshio CellBlock, type: triangle, num cells: 156, tags: []>} set meshio_element_types_and_connectivities [MeshIo::PythonArrayToTclList [lindex $m 2]] set layer [GiD_Layers get to_use] set offset_nodes [GiD_Info mesh MaxNumNodes] set offset_elements [GiD_Info mesh MaxNumElements] set last_element_id $offset_elements #better use GiD_MeshPre_Create with same syintax as GiD_MeshPost (and some day could be implemented to be faster in C++) set num_nodes [llength $nodes_coordinates] set node_ids [objarray new_from_to intarray [expr $offset_nodes+1] [expr $offset_nodes+$num_nodes]] set vertices [objarray new doublearray [expr $num_nodes*3]] set i 0 foreach node $nodes_coordinates { foreach value $node { objarray set $vertices $i $value incr i } } foreach {meshio_element_type meshio_connectivities} $meshio_element_types_and_connectivities { set element_type "" set element_num_nodes 0 if { [info exists meshio_gid_element($meshio_element_type)] } { set element_type $meshio_gid_element($meshio_element_type) set element_num_nodes $meshio_num_nodes_per_cell($meshio_element_type) } else { W "element $meshio_element_type not supported" continue } set elements [lindex $meshio_connectivities 0] set num_elements [llength $elements] set element_ids [objarray new_from_to intarray [expr $last_element_id+1] [expr $last_element_id+$num_elements]] set element_vertex_indices [objarray new intarray [expr $num_elements*$element_num_nodes]] set i 0 foreach element $elements { foreach node_id $element { objarray set $element_vertex_indices $i [expr $node_id+$offset_nodes+1] incr i } } set zero_based_array 0 GiD_MeshPre_Create $element_type $element_num_nodes $node_ids $vertices $element_ids $element_vertex_indices $zero_based_array $layer incr last_element_id $num_elements } return $fail }

 

This import plugin is calling Python files and modules, like meshio and numpy, from Tcl code functions.

The export feature is implemented in two alternative ways:

  1. For Tcl-programmers, with most code in Tcl.

  2. For Python-programmers: with most code in Python.

Note that only the second approach is bi-directional and will invoke Tcl commands (of the GiD interpreter) from Python by first importing the tohil module in Python:

  1. Tcl-programmers: Ask GiD for its current mesh data with Tcl, and transforms this data with Tcl code to the format expected by the Python meshio module and then call a Python function that creates a meshio.Mesh and writes it to file with the desired format.

  2. Python-programmes: From Tcl, call some Python code that asks GiD for the mesh information using Tcl commands, and processes this data with Python to create a meshio.Mesh and writes it to file with the desired format.

The implementation of 1. is something like this:

meshio.tcl (big code)

gid_meshio.py (small code)

 

The implementation of 2. is something like this:

meshio.tcl (small code)

gid_meshio.py (big code)

Note that in this case Python uses commands to call Tcl like these:

 

To know the syntax of GiD-Tcl added commands (like GiD_Info or GiD_Mesh) read the GiD Customization Manual: TCL AND TK EXTENSION

 

COPYRIGHT © 2022 · GID · CIMNE