How to use the GidIO
This is a tutotial on how to use the Kratos GiD interface (GidIO).
The HowTo describes the measures to be taken in order to read input from input files using the GidIO interface and how to write results that can be post-processed in GiD.
Generating an instance of GidIO
The GidIO interface can only be used, if an instance of the GidIO class has been created. This GidIO instance knows the path of the current problem.gid directory and automatically opens the respective input and output files in the problem.gid directory.
For the instantiation of the GidIO interface there are two Constructors available:
- GidIO( NodeDatafilename, PropertiesDatafilename, ElementDatafilename, ConditionDatafilename, InitialValueDatafilename, ResultFilename, GiD_PostMode, MeshGroupsFlag, WriteDeformedMeshFlag, WriteConditionsFlag ) where the names of each input file and the output file may be given separately, and
- GidIO( Filename, GiD_PostMode, MeshGroupsFlag, WriteDeformedMeshFlag, WriteConditionsFlag ), where the file names are determined automatically according to the given problem name
The following flags have to be specified in the constructor of the GiDIO instance: GiD_PostMode determines whether the output should be written in plain text (GiD_PostASCII) or binary (Gid_PostBinary) file format. The ASCII format is only recommended for debugging, where the user needs to manually access and read the output data. In general, the binary format should be preferred as it yields much smaller output files and can be read and written much faster.
MeshGroupsFlag states whether GidIO should use mesh groups or not. If the flag is set to UseMeshGroups, the meshes are put into groups and labelled with a certain name. Each set of results lateron refers to a specific mesh group. If instead the flag is set to UseNoMeshGroups, the meshes are not labelled. In this case, only one mesh for all results is written. If more than one mesh is needed (be it one mesh for each time step or several meshes for the complete simulation), the MeshGroupsFlag has to be UseMeshGroups.
WriteDeformedMeshFlag specifies whether the meshes are written in deformed or undeformed configuration. WriteDeformedMesh will cause the meshes to be written in deformed state and WriteUndeformedMesh causes the meshes to be written in their original configuration respectively.
WriteConditionsFlag is used to switch between the option to write only the elements of each mesh (option WriteElementsOnly) or to write additionally the Condition objects in the current model part (option WriteConditions)
In the Python script of the problem to be solved with Kratos, the GidIO instance can be, for example, initialised by the following command:
gid_io = GidIO("problem_name",GiDPostMode.GiD_PostBinary, MeshGroupsFlag.UseMeshGroups, \ ...WriteDeformedMeshFlag.WriteUndeformed, WriteConditionsFlag.WriteElementsOnly )
the resulting Python object can then be used to read the input and write the output of the current problem.
Once a ModelPart object has been created, the actual content of the model can be read from the input files by means of the GidIO. The following command creates a ModelPart object and reads all the input files and automatically creates the respective model data:
model_part = ModelPart("Name") gid_io.ReadModelPart(model_part)
After this, the ModelPart is ready to use.
Writing output that can be post-processed by GiD is written by means of the gidpost library. The GidIO interface provides several functions that allow for a convenient usage of this library in order to easily generate suitable output files. The following sections describe the different features available in the GidIO interface.
GidIO provides two functions for writing a mesh (with mesh being an instance of Kratos::Mesh):
- WriteNodeMesh( mesh ) writes only the nodes
- WriteMesh( mesh ) writes elements of the given mesh
In order to initialize and finalize the mesh writing process, the finctions WriteNodeMesh and WriteMesh have to be encapsulated in calls to InitializeMesh( name ) and FinalizeMesh(). Usually, if one mesh should be written for each time step (or solution step), it is recommended to give the current time as name parameter (here AND for the InitializeResults function). However, if only one mesh shall be written (in combination with the UseMeshGroups flag), one should provide an artificial (usually: initial) "time" value as name and refer to this as well for the InitializeResults function. See an example for this below:
#mesh is written for each time step: gid_io.InitializeMesh( time ) gid_io.WriteNodeMesh( model_part.GetMesh() ) gid_io.WriteMesh( model_part.GetMesh() ) gid_io.FinalizeMesh()
#mesh is written only once gid_io.InitializeMesh( 0.0 ) gid_io.WriteNodeMesh( model_part.GetMesh() ) gid_io.WriteMesh( model_part.GetMesh() ) gid_io.FinalizeMesh()
A set of results has to be initialized and finalized each time a new mesh is used. Here, three cases can be distinguished:
Case 1: one mesh serves all time steps. In this case, the mesh has to be written only once for the complete simulation. In this case, this mesh has to be assigned a suitable "name" number (e.g. 0.0). The results are then initialized to this mesh group name and finalized at the very end of the simulation:
gid_io.InitializeMesh( 0.0 ) gid_io.WriteMesh( model_part.GetMesh() ) gid_io.FinalizeMesh() gid_io.InitializeResults( 0.0, model_part.GetMesh() ) #do some calculations... for step in range( start, end ): gid_io.WriteNodalResults( DISPLACEMENT, model_part.Nodes, time, 0 ) gid_io.PrintOnGaussPoints( PK2_STRESS_TENSOR, model_part, time) #at the end: finalize results gid_io.FinalizeResults()
Case 2: each time step has its own mesh. In this case, the mesh has to be written once for each time step. The mesh should then be named with the current time information. The results are initialized and finalized at each time step, respectively
#do some calculations... for step in range( start, end ): gid_io.InitializeMesh( time ) gid_io.WriteMesh( model_part.GetMesh() ) gid_io.FinalizeMesh() gid_io.InitializeResults( time, model_part.GetMesh() ) gid_io.WriteNodalResults( DISPLACEMENT, model_part.Nodes, time, 0 ) gid_io.PrintOnGaussPoints( PK2_STRESS_TENSOR, model_part, time) gid_io.FinalizeResults() #at the end: do nothing
Case 3: the flexible one. This case is a mixture of cases 1 and 2, where a subset of results share one mesh each, but several meshes are available. In this case, the initialization and finalization have to be carried out as in the following example:
for step in range( global_start, global_end ): gid_io.InitializeMesh( time ) gid_io.WriteMesh( model_part.GetMesh() ) gid_io.FinalizeMesh() gid_io.InitializeResults( time, model_part.GetMesh() ) for inner_step in range( start, end ): #now do some calculations on the unchanged mesh gid_io.WriteNodalResults( DISPLACEMENT, model_part.Nodes, time, 0 ) gid_io.PrintOnGaussPoints( PK2_STRESS_TENSOR, model_part, time) gid_io.FinalizeResults() #do some remeshing... #end
Writing nodal results
Nodal results are written by WriteNodalResults( variable, nodes, time, solution_step_index). Here, variable is a Kratos variable (e.g. DISPLACEMENT) that may be of types double, array_1d<double,3>, Vector or Matrix. nodes is the list of nodes the results shall be printed on, usually obtained from ModelPart.Nodes. time is the current solution step, whereas solution_step_index is the variables buffer index (0 for the current solution step, 1 for the previous one, etc.).
Writing results on integration points
Results on integration points are written by PrintOnGaussPoints( variable, model_part, time ), where variable is once again the Kratos variable like in WriteNodalResults. model_part is the current ModelPart instance. time denotes the current solution step.
Writing results must be enclosed by InitializeResults( time, mesh ) and FinalizeResults(). See an example code below:
gid_io.InitializeResults( time, model_part.GetMesh() ) gid_io.WriteNodalResults( DISPLACEMENT, model_part.Nodes, time, 0 ) gid_io.PrintOnGaussPoints( PK2_STRESS_TENSOR, model_part, time) gid_io.FinalizeResults()