Tcl Extension
=============
Tdyn CFD+HT can be extended by using the Tcl scripting language.
Tcl, or the "Tool Command Language", is a very simple,
open-source-licensed programming language. Tcl provides basic language
features such as variables, procedures, and control, and it runs on almost any
modern OS, such as Unix, MacOS and Windows computers. But the key feature of
Tcl is its extensibility.
You may find further information on Tcl at:
`wiki.tcl-lang.org `_
Tdyn distribution includes a basic installation of Tcl, that allows to efficiently
implement new capabilities in Tdyn. However full Tcl installation provides
many tool-kits and libraries that can help in the implementation of above
mentions Tdyn extensions.
The full Tcl version can be downloaded from:
`www.activestate.com/activetcl/ `_
Finally, you can use Ramdebbuger for editing and debugging
Tcl code. Ramdebugger is free to use and can be downloaded
from:
`https://www.compassis.com/downloads/Ramdebugger/ `_
Initiating Tcl extension
^^^^^^^^^^^^^^^^^^^^^^^^
Tdyn CFD+HTTcl extension is initiated by selecting the *Use Tcl external
script* option available in the **Fluid dynamics data > Other > Tcl data** page.
If the check-box is selected, the Tcl extension of Tdyn CFD+HT is activated.
The entry may indicate a Tcl script to be interpreted during Tdyn CFD+HT execution.
Tdyn Tcl event procedures
^^^^^^^^^^^^^^^^^^^^^^^^^
The Tcl script used for the Tdyn extension can optionally implement some
of these Tcl event procedures (as well as other user-defined procedures).
These procedures (listed below) are automatically called by Tdyn CFD+HT
during execution, when the Tcl interface is activated.
Their syntax corresponds to the standard Tcl language.
* **TdynTcl_InitiateProblem**: This procedure is called at the beginning of the execution,
once all the data structures have been created.
* **TdynTcl_FinishProblem**: This procedure is called at the end of the
execution of the current problem.
* **TdynTcl_StartNewFluidStep**: This procedure is called when a new time step is
started in fluid domain.
* **TdynTcl_StartNewSolidStep**: This procedure is called when a new time step is
started in solid domain.
* **TdynTcl_FinishFluidStep**: This procedure is called when a time step is
finished in fluid domain.
* **TdynTcl_FinishStep**: This procedure is called once the current step is finished.
* **TdynTcl_AssembleFluidMomentumX, TdynTcl_AssembleFluidMomentumY, TdynTcl_AssembleFluidMomentumZ**:
This procedure is invoked once the X/Y/Z
component of the velocity momentum equation in the fluid domain has been
assembled. It allows modifying Navier Stokes equations,
for example by imposing imposing boundary conditions for every component of the velocity vector.
* **TdynTcl_AssembleFluidPressure**: This procedure is invoked once the continuity
equation of the Navier Stokes equations in fluid domain has been assembled.
It allows modifying Navier Stokes equations, for example by imposing
boundary conditions for the pressure.
* **TdynTcl_AssembleSolidPressure**: This procedure is invoked once the continuity
equation of the Navier Stokes equations in solid domain has been assembled.
It allows modifying Navier Stokes equations, for example by imposing boundary
conditions for the pressure.
* **TdynTcl_AssembleFluidODDLSPressure**: This procedure is invoked once the
continuity equation of the Navier Stokes equations for ODD level set solver
has been assembled. It allows modifying Navier Stokes equations, for
example by imposing boundary conditions for the pressure.
* **TdynTcl_AssembleFluidTemperature**: This procedure is invoked once the
temperature equation for the fluid has been assembled. It allows modifying
temperature equation, for example by imposing boundary conditions for the fluid
temperature field.
* **TdynTcl_AssembleSolidTemperature**: This procedure is invoked once the
temperature equation for the solid has been assembled. It allows modifying
temperature equation, for example by imposing boundary conditions for the solid
temperature field.
* **TdynTcl_AssembleFluidSpecies** *index*: This procedure is invoked once
the equation for the fluid species index has been assembled.
The index of the species is sent to the procedure in the argument *index*.
It allows modifying species equation, for example by imposing boundary conditions
for the fluid species concentration field.
* **TdynTcl_AssembleSolidSpecies** *index*: This procedure is invoked once the
equation for the solid species index has been assembled. The index of the
species is sent to the procedure in the argument index. It allows modifying
species equation, for example by imposing boundary conditions for the solid species
concentration field.
* **TdynTcl_AssembleFluidPhiVariable** *index*: This procedure is invoked once the
equation for the fluid phi variable defined by the index has been assembled.
The index of the phi variable is sent to the procedure in the argument index.
It allows modifying variable equation, for example by imposing boundary conditions
for the fluid variable field.
* **TdynTcl_AssembleSolidPhiVariable** *index*: This procedure is invoked once the
equation for the solid phi variable defined by the index has been assembled.
The index of the phi variable is sent to the procedure in the argument index.
It allows modifying variable equation, for example by imposing boundary conditions
for the solid variable field.
* **TdynTcl_CalculateDensityFromPressure**: This procedure is invoked
once the density field has been updated in incompressible or slightly
compressible flows.
* **TdynTcl_CalculatePressureFromDensity**: This procedure is invoked
once the pressure field has been updated in fully compressible flows.
* **TdynTcl_AssembleFluidMeshDeformation**: This procedure is invoked once
the structures required to perform the fluid mesh deformation are ready.
* **TdynTcl_AssembleSolidMeshDeformation**: This procedure is invoked once
the structures required to perform the solid mesh deformation are ready.
* **TdynTcl_FinishFluidMeshDeformation**: This procedure is invoked once the
fluid mesh deformation is done.
* **TdynTcl_FinishSolidMeshDeformation**: This procedure is invoked once the
solid mesh deformation is done.
* **TdynTcl_MoveBody** *name*: This procedure is invoked once the body
movement of body name is evaluated. It allows re-defining body movement.
Managing Tdyn data from the Tcl script
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
From the Tcl procedures defined in the Tdyn CFD+HT extension, it is possible to
access Tdyn CFD+HT internal data. This access is done by means of the following
functions:
.. note::
**Remarks**: Unless otherwise indicated the arguments and returning
values are given in internal units (those defined in the user interface).
The conversion factor to any other units can be obtained calling the procedures
dynTcl_UnitsToInternal or TdynTcl_InternalToUnits.
* **TdynTcl_VecVal** *vec inode*: Returns the value of the variable identified by vec,
corresponding to the node inode. vec must be one of the vector names defined
in the `Function Syntax <./chap9_function_syntax.html>`_ section.
Example: *TdynTcl_VecVal Tm 10*
* **TdynTcl_SetVecVal** *vec inode newvalue*: Set a single value of the vector identified by vec,
corresponding to the node inode, to the value given by newvalue. vec must be one of the vector
names defined in the `Function Syntax <./chap9_function_syntax.html>`_ section.
Example: *TdynTcl_SetVecVal Tm 10 0.0*
* **TdynTcl_DVecVal** *vec inode idim*: Returns the value of the derivative in the
direction given by idim (1 -x-, 2 -y-, 3 -z-) of variable identified by vec,
corresponding to the node inode. vec must be one of the vector names defined in
the `Function Syntax <./chap9_function_syntax.html>`_ section.
Example: *TdynTcl_DVecVal Tm 10 2*
* **TdynTcl_VecVals** *vec node_list*: Returns a list with the values of the
variable identified by vec, corresponding to the nodes in the list given
by node_list. vec must be one of the vector names defined in the `Function Syntax <./chap9_function_syntax.html>`_ section.
Example: *TdynTcl_VecVals Tm [list 10 12 14]*
* **TdynTcl_VecValsAverage** *vec node_list*: Returns the average of the values
of the variable identified by vec, corresponding to the nodes in the list
given by node_list. vec must be one of the vector names defined in the
`Function Syntax <./chap9_function_syntax.html>`_ section.
Example: *TdynTcl_VecValsAverage Tm [list 10 12 14]*
* **TdynTcl_Coord** *inode idim*: Returns the coordinate idim
(1 for x component, 2 for y component and 3 for z component) of the
global node inode. The returning value is given in [m].
Example: *TdynTcl_Coord 10 2*
* **TdynTcl_Coords** *inode idom*: Returns the coordinates of the node (1 for x component,
2 for y component and 3 for z component) of the node inode. The returning
value is given in [m]. The index of the can be global (idom = 0) fluid
(idom = 1) or solid (idom = 2).
Example: *TdynTcl_Coords 10 0*
* **TdynTcl_NNode** *itype*: Returns the number of nodes of the problem.
If itype is 0, returns the total number of nodes, for itype 1
returns the number of fluid nodes and for itype 2 returns the number
of solid nodes.
Example: *TdynTcl_NNode 0*
* **TdynTcl_Dt**: Returns the current time increment. The returning value
is given in [s].
Example: *TdynTcl_Dt*
* **TdynTcl_Time**: Returns the current physical time of the simulation
(output time). The returning value is given in output units.
Example: *TdynTcl_Time*
* **TdynTcl_PTime**: Returns the current physical time of the simulation
(output time). The returning value is given in [s].
Example: *TdynTcl_PTime*
* **TdynTcl_Step**: Returns the current step of the simulation.
Example: *TdynTcl_Step*
* **TdynTcl_Phase** : Returns 0 for during the Initial Phase of the calculation
(if any) and 1 otherwise.
Example: *TdynTcl_Phase
* **TdynTcl_FixSystemRow** *idof val*: Fixes the idof row of the current system
of equations to val.
Example: *TdynTcl_FixSystemRow 10 0.0*
* **TdynTcl_DelSystemRow** *idof*: Sets to 0.0 all the entries of the idof row of the
current system of equations.
Example: *TdynTcl_DelSystemRow 10*
* **TdynTcl_GetSystemValue** *irow icol*: Returns the (irow, icol) position of the
current system.
Example: *TdynTcl_GetSystemValue 10 15*
* **TdynTcl_SetSystemValue** *irow icol val*: Prescribes to val the value of the
(irow, icol) position of the current system.
Example: *TdynTcl_SetSystemValue 10 15 1.0*
* **TdynTcl_GetRhs** *idof*: Returns the idof value of the right hand side
vector of the current system of equations.
Example: *TdynTcl_GetRhs 10*
* **TdynTcl_SetRhs** *idof val*: Sets the idof value of the right hand side vector
of the current system of equations to val.
Example: *TdynTcl_SetRhs 10 0.0*
* **TdynTcl_IsFluid** *inode*: Returns 1 if the index inode corresponds to a fluid
node and 0 otherwise.
Example: *TdynTcl_IsFluid 10*
* **TdynTcl_IsSolid** *idof*: Returns 1 if the index inode corresponds to a solid node
and 0 otherwise.
Example: *TdynTcl_IsSolid 10*
* **TdynTcl_GetFluidBodyNodes** *name*: Returns a list containing the indexes of
the nodes of the FluidBody name.
Example: *TdynTcl_GetFluidBodyNodes fluid_body*
* **TdynTcl_GetFluidBodyElems** *name*: Returns a list containing the connectivities
of the elements of the FluidBody name.
Example: *TdynTcl_GetFluidBodyElems fluid_body*
* **TdynTcl_GetSolidBodyNodes** *name*: Returns a list containing the indexes of
the nodes of the SolidBody name.
Example: *TdynTcl_GetSolidBodyNodes solid_body*
* **TdynTcl_GetSolidBodyElems** *name*: Returns a list containing the connectivities of
the elements the SolidBody name.
Example: *TdynTcl_GetSolidBodyElems solid_body*
* **TdynTcl_GetBodyArea** *name*: Returns the area of the body identified by name.
Example: *TdynTcl_GetBodyArea Fluid_Body*
* **TdynTcl_GetFluidNodes** *name*: Returns a list of the nodes belonging to the
fluid Material identified by name. If no argument is given all nodes are
returned.
Example: *TdynTcl_GetFluidNodes Fluid*
* **TdynTcl_GetSolidNodes** *name*: Returns a list of the nodes belonging
to the solid Material identified by name. If no argument is given all
nodes are returned.
Example: *TdynTcl_GetSolidNodes Solid*
* **TdynTcl_GetFluidElems** *name*: Returns a list containing the connectivities
of the elements of the Fluid Material name.
Example: *TdynTcl_GetFluidElems fluid*
* **TdynTcl_GetSolidElems** *name*: Returns a list containing the connectivities
of the elements of the Solid Material name.
Example: *TdynTcl_GetSolidElems solid*
* **TdynTcl_Message** *message type*: Print the notice or error given by message.
type can be *"error"*, *"warning"* or *"notice"*. Error messages will stop calculation.
Example: *TdynTcl_Message "Tcl script executed correctly" notice*
* **TdynTcl_UnitsConversor** *value in_units out_units magnitude*: Convert the
value of the defined magnitude from the units given by in_units to the units
given by out_units. Units format must follow the criteria defined in
`Units Syntax <./chap5_units_syntax.html>`_ section.
Example: *TdynTcl_UnitsConversor 1.0 "\[m\]" "\[mm\]" Length*
* **TdynTcl_SetGlobalVariable** *variable value*: Set the Tdyn variable to the
given value. Available variables are: Number_of_Steps, Max_Iterations, Total_Time,
OutPut_Start, OutPut_Step, and Gravity_X/Y/Z.
Example: *TdynTcl_SetGlobalVariable OutPut_Start 10*
* **TdynTcl_GetGlobalVariable** *variable*: Returns the value of the given Tdyn
variable. Available variables are: Number_of_Steps, Max_Iterations, Total_Time,
OutPut_Start, OutPut_Step, and Gravity_X/Y/Z.
Example: *TdynTcl_GetGlobalVariable OutPut_Start*
* **TdynTcl_GlobalToFluid** *inode*: Converts the global node index inode
to local index in fluid domain.
Example: *TdynTcl_GlobalToFluid 10*
* **TdynTcl_GlobalToSolid** *inode*: Converts the global node index inode
to local index in solid domain.
Example: *TdynTcl_GlobalToSolid 10*
* **TdynTcl_FluidToGlobal** *inode*: Converts the local node index inode
in fluid domain to global index.
Example: *TdynTcl_FluidToGlobal 15*
* **TdynTcl_SolidToGlobal** *inode*: Converts the local node index inode in
solid domain to global index.
Example: *TdynTcl_SolidToGlobal 15*
* **TdynTcl_SetFluidBodyVariable** *name variable value*: Set the variable of
fluid body name to the given value. Available variables are:
AccelerationX/Y/Z, RAccelerationX/Y/Z, DisplacementX/Y/Z, RotationX/Y/Z.
The value argument must be given in basic units [m],[s],[Kg],[N],[rad].
Example: *TdynTcl_SetFluidBodyVariable fluid_body DisplacementX 0.02*
* **TdynTcl_GetFluidBodyVariable** *name variable*: Returns the value of the
variable of fluid body name. Available variables are: ForceX/Y/Z,
MomentX/Y/Z, AccelerationX/Y/Z, RAccelerationX/Y/Z, DisplacementX/Y/Z, RotationX/Y/Z.
The returning variables are in basic units [m],[s],[Kg],[N],[rad].
Example: *TdynTcl_GetFluidBodyVariable fluid_body RAccelerationY*
* **TdynTcl_SetSolidBodyVariable** *name variable value*: Set the variable of
solid body name to the given value. Available variables are: AccelerationX/Y/Z,
RAccelerationX/Y/Z, DisplacementX/Y/Z, RotationX/Y/Z.
The value argument must be given in basic units [m],[s],[Kg],[N],[rad].
Example: *TdynTcl_SetSolidBodyVariable solid_body DisplacementX 0.02*
* **TdynTcl_GetSolidBodyVariable** *name variable*: Returns the value of the
variable of solid body name. Available variables are: ForceX/Y/Z, MomentX/Y/Z,
AccelerationX/Y/Z, RAccelerationX/Y/Z, DisplacementX/Y/Z, RotationX/Y/Z.
The returning variables are in basic units [m],[s],[Kg],[N],[rad].
Example: *TdynTcl_GetSolidBodyVariable solid_body RAccelerationY
* **TdynTcl_GetFluidBodyInfo** *name info*: Returns some information of the
fluid body name. Several options are available, depending on the value of the
argument info:
- nnormals: a list of nodal normals for the body is returned.
- enormals: a list of normals of the body elements is returned.
- nareas: a list of the areas associated with every body node is returned.
- eareas: a list of the areas of every element of the body is returned.
- area: the area of the body is returned.
Example: *TdynTcl_GetFluidBodyInfo fluid_body nnormals*
* **TdynTcl_GetSolidBodyInfo** *name info*: Returns some information of the
solid body name. Several options are available, depending on the value of
the argument info:
- nnormals: a list of nodal normals for the body is returned.
- enormals: a list of normals of the body elements is returned.
- nareas: a list of the areas associated with every body node is returned.
- eareas: a list of the areas of every element of the body is returned.
- area: the area of the body is returned.
Example: *TdynTcl_GetSolidBodyInfo solid_body eareas*
* **TdynTcl_X/Y/Z**: Returns the x coordinate of the current node. This function can
only be used in those tcl functions called from entries of Materials and
Boundaries windows. The returning value is given in [m].
Example: *TdynTcl_Y*
* **TdynTcl_Index** *type*: Returns the index of the current node.
Depending on type, the global (type = 0), fluid (type = 1) or
solid (type = 2) index is returned.
This function can only be used in those tcl functions called from entries
of Materials and Boundaries windows.
* **TdynTcl_ODDLSLevel** *inode*: Returns the level of the node inode
given by the levelset function (i.e. nodes connected to free surface
have level 1 for the fluid of interest and level -1 for the rest,
the rest of the nodes have a increasing (or decreasing) level given
by the shortest path required to arrive to 1 or -1 nodes).
Example: *TdynTcl_ODDLSLevel 10*
* **TdynTcl_Create_Interpolator**: Creates an interpolator structure and
returns its name. An interpolator can be used to interpolate data from nodal
values of an initial mesh to a final mesh or the other way around.
Example: *set interpolator [TdynTcl_Create_Interpolator]*
* **TdynTcl_Release_Interpolator**: Deletes an interpolator structure.
Example: *TdynTcl_Release_Interpolator $interpolator*
* **TdynTcl_Read_Interpolator_Mesh** *interpolator initial/final mesh_file*:
Reads a mesh file and inserts it in the interpolation structure.
The arguments are the interpolator name, initial or final
(i.e. original or final mesh) and the file name.
The mesh file must use the standard GiD ASCII format
(see `http://www.gidhome.com/support_team/ `_ for further information).
Example: *TdynTcl_Read_Interpolator_Mesh $interpolator initial {C:/Temp/meshi.msh}*
* **TdynTcl_Insert_Interpolator_Mesh** *interpolator initial/final name*:
Inserts a body mesh in the interpolation structure.
The arguments are the interpolator name, initial or final
(i.e. original or final mesh) and the body name or the keywords
"fluid_mesh" or "solid_mesh" for inserting the full fluid/solid mesh.
Example: *TdynTcl_Insert_Interpolator_Mesh $interpolator initial fluid_body*
* **TdynTcl_OnInitial_Interpolator** *interpolator vectorA vectorB*: Performs an
interpolation of vectorA (nodal values of the final mesh) to vectorB
(resulting nodal values of the initial mesh). The vectorB will be overwritten
with the interpolated values.
Example: *TdynTcl_OnInitial_Interpolator $interpolator $vectorA $vectorB*
* **TdynTcl_OnFinal_Interpolator** *interpolator vectorA vectorB*: Performs an
interpolation of vectorA (nodal values of the initial mesh) to vectorB
(resulting nodal values of the final mesh). The vectorB will be overwritten
with the interpolated values.
Example: TdynTcl_OnFinal_Interpolator $interpolator $vectorA $vector
* **TdynTcl_InternalToUnits** *units value*: Convert a value from internal units
to the units given as argument. if the value argument is omitted,
the conversion factor for 1.0 is returned. See `Units Syntax <./chap5_units_syntax.html>`_ section.
for information about units syntax.
Example: *TdynTcl_InternalToUnits {[m/s]}*
* **TdynTcl_UnitsToInternal** *units value*: Converts value from the units
given as argument to internal units. if the value argument is omitted,
the conversion factor for 1.0 is returned.
See `Units Syntax <./chap5_units_syntax.html>`_ section for information about units syntax.
Example: *TdynTcl_InternalToUnits {[bar]}*
* **TdynTcl_SetSolveVariableOnvariable** *variable domain*: Activates the solution of
the Tdyn problem associated to the specified variable
(0 = within the total domain, 1 = within the Fluid, 2 = within the Solid).
Example: *TdynTcl_SetSolveVariableOn velocity 0*
* **TdynTcl_SetSolveVariableOff** *variable domain*: Deactivates the solution of
the Tdyn problem associated to the specified variable
(0 = within the total domain, 1 = within the Fluid, 2 = within the Solid).
Example: *TdynTcl_SetSolveVariableOff velocity 1*
* **TdynTcl_Clock** *codename start/end*: Starts or finish a time measurement
procedure. The results are saved in the standard time table.
Example: *TdynTcl_Clock "Start time control" start*
* **TdynTcl_ProjectFileName**: Returns the name of the current project.
Example: *TdynTcl_ProjectFileName*
* **TdynTcl_GetFluidInfo** *coords/xcoords/ycoords/zcoords vector*: Returns
coordinates of fluid material nodes, storing them in a vector.
Different options are available, depending on the value of the argument info:
- *coords*: a list of nodal coordinates for the fluid is returned.
- *xcoords*: a list of nodal X coordinates for the fluid is returned.
- *ycoords*: a list of nodal Y coordinates for the fluid is returned.
- *zcoords*: a list of nodal Z coordinates for the fluid is returned.
Example:
.. code-block::
set nnod [TdynTcl_NNode 1]
set x [::mather::mkvector $nnod 0.0]
TdynTcl_GetFluidInfo xcoords $x
* **TdynTcl_Create_DistanceToMesh** *body/file [fast/precise]*: Creates a structure
to calculate distance to the mesh given in a body/boundary of mesh file in GiD format.
* **TdynTcl_Insert_DistanceToMesh** *mdistance body/file*: This procedure adds a
new mesh into a previously created mdistance.
* **TdynTcl_Update_DistanceToMesh** *mdistance body/file [mesh index]*: Updates
mdistance's nodes position from a new file of due to the movement of body/boundary.
If any body movement if performed during calculation, this will only be taken into
account after calling to this function.
* **TdynTcl_Calculate_DistanceToMesh** *mdistance body vector [numtype]*:
Calculates the distance to the nodes of the given body/boundary.
The results are stored in the given vector.
* **TdynTcl_Delete_DistanceToMesh** *[mdistance]*
* **TdynTcl_Release_DistanceToMesh** *[mdistance]*: Deletes a mdistance
(all mdistances are released if no argument is given).
Calling Tcl procedures
^^^^^^^^^^^^^^^^^^^^^^
Most of the material and data fields of Tdyn CFD+HT can be defined by
Tcl procedures. This can be done by using the tcl function, that
executes a Tcl script or procedure returning a double value.
The syntax of this function is *tcl(.)* where the argument is the script to be executed.
Examples:
* **tcl(set var)** : return the value of the Tcl variable var.
* **tcl(myproc arg)** : the procedure myproc is called with argument arg.
Procedure myproc must be defined in the Tcl script selected in the *Tcl extension*
entry and must return a double value.
Note that in order to use this function, Tcl extension must be activated by
selecting *Tcl extension*.
Tdyn Tcl math library
^^^^^^^^^^^^^^^^^^^^^
Tdyn CFD+HT Tcl extension includes a basic library for vector operation and manipulation.
The functions for vector manipulation can operate with temporal vector created from Tcl
code and with internal Tdyn CFD+HT variable vectors. Internal Tdyn CFD+HT vectors
can be accessed using the standard names for variables defined in `Function Syntax <./chap9_function_syntax.html>`_ section,
but they have to be preceded by an 's' (for solid domain vectors) or 'f' (for fluid domain vectors).
This way, the vector containing the x components of the velocity in the fluid domain can be accessed
by 'fvx', and the temperature of the solid domain by 'stm'.
.. note::
**Remarks**: Internal Tdyn CFD+HT vectors are in internal units (those
defined in the user interface). The conversion factor to any other units can
be obtained calling the procedures TdynTcl_UnitsToInternal or TdynTcl_InternalToUnits.
The basic functions of this library are described below.
* **vmexpr** function(vectorname)*
Performs the operation given by function in the vector *vectorname*, returning a real.
Functions available for vmexpr are those defined in *vmevaluate*.
Example: *set ret [vmexpr sum_abs(fvx)]*
* **vmexpr** *vector=linear_operation or vmexpr temp=function(linear_operation)*
Calculates a linear combination of vectors, returning the results in vector.
If vector is "temp" a new temporal vector is returned. A function can be applied to the
results of the linear combination.
Functions available for vmexpr are those defined in *mather_apply_vectors*.
Examples:
.. code-block::
set temp [vmexpr temp=abs(2.0*fvy)]
set temp [vmexpr temp=2.0*stm]
vmexpr $phis=$phi2+$phi1
set temp [vmexpr temp=fpr-1.]
set temp [vmexpr temp=-1.0*$phi1+[expr $a+$b]*$phi2+3.0*$phi3+1.0]
The following functions are also available under the namespace
*::mather::* with the same name, but without the prefix wm.
Example:
.. code-block::
::mather::mkvectororvmmkvector.
* **vmmkvector** *vectorsize defaultvalue*
Creates a temporal vector of size *vectorsize*. This vector is
initiated to *defaultvalue*. The function returns the name of the
vector.
Example:
.. code-block::
set temp [vmmkvector 100 0.0]
* **vmdelete** *vectorname*
Deletes the temporal vector named vectorname.
Example:
.. code-block::
vmdelete vector2
* **vmvector_info** *name type*
Access to information of the vector given by name. type can be:
length (length of the vector), min_index (index of the minimum of the elements),
max_index (index of the maximum of the elements), min_abs_index
(index of the minimum in absolute value of the elements),
max_abs_index (index of the maximum in absolute value of the elements)
or values (return a list with the elements of the vector).
Example:
.. code-block::
*vmvector_info $res values*
* **vmdelete**
Deletes all the temporal vectors.
Example:
.. code-block::
vmdelete
* **vmdimtemps** *isize*
Defines the dimension of the array of temporal vectors to isize.
By default Tdyn CFD+HT only allows to use 100 temporal vectors.
This function has to be called before to start using temporal vectors.
Example:
.. code-block::
vmdimtemps 150
* **vmsetelem** *vectorname index newvalue*
Set a single element of a vector to a new value.
Example:
.. code-block::
vmsetelem stm 150 0.0
* **vmgetelem** *vectorname index*
Returns a single element of a vector.
Example:
.. code-block::
vmgetelem stm 150
* **vmvector_print** *vectorname*
Returns a string containing all the the index and value of every element of the vector.
Example:
.. code-block::
vmvector_print fvy
* **vmapply** *function vectorname*
Apply a function to every value of the vector named vectorname.
Available functions are abs, sqrt, cos, sin, tan, acos, asin, atan,
cosh, sinh, tanh, log, log10, exp, square, inverse and opposite.
Example:
.. code-block::
vmapply sqrt temp2
* **vmevaluate** *function vectorname*
Apply a function to a vector named vectorname. Available
functions are sum, sum_abs, min_val, max_val, min_abs, max_abs,
min_signed, max_signed, sumsq, norm, mean, fintegral, sintegral,
fintegralnorm, sintegralnorm.
Example:
.. code-block::
vmevaluate min_val temp2
vmevaluate sintegral stm
vmevaluate fintegral ftm
* **vmupdate** *vectorname newvalue*
Sets the ith value of vectorname to the i-1th. The last value of vectorname is set to newvalue.
* **vmexists_vector** *vectorname*
Returns 1 if the vector vectorname exists in the current problem.
vectorname can be any of the standard vector names of Tdyn CFD+HT shown in `Function Syntax <./chap9_function_syntax.html>`_ section.
* **vmexists_smatrix*** matrixname*
Returns 1 if the matrix matrixname exists in the current
problem. The argument matrixname is generally composed of a
key name and a prefix (f- for fluid domain and s- for solid
domain):
N_DNx: matrix :math:`\int_{\Omega}N_i·dN_j/dN_xd\Omega`
N_DNy: matrix :math:`\int_{\Omega}N_i·dN_j/dN_yd\Omega`
N_DNz: matrix :math:`\int_{\Omega}N_i·dN_j/dN_zd\Omega`
DN_DN: matrix :math:`\int_{\Omega}{\triangledown}N_i{\triangledown}N_jd\Omega`
DNx_DNx: matrix :math:`\int_{\Omega}dN_i/dN_x·dN_j/dN_xd\Omega`
DNx_DNy: matrix :math:`\int_{\Omega}dN_i/dN_x·dN_j/dN_yd\Omega`
DNx_DNz: matrix :math:`\int_{\Omega}dN_i/dN_x·dN_j/dN_zd\Omega`
DNy_DNy: matrix :math:`\int_{\Omega}dN_i/dN_y·dN_j/dN_yd\Omega`
DNy_DNz: matrix :math:`\int_{\Omega}dN_i/dN_y·dN_j/dN_zd\Omega`
DNz_DNz: matrix :math:`\int_{\Omega}dN_i/dN_z·dN_j/dN_zd\Omega`
SDNx_DNy: matrix :math:`\int_{\Omega}dN_i/dN_x·dN_j/dN_yd\Omega+\int_{\Omega}dN_i/dN_y·dN_j/dN_xd\Omega`
SDNx_DNz: matrix :math:`\int_{\Omega}dN_i/dN_x·dN_j/dN_zd\Omega+\int_{\Omega}dN_i/dN_z·dN_j/dN_xd\Omega`
SDNy_DNz: matrix :math:`\int_{\Omega}dN_i/dN_y·dN_j/dN_zd\Omega+\int_{\Omega}dN_i/dN_z·dN_j/dN_yd\Omega`
N_N: matrix :math:`\int_{\Omega}N_i·N_jd\Omega`
STAB: matrix :math:`\int_{\Omega}{\triangledown}N_i(vxv){\triangledown}N_jd\Omega`
Furthermore, the system matrix of a problem is accessed with the key name SYS,
and the system matrix for every component of the velocity vector with the key name VSYS.
Finally, the mass matrix of the boundary mesh of any body can be accessed
using the prefix f- or s- and the name of the corresponding body.
.. note::
**Remarks**: Any of these matrices can be or not available depending on the problem.
Examples: fn_n, sbody, fdn_dn, sdnx_dnx.
* **vmsmatrix_getelem** *matrixname irow icol*: Returns the element of the matrix in the position irow icol.
* **vmsmatrix_setelem** *matrixname irow icol value*: Sets the element of the matrix in the position irow icol to value.
* **vmmatrix_copy** *matrixname matrixname2*: Copies *matrixname2* to *matrixname*.
* **vmmatrix_add** *matrixname matrixname2*: Adds matrixname2 to matrixname.
* **vmmult_matrix_per_vec** *matrixname vectorname vectorname2*: Multiplies
matrixname by vectorname and saves the result in vectorname2.
* **vmmult_matrix_per_vec_add** *matrixname vectorname vectorname2*: Multiplies
matrixname by vectorname and adds the result to vectorname2.
* **vmmult_matrix_per_vec_sub** *matrixname vectorname vectorname2*: Multiplies
matrixname by vectorname and subtracts the result from vectorname2.
* **vmmult_matrixt_per_vec** *matrixname vectorname vectorname2*: Multiplies
the transpose of matrixname by vectorname and saves the result in vectorname2.
* **vmmult_matrixt_per_vec_add** *matrixname vectorname vectorname2*: Multiplies
the transpose of matrixname by vectorname and adds the result to vectorname2.
* **vmmult_matrixt_per_vec_sub** *matrixname vectorname vectorname2*: Multiplies
the transpose of matrixname by vectorname and subtracts the result from vectorname2.
* **vmmatrix_vector_mult_add** *matrixname vectorname matrixname2 {add_arg}*:
Multiplies matrixname by the elements of vectorname and adds the result to
matrixname2 **(B=A·v)**. If the additional *add_arg* is given, other type of
matrix-vector operations can be done. For *add_arg=1*, the operation carried
out is **B=1/2·[A·v+(A :sup:`T`.v) :sup:`T`]**. For *add_arg=2*, the operation
done is similar to the previous case, but the result of the operation is
limited if the element of the matrix is negative. For *add_arg=3*, the operation
performed is B=(A :sup:`T`.v) :sup:`T`.
* **vmmatrix_scalar_mult_add** *matrixname value matrixname2*: Multiplies
matrixname by value and adds the result to matrixname2.
* **vmmult_vector_per_vec** *vector vector2 resvector*: Multiplies two vectors
(vector and vector2) component by component and saves the result in resvector.
* **vmquot_vector_per_vec** *vector vector2 resvector*: Calculates the quotient
of the components of two vectors (vector and vector2) and saves the result in resvector.
* **vmcreate_function** *domain function*:
::mather::create_function domain function
Creates a Tdyn function to be used in the Tcl script.
Domain must be fluid/solid/waves (waves is used for Seakeeping analysis).
The functions returns the function name assigned.
Further information on the Tdyn functions syntax can be find at Function Syntax.
* **vmevaluate_function** *function [ipnt]*
::mather::evaluate_function function [ipnt]
Evaluates a Tdyn function created in the Tcl script. If ipnt is given,
the function is evaluated for the node of index ipnt.
* **vmdelete_function** *function_name*
::mather::delete_function [function_name]
Deletes a previously created function given by function_name.
* **mather_initcoupling** *type port timeout*:
::mather::initcoupling type port timeout
Initiate coupling library of Tdyn. Coupling library allows to
interchange information at memory level among two Tdyn instances.
type must be 0,1,2 indicating whether this instance will act as
server (1), client (2) or any of them (0, randomly selected).
* **mather_insertcouplingmesh** *name/file*
Inserts a mesh to interpolate data from one side of the communication
interface to the other. The input data must be the internal name of a body mesh
or a file containing a mesh in GiD ASCII format.
* **mather_retrievecouplingheader**
::mather::retrieve_coupling_header
Starts a reading communication sequence. The execution of the current instance
is paused until a confirmation of reception is received.
This confirmation must be sent by other instance by a call to ::mather::send_coupling_vector.
The procedure returns a Tcl list containing the data type id (integer),
the corresponding time step (double) and the size of the vector that will be sent immediately (integer).
* **mather_sendcouplingvector** *name type step*
::mather::send_coupling_vector name type step
Sends a vector given by name to other Tdyn instance.
* **mather_retrievecouplingvector** *name*
::mather::retrieve_coupling_vector name
Reads the information sent by other Tdyn instance by means of ::mather::send_coupling_vector,
and saves the data to vector name. A previous call to ::mather::retrieve_coupling_header is required.
* **mather_sendcouplingconvergence** *step 0/1*
::mather::send_coupling_convergence
Sends convergence information to other Tdyn instance. The arguments are
the time step and the convergence status (1 for 'convergence obtained', or 0 for 'not converged').
Examples of scripts defining a Tcl extension
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The scripts below show examples of procedures defining a Tdyn CFD+HT Tcl extension.
In order to execute these procedures, they have to be saved to a file and
the file has to be inserted in the *Tcl extension* entry in the
**Fluid Dynamics & MultiPhysicsData > Other | General data** page.
More practical examples of Tcl extension can be found in the Tdyn Tutorials
manual: see Ekman's Spiral and Taylor-Couette flow tutorials.
* **Tcl script example 1: Write a notice in Tdyn's info file**
The following script (TdynTcl_AssembleFluidSpecies) is executed every time
the system of equations for species problem is assembled.
It just writes a message to the standard Tdyn CFD+HT output
(**Calculate > View process info...**).
.. code-block::
proc TdynTcl_AssembleFluidSpecies { ispecies } {
# Reading Tdyn CFD+HT internal time
set t [TdynTcl_Time]
# Writing a message in Tdyn CFD+HT info window
TdynTcl_Message "Executing TdynTcl_AssembleFluidSpecies $ispecies: time $t" notice
}
* **Tcl script example 2: Fix pressure values**
The following script is invoked every time the pressure system of equations is assembled.
It fixes the value of the pressure to y^2+1.
.. code-block::
proc TdynTcl_AssembleFluidPressure { } {
# Reading the number of total nodes
set nnode [TdynTcl_NNode 0]
# Imposing boundary conditions
for { set i 1 } { $i <= $nnode } { incr i } {
# Check if the node is in the fluid domain
if { [TdynTcl_IsFluid $i] } {
# Read y coordinate of the node i
set y [TdynTcl_Coord $i 2]
# Fix degree of freedom i to y^2+1
TdynTcl_FixSystemRow $i [expr pow($y,2)+1]
}
}
}
* **Tcl script example 3: Write results in a file**
The following script is invoked once the current time step is finished.
It writes the velocity values of several points to a file.
.. code-block::
proc TdynTcl_FinishStep { } {
# Open file "C:/Temp/writing_in_this_file" ...
cd {C:/Temp}
set fileid [open writing_in_this_file w+]
# ... and writes some info for a list of nodes
set nodelist [list 1 2 3 4 5]
puts $fileid "Velocity info for time $t"
foreach inode $nodelist {
puts $fileid "Velocity of node $inode: \
[TdynTcl_VecVal vx $inode] \
[TdynTcl_VecVal vy $inode] \
[TdynTcl_VecVal vz $inode]"
}
# Finally close the file
close $fileid
}
* **Tcl script example 4: Impose traction on fluid body**
The following script is called every time the velocity system of equations
is assembled. It imposes a traction on the nodes of the fluid body "wind"
that is defined through the user interface in the standard way.
.. code-block::
proc TdynTcl_AssembleFluidMomentumX { } {
TdynTcl_Message "Imposing traction in fluid momentum X equation" notice
# Value of traction
set value 1.0
# Read the list of nodes of the fluid body "Wind"
set nodes [TdynTcl_GetFluidBodyNodes wind]
# Create a traction vector
set nnode [TdynTcl_NNode 1]
set tract [::mather::mkvector $nnode 0.0]
foreach inode $nodes {
set jnode [TdynTcl_GlobalToFluid $inode]
::mather::setelem $tract $jnode $value
}
# Calculate the FEM integral of the traction
set temp [::mather::vmexpr temp=fwind*$tract]
# Assemble the terms
foreach inode $nodes {
set jnode [TdynTcl_GlobalToFluid $inode]
set ri [TdynTcl_GetRhs $jnode]
set ti [::mather::getelem $temp $jnode]
TdynTcl_SetRhs $jnode [expr $ri+$ti]
}
# Delete the temporal vectors
::mather::delete $tract
::mather::delete $temp
}
* **Tcl script example 5: Loading Tk package**
The following script loads Tk package. Tk is Tcl a library,
including basic elements for building a graphical user interface.
Once this library is loaded, graphic elements can be created from
the Tdyn Tcl interface. In this example, a text window is created and
then every time step, the text "Step $Current_Step$" is printed in that window.
In the following code, the full Tcl installation is assumed to be in the
directory "C:\Program Files\Tcl\lib". The full Tcl installation can be
downloaded from `www.activestate.com/activetcl `_
.. code-block::
# Define directory of the Tcl installation
lappend ::auto_path {C:\Program Files\Tcl\lib}
TdynTcl_Message [package require Tk] notice
# Creates a text window
pack [text .t -width 70 -height 20]
# Prints information in the text window
proc TdynTcl_StartNewFluidStep { } {
set step [TdynTcl_Step]
.t ins end "Step $step\n" ; .t see end ; update
}
* **Tcl script example 6: Interpolates data form one mesh to other**
The following example interpolates the nodal values of the pressure from
a Fluid Body mesh of Tdyn, on a mesh read from a file. Both meshes must represent
the same geometry.
The mesh file read from a file must use the standard GiD ASCII format
(see `www.gidhome.com/support_team `_
for further information).
.. code-block::
proc TdynTcl_FinishProblem { } {
# Creates an interpolator structure
set interpolator [TdynTcl_Create_Interpolator]
# Insert first mesh (A) - Fluid Body called "Wall/Bodies Auto1"
TdynTcl_Insert_Interpolator_Mesh $interpolator initial "Wall/Bodies Auto1"
# Insert second mesh (B) from file C:/Temp/bmesh.msh
TdynTcl_Read_Interpolator_Mesh $interpolator final {C:/Temp/bmesh.msh}
# Creates a vector (dimension of the number of nodes of mesh B is set to nnod)
set nnod 587
set res [::mather::mkvector $nnod 0.0]
# Performs an interpolation of the pressure values in mesh A to mesh B
TdynTcl_OnFinal_Interpolator $interpolator fpr $res
# Writes the resulting values in a file (GiD postprocessing format)
cd {C:/Temp}
set fileid [open output_file w+]
puts $fileid "GiD Post Results File 1.0"
puts $fileid "Result Pressure Analysis 1 Scalar OnNodes"
puts $fileid "Values"
puts $fileid [::mather::vector_print $res]
puts $fileid "End Values"
close $fileid
# Deletes interpolator structure
TdynTcl_Release_Interpolator $interpolator
}
* **Tcl script example 7: Debugging a Tcl script with Ramdebugger**
RamDebugger is a graphical debugger for Tcl-TK. With RamDebugger,
it is possible to make Local Debugging, where the debugger starts
the program to be debugged. and Remote debugging, where the program to debug
is already started and RamDebugger connects to it.
The latter option will be used in this case.
.. note::
**Remarks**: In Windows, it is necessary to load the package comm (not the standard,
but the one modified in RamDebugger), in order to debug the program remotely.
To debug the following example:
1. Open it with Ramdebugger and set a breakpoint in the line "TdynTcl_Message"
Set a breakpoint in this line" notice".
2. Then execute Tdyn, and wait for a few seconds, until the execution freezes.
3. Go to Ramdebugger pressing **F12** and select.
:guilabel:`File > Debug on > Tdyn`
4. Tdyn execution will restart until the breakpoint is find.
.. note::
**Remarks**: If Tdyn is not included in the list of "Remote TCL
debugging" programs, select to update the list.
:guilabel:`File > Debug on > Update remotes`
.. code-block::
# Load package commR
# Change the directory below with the one where Ramdebugger is installed
lappend ::auto_path {C:/Utils/RamDebugger7.0/addons}
TdynTcl_Message [package require commR] notice
set ret [package require commR]
# This register Tdyn for debugging
comm::register Tdyn 1
# Add breakpoint beyond this point.
# breakpoints only work inside a proc.
proc TdynTcl_FinishStep {} {
TdynTcl_Message "Set a breakpoint in this line" notice
TdynTcl_Message "Click the arrow button to go to this line" notice
TdynTcl_Message "Click the arrow button to go to this line" notice
}
# Program gets stopped here waiting for the debugger to connect
commR::wait_for_debugger
* **Tcl script example 8: Solving the wave equation using URSOLVER**
This example shows how to solve the following wave equation:
:math:`d^{2\varphi}/dt^2-c^2·{\triangle}{\varphi}=0`
The procedure to solve it requires to create a new phi variable (ph1) using
URSOLVER module. All the properties of the new variable have to be set to
zero except f2, that have to be set to the square of the wave velocity (phase speed).
In the following picture f2 is set to the value corresponding to a gravity wave of 11 m length.
.. figure:: figures/Phi_edition.png
:scale: 80%
:align: center
Definition of the properties of the phi variable.
The model has to be completed with the proper initial and boundary conditions.
The following script modifies the assembling process of the ph1 problem,
by adding the temporal term of the wave equation.
.. code-block::
set x1 ""
set x2 ""
proc TdynTcl_StartNewFluidStep {} {
global x1 x2
# Create two vectors to save ph1(t-dt) and ph1(t)
set nnod [TdynTcl_NNode 1]
# x1 is initiated with ph1' values
if { $x1 eq "" } {
set x1 [::mather::mkvector $nnod 0.0]
}
if { $x2 eq "" } {
set x2 [vmexpr temp=fph1]
}
}
proc TdynTcl_AssembleFluidPhiVariable { index } {
global x1 x2
if { $index != 1 } { return }
set nnod [TdynTcl_NNode 1]
set step [TdynTcl_Step]
set dt_i [expr 1.0/[TdynTcl_Dt]]
set dt2i [expr pow($dt_i,2.0)]
# Assemble temporal term (ph1'')
if { $step == 1 } {
set x2_ [vmexpr temp=$dt2i*$x2]
set x1_ [vmexpr temp=$dt_i*$x1]
} else {
set x2_ [vmexpr temp=2.0*$dt2i*$x2]
set x1_ [vmexpr temp=-$dt2i*$x1]
}
# Assemble ph1(t+dt)/dt^2
::mather::matrix_scalar_mult_add fsys $dt2i fn_n
# Assemble (right hand side) 2.0*ph1(t)/dt^2
::mather::mult_matrix_per_vec fn_n $x2_ frhs
# Assemble (right hand side) -ph1(t-dt)/dt^2
::mather::mult_matrix_per_vec_add fn_n $x1_ frhs
::mather::delete $x1_
::mather::delete $x2_
}
proc TdynTcl_FinishFluidStep {} {
global x1 x2
# Update phi values
vmexpr $x1=$x2
vmexpr $x2=fph1
}
* **Tcl script example 9: Distance to body calculation**
The following example, creates the structure to calculate the distance to the body "group2".
Afterwards, the distance is calculated every step and stored in the vector "vector0".
.. code-block::
set myvec ""
set mydistance ""
proc TdynTcl_InitiateProblem {} {
global myvec mydistance
TdynTcl_Clock "Distance evaluation" start
set myvec [::mather::mkvector vector0 [TdynTcl_NNode 2] 0.0 ]
set mydistance [TdynTcl_Create_DistanceToMesh group2 precise]
TdynTcl_Clock "Distance evaluation" end
}
proc TdynTcl_FinishSolidStep {} {
global myvec mydistance
if { [TdynTcl_Step] == 1 } {
set name "Distance evaluation 1"
} else {
set name "Distance evaluation"
}
TdynTcl_Clock $name start
# Note numtype argument (0,1 or 2) is optional in the following
TdynTcl_Update_DistanceToMesh $mydistance group2
TdynTcl_Calculate_DistanceToMesh $mydistance group1
$myvec
TdynTcl_Clock $name end
}