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 }