TUNSUB

ModelingTUNSUBでは、シミュレーション中に特定のソルバーパラメータを変更することができます。

使用

<Param_Simulation
     usrsub_param_string = "USER(9998, 0.1)"
     usrsub_dll_name     = "NULL"
     usrsub_fnc_name     = "TUNSUB"
  /> 

フォーマット

Fortranの呼出し構文
SUBROUTINE TUNSUB (TIME, PAR, NPAR, IFLAG, ISTATE, H, IORDER)
C/C++の呼出し構文
void TUNSUB (double *time, double *par, int *npar, int *iflag, int *istate, double *h, int *iorder)
Pythonの呼出し構文
def TUNSUB(time, par, npar, iflag, istate, h, iorder)
MATLABの呼出し構文
function TUNSUB(time, par, npar, iflag, istate, h, iorder

属性

TIME
[倍精度]
現在のシミュレーション時間。
PAR
[倍精度]
ユーザー定義のステートメントで提供されたリストにある定数引数を格納した配列。
NPAR
[整数]
PAR配列のエントリの数。
IFLAG
[整数]
MotionSolveの初期化中にユーザーサブルーチンが呼び出されたときに、MotionSolveが1に設定する整数変数。他の時間では、IFLAGは0に設定されます。
ISTATE
[整数]
積分器ステップが連続ステップの場合にMotionSolveが1に設定する整数変数。積分器ステップが連続的でない場合は、ISTATEは0に設定されます。
H
[倍精度]
現在の積分器ステップサイズ(h < h_maxParam_Transientで指定される)。
IORDER
[整数]
現在の積分器の次数(IORDER < max_orderParam_Transientで指定される)。

次のTUNSUBの例は、絶対および相対積分器誤差トレランスを、剛体の角速度が20ラジアン / 秒を超えた場合にモデル内のUSER(…)の2つ目の引数として渡される値に変更します。

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])

コメント

  1. TUNSUBは、モデル内で1つのみ定義することができ、モデルセクションで定義する必要があります。TUNSUBに関連付けられるIDはありません。
  2. 現時点で、TUNSUBは、DAE積分器DSTIFFとFIM_Dにのみ適用できます。
  3. TUNSUBは各積分ステップの後に呼び出され、その時間以降の解析には、変更されたソルバー設定が適用されます。
  4. すべてのユーティリティサブルーチンをTUNSUBから呼び出すことができます。加えて、ソルバー設定を変更するための特別なユーティリティサブルーチンがいくつか用意されています。
    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);