Kratos Structure: Node and Nodal Data
One of the most basic classes is the Node. In this section, we will briefly present its implementation, which will will allow us to present some basic concepts in Kratos.
The Node class centralizes the information related to a single point in the finite element mesh. In its core, the node class contains an index (Id) that uniquely identifies the node in the finite element mesh, and the geometrical information about the position of the node, which is stored as a Point instance. This basic structure is common to all nodes used in Kartos, and can be accessed and modified from Python using the following interface
node.Id # Unique identifier for the node. An unsigned integer value, starting from 1 node.X # X coordinate of the current position of the node node.Y # Y coordinate node.Z # Z coordinate
In addition, the original position of the node is also stored, which is useful in Lagrangian or ALE (Arbitrary Lagrangian-Eulerian) formulations:
node.X0 # Original X coordinate node.Y0 # Original Y coordinate node.Z0 # Original Z coordinate
The node class is also responsible for managing the information related to that point of the mesh and, in particular, of the values of the problem data and unknowns at that point of the mesh. In Kratos, all such data is associated to a Variable, which typically identifies a phyisical magnitude such as velocity or temperature. For example, a node in a fluid problem could be required to store the following data:
Node 735 Velocity: An unknown of the problem, 3D vector. Pressure: An unknown of the problem, scalar. Density: Problem data, given as input, scalar. Viscosity: Problem data, given as input, scalar. Body force: Problem data (for example, acceleration of gravity), given as input, 3D vector.
In Kratos, all variables are identified by a label, typically their name in uppercase (VELOCITY,PRESSURE). In the case of vectors, individual components can be also recovered explicitly so, for example, instead of asking for VELOCITY, we can inquire a node about VELOCITY_X, VELOCITY_Y or VELOCITY_Z. Variable names are hardcoded in Kratos, so adding new ones requires modifying the source. There is a main set of variables that is defined in the Kratos core files (see kratos/includes/variables.h and kratos/sources/variables.cpp) while each application can define its own set of variables. On a given Kratos model, all variables included in the Kratos Kernel and each of the individual applications imported will be available for use.
Types of Nodal Data
There are two different containers for information that can be stored in nodes: the historical database and the non-historical database. Both can be used to store As the name suggests, the difference between the two is that the first one stores both the current value and the values that the variable held during the previous time steps, while the second stores only the current value.
Note that there is no restriction to storing variables in either container, so both containers can store values for the same variable at the same time. While this can be useful in some cases, it should be noted that the values stored in each container are completely independent and no attempt will be made to synchronize them.
Historical database: Solution step data
The historical database is typically used to store values that we want to track as the simulation advances. A typical example of this is a dynamic problem where, to advance in time, we use a time scheme that approximates time derivatives using the values of our unknowns at previous time steps. To access the historical database of a node, we will use the C function
Value& node.FastGetSolutionStepValue(VARIABLE,StepIndex = 0)
or its Python interface
Value = node.GetSolutionStepValue(VARIABLE,StepIndex) node.SetSolutionStepValue(VARIABLE,StepIndex,Value)
where VARIABLE is the Kratos Variable we want to access, Value is the value stored in the node for VARIABLE and StepIndex indicates the time step we are interested in, with 0 being the current time step, 1 the previous time step and so on. The maximum number of time steps stored at the same time for a given simulation is regulated by the ModelPart's buffer size parameter, that will be described in a later section.