# Operations

Operations are routines written either in Python or C++ (derived from processes) to perform, precisely, general operations on the mesh such as translation or rotations. To do so, the class Operation needs the following parameters:

MyOperation(model_part,group_ids,table_ids,echo_level=0)


Where the arguments are:

#model_part -> model_part to which the operation will be applied
#group_ids -> python array containing the ids of the groups to which the operation should be applied
#table_ids --> python array containing the ids of the tables to be applied
#echo_level -> level of expected echo for the operation: echo_level=0 implies no echo


A model part can contain several meshes that are overlapping. That is, a single element or node can be part of two meshes or more. This way it is possible to have groups(meshes) for the different operations that we have to be performed. By default, mesh 0 is the global mesh that contains all elements and nodes. Therefore , in general , meshes 1-x can be used to create the groups for the operations. The IDs of the meshes that will be affected by the operations will be passed in the Vector group_ids.

On the other hand, the Vector table_ids contains the IDs of the tables that will be used by the operation to perform the desired task (see the Translation Operation below for an example). Tables are also contained inside the modelpart and are used to provide information in the way: {y = f(x)} . The table is formed by rows of pairs x , y(x). Tables make use of linear interpolation to return the value of y but is invisible to the user , therefore only the x value must be passed. Below can be seen a table inside a .mdpa file. The words in capital letters are the name of the variables.

Begin Table 1 TIME TEMPERATURE
0.0  0.0
1.0  0.0
2.0  5.0
End Table


Finally, the usage of echo level will depend on each particular operation.

## Translation operation

TranslationOperation(model_part,group_ids,table_ids)

The Translation Operation is designed to translate the groups(meshes) passed in the argument group_ids as a function of time. The tables whose IDs are passed in table_ids represent the displacement that has to be imposed to the desired nodes.

As an example, let us suppose that we want to create a linear displacement of time in the shape {Displament{X,Y} = 1.0 + 0.5*t ; Displament{Z} = -2*t } but only for the nodes 3,4,5 of our mesh. This implies that we will have to create a new group(mesh) that contains only these nodes. We will also need the tables for the displacement for the three components . The easiest way to create both the needed group and the tables is to do it in the .mdpa file:

Begin ModelPartData
End ModelPartData

Begin Properties 0
End Properties

Begin Nodes
1              0.0              0.0                  0.0
2              0.0              0.0                  1.0
3              0.0              1.0                  1.0
4              1.0		0.0                  0.0
5              1.0              0.0                  1.0
6              1.0              1.0                  1.0
End Nodes

Begin Table 7 TIME TEMPERATURE
0.0  1.0
1.0  1.5
End Table

Begin Table 8 TIME TEMPERATURE
0.0  0.0
1.0  -2.0
End Table
#notice that we have only two tables because displacement_x = displacement_y

Begin Mesh 2
Begin MeshNodes
3
4
5
End MeshNodes
End Mesh


Now the .mdpa contains all the information that we need to create the displacement: the nodes that we want to move and the displacement as a function of time. (Notice that we used a random variable(TEMPERATURE) to describe the displacement; despite not very orthodox, it is written like this in the example to point out that we are only interested in the fact that it is a scalar ).To make use of this information, we will have to first construct the TranslationOperation with the correct arguments. In the script file (.py) the first thing we have to do is to create the vector that contain the groups and the table IDs. Notice that the table's vector must be of size 3 at least since we need the 3 components of the displacement.

group_ids = Vector(1) #we create a vector of size one, no need to create a bigger one since we will have only one group:
table_ids = Vector(3) #this vector will contain the IDs of the tables for the x,y and z displacements respectively


Having created the vectors, we have to fill them with the correct data

group_ids[0] = 2 # recalling the .mdpa file above, mesh number 2 is the one containing the nodes that we want to move.
#table_ids[0] = 7 # displacement in X follows the law described in table 7
#table_ids[1] = 7 # displacement in Y also follows the law described in table 7
#table_ids[2] = 8 # displacement in Z follows the law described in table 8
#notice that the displacment operation needs a vector table_ids of size at least 3 since the first 3 positions will be the displacements in x,y,z.


Now we can call the constructor of the translation operation. (at this stage the translation is NOT performed, we only called the constructor)

example_translation = TranslationOperation(my_model_part,group_ids,table_ids)


And finally, whenever we want to translate the nodes, we simply execute:

translation_operation.ExecuteInitializeSolutionStep()


## Rotation Operation

The rotation operation consists on performing the following operation on the selected nodes (taken from Wikipedia)

• α (or $\varphi$) is the angle between the x-axis and the N-axis.
• β (or θ) is the angle between the z-axis and the Z-axis.
• γ (or ψ) is the angle between the N-axis and the X-axis.

• for α and γ, a valid range could be [−π, π].
• for β, the range is [−π/2, π/2].

And given a reference point :X0,Y0,Z0

$\begin{bmatrix} x' \\ y' \\ z' \\ \end{bmatrix} = \begin{bmatrix} \cos\theta \cos\psi & \cos\phi \sin\psi + \sin\phi \sin\theta \cos\psi & \sin\phi \sin\psi - \cos\phi \sin\theta \cos\psi \\ -\cos\theta \sin\psi & \cos\phi \cos\psi - \sin\phi \sin\theta \sin\psi & \sin\phi \cos\psi + \cos\phi \sin\theta \sin\psi \\ \sin\theta & -\sin\phi \cos\theta & \cos\phi \cos\theta \\ \end{bmatrix} \begin{bmatrix} x - X_0 \\ y - Y_0\\ z - Z_0\\ \end{bmatrix}+ \begin{bmatrix} X_0 \\ Y_0\\ Z_0\\ \end{bmatrix}$

Reading the previous operations, it can be seen that the needed input data are the 3 angles and the 3 coordinates of the reference points. That means we need 6 tables (or less but using tables more than once). Then the commands needed for the RotationOperation are:

group_ids = Vector(1) #we create a vector of size one, no need to create a bigger one since we will have only one group:
table_ids = Vector(8) #this vector will contain the IDs of the tables for the  3 rotations and the x,y and z refernce points respectively


For this example we will use the same .mdpa used in the translation example, but we will add a new table in python for the reference points:

new_table = PiecewiseLinearTable(TIME,TEMPERATURE) #we create the table
new_table.AddRow(0.0,0.0)          #we add a row, for time 0, the variable is 0
new_table.AddRow(1.0,0.0)          #another row, for time 1.0, the variable remains zero


Having created the vectors, we have to fill them with the correct data

group_ids[0] = 2 # recalling the .mdpa file above, mesh number 2 is the one containing the nodes that we want to move.
#table_ids[0] = 7 # rotationA follows the law described in table 7
#table_ids[1] = 7 # rotationB also follows the law described in table 7
#table_ids[2] = 8 # rotationC follows the law described in table 8
#table_ids[3] = 9 # reference point x follows the law described in table 9 (constant 0.0)
#table_ids[4] = 9 # reference point y follows the law described in table 9 (constant 0.0)
#table_ids[5] = 9 # reference point z follows the law described in table 9 (constant 0.0)

#notice that the displacment operation needs a vector table_ids of size at least 6 since the first 3 positions are the rotations and the other 3 are the reference point


Now we can call the constructor of the translation operation. (at this stage the translation is NOT performed, we only called the constructor)

rotation_operation = RotationOperation(my_model_part,meshes_to_translate,xyz_displacements,0)


And finally, whenever we want to execute the rotation:

rotation_operation.ExecuteInitializeSolutionStep()