Introduction
VariableExpressionIO
is used to read Kratos::Variable
from a container to an expression vice versa. The expression will only read or write to the entities (i.e. nodes/conditions/elements) in the local mesh. If writing an expression to a variable in a container during an MPI run, synchronization between ranks is automatically done.
Variable types
The following Kratos variable types are supported:
Kratos::Variable<int>
Kratos::Variable<double>
Kratos::Variable<array_1d<double, 3>>
Kratos::Variable<array_1d<double, 4>>
Kratos::Variable<array_1d<double, 6>>
Kratos::Variable<array_1d<double, 9>>
Kratos::Variable<Vector>
Kratos::Variable<Matrix>
Shape of the resulting expression
If the data type has static size (such as Kratos::Variable<double>
, Kratos::Variable<array_1d<double, 3>>
), the result’s shape is the number of local entities, followed by the static size of the type. However, if the data type has dynamic size (such as Kratos::Variable<Vector>
, Kratos::Variable<Matrix>
), then all entries in the container are assumed to have the same shape as the first entry. [In MPI runs, the first entry’s shape is synchronized across all ranks to determine the final shape of the expression].
Reading/Writing nodal values
import KratosMultiphysics as Kratos
model = Kratos.Model()
model_part = model.CreateModelPart("test")
model_part.AddNodalSolutionStepVariable(Kratos.ACCELERATION)
node_1 = model_part.CreateNewNode(1, 0.0, 0.0, 0.0)
node_2 = model_part.CreateNewNode(2, 0.0, 1.0, 0.0)
node_1.SetValue(Kratos.VELOCITY, Kratos.Array3([1,2,3]))
node_2.SetValue(Kratos.VELOCITY, Kratos.Array3([3,4,5]))
# now create the expression:
nodal_expression = Kratos.Expression.NodalExpression(model_part)
# now read the VELOCITY from the non-historical container
Kratos.Expression.VariableExpressionIO.Read(nodal_expression, Kratos.VELOCITY, False)
# do some arithmetic operations
nodal_expression *= 2.0
# now write the expression value to model part as ACCELERATION in the historical container
Kratos.Expression.VariableExpressionIO.Write(nodal_expression, Kratos.ACCELERATION, True)
# now print and see
for node in model_part.Nodes:
velocity = node.GetValue(Kratos.VELOCITY)
acceleration = node.GetSolutionStepValue(Kratos.ACCELERATION)
print(f"node_id: {node.Id}, velocity: [{velocity[0]},{velocity[1]},{velocity[2]}], acceleration: [{acceleration[0]},{acceleration[1]},{acceleration[2]}]")
Expected output:
| / |
' / __| _` | __| _ \ __|
. \ | ( | | ( |\__ \
_|\_\_| \__,_|\__|\___/ ____/
Multi-Physics 9.4."3"-docs/expression_documentation-156476ea1c-Release-x86_64
Compiled for GNU/Linux and Python3.11 with GCC-13.2
Compiled with threading and MPI support.
Maximum number of threads: 30.
Running without MPI.
node_id: 1, velocity: [1.0,2.0,3.0], acceleration: [2.0,4.0,6.0]
node_id: 2, velocity: [3.0,4.0,5.0], acceleration: [6.0,8.0,10.0]
Reading/Writing condition values
import KratosMultiphysics as Kratos
model = Kratos.Model()
model_part = model.CreateModelPart("test")
model_part.CreateNewNode(1, 0.0, 0.0, 0.0)
model_part.CreateNewNode(2, 0.0, 1.0, 0.0)
prop = model_part.CreateNewProperties(1)
cond1 = model_part.CreateNewCondition("LineCondition2D2N", 1, [1, 2], prop)
cond1.SetValue(Kratos.VELOCITY, Kratos.Array3([1,2,3]))
# now create the expression:
condition_expression = Kratos.Expression.ConditionExpression(model_part)
# now read the VELOCITY from the non-historical container
Kratos.Expression.VariableExpressionIO.Read(condition_expression, Kratos.VELOCITY)
# do some arithmetic operations
condition_expression *= 2.0
# now write the expression value to model part as ACCELERATION in the historical container
Kratos.Expression.VariableExpressionIO.Write(condition_expression, Kratos.ACCELERATION)
# now print and see
for condition in model_part.Conditions:
velocity = condition.GetValue(Kratos.VELOCITY)
acceleration = condition.GetValue(Kratos.ACCELERATION)
print(f"condition_id: {condition.Id}, velocity: [{velocity[0]},{velocity[1]},{velocity[2]}], acceleration: [{acceleration[0]},{acceleration[1]},{acceleration[2]}]")
Expected output:
| / |
' / __| _` | __| _ \ __|
. \ | ( | | ( |\__ \
_|\_\_| \__,_|\__|\___/ ____/
Multi-Physics 9.4."3"-docs/expression_documentation-156476ea1c-Release-x86_64
Compiled for GNU/Linux and Python3.11 with GCC-13.2
Compiled with threading and MPI support.
Maximum number of threads: 30.
Running without MPI.
condition_id: 1, velocity: [1.0,2.0,3.0], acceleration: [2.0,4.0,6.0]
Reading/Writing element values
import KratosMultiphysics as Kratos
model = Kratos.Model()
model_part = model.CreateModelPart("test")
model_part.CreateNewNode(1, 0.0, 0.0, 0.0)
model_part.CreateNewNode(2, 0.0, 1.0, 0.0)
model_part.CreateNewNode(3, 1.0, 1.0, 0.0)
prop = model_part.CreateNewProperties(1)
cond1 = model_part.CreateNewElement("Element2D3N", 1, [1, 2, 3], prop)
cond1.SetValue(Kratos.VELOCITY, Kratos.Array3([1,2,3]))
# now create the expression:
element_expression = Kratos.Expression.ElementExpression(model_part)
# now read the VELOCITY from the non-historical container
Kratos.Expression.VariableExpressionIO.Read(element_expression, Kratos.VELOCITY)
# do some arithmetic operations
element_expression *= 2.0
# now write the expression value to model part as ACCELERATION in the historical container
Kratos.Expression.VariableExpressionIO.Write(element_expression, Kratos.ACCELERATION)
# now print and see
for element in model_part.Elements:
velocity = element.GetValue(Kratos.VELOCITY)
acceleration = element.GetValue(Kratos.ACCELERATION)
print(f"element_id: {element.Id}, velocity: [{velocity[0]},{velocity[1]},{velocity[2]}], acceleration: [{acceleration[0]},{acceleration[1]},{acceleration[2]}]")
Expected output:
| / |
' / __| _` | __| _ \ __|
. \ | ( | | ( |\__ \
_|\_\_| \__,_|\__|\___/ ____/
Multi-Physics 9.4."3"-docs/expression_documentation-156476ea1c-Release-x86_64
Compiled for GNU/Linux and Python3.11 with GCC-13.2
Compiled with threading and MPI support.
Maximum number of threads: 30.
Running without MPI.
element_id: 1, velocity: [1.0,2.0,3.0], acceleration: [2.0,4.0,6.0]
Using expressions without the model parts
The NodalExpression
, ConditionExpression
and ElementExpression
has an expression which can be directly used if required. The advantage of working
with the Expression
directely is, then it is not bound to a model part of a DataValueContainer
. Hence, these expressions can be interchanged if required in
advanced use cases. Following code snippet shows how to use bare Expressions
.
import KratosMultiphysics as Kratos
model = Kratos.Model()
model_part = model.CreateModelPart("test")
node_1 = model_part.CreateNewNode(1, 0.0, 0.0, 0.0)
node_2 = model_part.CreateNewNode(2, 0.0, 1.0, 0.0)
node_1.SetValue(Kratos.VELOCITY, Kratos.Array3([1,2,3]))
node_2.SetValue(Kratos.VELOCITY, Kratos.Array3([3,4,5]))
# now create the expression by reading non historical velocity:
exp = Kratos.Expression.VariableExpressionIO.Input(model_part, Kratos.VELOCITY, Kratos.Globals.DataLocation.NodeNonHistorical).Execute()
# do some arithmetic operations
exp *= 2.0
# now write the expression value to model part as ACCELERATION in the historical container
Kratos.Expression.VariableExpressionIO.Output(model_part, Kratos.ACCELERATION, Kratos.Globals.DataLocation.NodeNonHistorical).Execute(exp)
# now print and see
for node in model_part.Nodes:
velocity = node.GetValue(Kratos.VELOCITY)
acceleration = node.GetValue(Kratos.ACCELERATION)
print(f"node_id: {node.Id}, velocity: [{velocity[0]},{velocity[1]},{velocity[2]}], acceleration: [{acceleration[0]},{acceleration[1]},{acceleration[2]}]")
Expected output:
| / |
' / __| _` | __| _ \ __|
. \ | ( | | ( |\__ \
_|\_\_| \__,_|\__|\___/ ____/
Multi-Physics 9.4."3"-docs/expression_documentation-156476ea1c-Release-x86_64
Compiled for GNU/Linux and Python3.11 with GCC-13.2
Compiled with threading and MPI support.
Maximum number of threads: 30.
Running without MPI.
node_id: 1, velocity: [1.0,2.0,3.0], acceleration: [2.0,4.0,6.0]
node_id: 2, velocity: [3.0,4.0,5.0], acceleration: [6.0,8.0,10.0]