TUNSUB
ModelingThe TUNSUB allows you to modify certain solver parameters during a simulation.
Use
<Param_Simulation
usrsub_param_string = "USER(9998, 0.1)"
usrsub_dll_name = "NULL"
usrsub_fnc_name = "TUNSUB"
/>
Format
- Fortran Calling Syntax
-
SUBROUTINE TUNSUB (TIME, PAR, NPAR, IFLAG, ISTATE, H, IORDER)
- C/C++ Calling Syntax
-
void TUNSUB (double *time, double *par, int *npar, int *iflag, int *istate, double *h, int *iorder)
- Python Calling Syntax
-
def TUNSUB(time, par, npar, iflag, istate, h, iorder)
- MATLAB Calling Syntax
-
function TUNSUB(time, par, npar, iflag, istate, h, iorder
Attributes
- TIME
- [double precision]
- PAR
- [double precision]
- NPAR
- [integer]
- IFLAG
- [integer]
- ISTATE
- [integer]
- H
- [double precision]
- IORDER
- [integer]
Example
The following TUNSUB example modifies the absolute and relative integrator error tolerance to the value passed in as the second argument in the USER(…) in the model when the angular velocity of the rigid bodies exceed 20 radians/second.
from math import fabs
g_num_rigid_body = 0
g_cg_id_vec = []
g_body_id_vec = []
#define the TUNSUB function
def TUNSUB(time, par, npar, iflag, istate, h, iorder):
w = 3*[0.0]
global g_num_rigid_body
global g_cg_id_vec
global g_body_id_vec
#set solver parameters
py_set_dae_error(0.01)
py_set_dae_hmax(0.01)
py_set_dae_maxord(5)
py_set_dae_maxit(4)
t0 = py_get_starting_time()
te = py_get_end_time()
#define dependencies during iflag = 1
if iflag==1:
tmp_num =0
tmp_num = py_getnumid("PART")
tmp_iarray1 = tmp_num*[0]
tmp_iarray2 = tmp_num*[0]
[tmp_iarray1, istat] = py_getidlist("PART", tmp_num)
g_num_rigid_body =0
for i in xrange(tmp_num):
[tmp_str, istat] = py_modfnc("Body_Rigid", tmp_iarray1[i],"cg_id")
cg_id =int(tmp_str)
[tmp_str, istat] = py_modfnc("Body_Rigid", tmp_iarray1[i],"IsGround")
if tmp_str=='TRUE':
continue
tmp_iarray2[g_num_rigid_body] = tmp_iarray1[i]
tmp_iarray1[g_num_rigid_body] = cg_id
g_num_rigid_body +=1
g_cg_id_vec = tmp_iarray1
g_body_id_vec = tmp_iarray2
for i in xrange (g_num_rigid_body):
cg_id = g_cg_id_vec[i];
[w[0], istat] = py_sysfnc("WX", cg_id)
[w[1], istat] = py_sysfnc("WY", cg_id)
[w[2], istat] = py_sysfnc("WZ", cg_id)
return
#check if current step is converged i.e. istate = 1
if istate==1:
for i in xrange(g_num_rigid_body):
cg_id = g_cg_id_vec[i];
#obtain angular velocities for all parts
[w[0], istat] = py_sysfnc("WX", cg_id)
[w[1], istat] = py_sysfnc("WY", cg_id)
[w[2], istat] = py_sysfnc("WZ", cg_id)
#check if the angular velocities are above some threshold
#value
if (fabs(w[0])>20) | (fabs(w[1])>20) | (fabs(w[2])>20):
#change tolerance values
istat = py_set_tol_factor("Body_Rigid", g_body_id_vec[i],"ATOL", par[1])
istat = py_set_tol_factor("Body_Rigid", g_body_id_vec[i],"RTOL", par[1])
Comments
- Only one TUNSUB can be defined in the model and it should be defined in the model section. There is no ID associated with TUNSUB.
- Currently TUNSUB is application only for DAE integrator DSTIFF and FIM_D.
- TUNSUB is called after every integration step and the solver settings that are modified are applicable for analysis from that time onward.
- All the utility subroutines can be called from
TUNSUB. In addition there are several special utility
subroutines available to modify solver
settings.
set_tol_factor(char*entity_type, intentity_id, char*tol_type, doublefactor, int*errflg) set_dae_error(doubleerror); set_dae_hmax(doubleh_max); set_dae_maxord(intmaxord); set_dae_maxit(intmaxit); set_dae_jacobeval(intjacob_eval); set_dae_jacobinit(intjacob_init);