Commit bab98dc8 authored by Sebastien Timmermans's avatar Sebastien Timmermans 🎹
Browse files

Merge branch 'oneshot_dirdyn' into 'dev'

Oneshot dirdyn option

See merge request robotran/mbsysc!400
parents d8ea67c1 23e06afa
...@@ -12,6 +12,9 @@ ...@@ -12,6 +12,9 @@
* [Py] User vector outputs are now available in the MbsDirdyn results field. * [Py] User vector outputs are now available in the MbsDirdyn results field.
* [Py] Using C symbolic library and Python user is possible even with external forces. * [Py] Using C symbolic library and Python user is possible even with external forces.
* [Py] Adding missing fields in MbsData. * [Py] Adding missing fields in MbsData.
* [dirdyn][new option] A new option option called 'oneshot' is added.
-> It allows to compute the derivative function only once (no time derivation) at time = dt0.
-> See the 'flag_oneshot' in dirdyn options.
* [dirdyn][Fix] the function user_dirdyn_loop is now called only at the real time steps, even for multisteps integration methods. * [dirdyn][Fix] the function user_dirdyn_loop is now called only at the real time steps, even for multisteps integration methods.
* [dirdyn][Fix] the mbs_data->flag_stop is taken into account in all the integrators now, the simulation stops. * [dirdyn][Fix] the mbs_data->flag_stop is taken into account in all the integrators now, the simulation stops.
* [integrators][dirdyn] Add a new integrator called 'AlphaM' for alpha method. It is explicit, fixed step-size but with two stages and a bit smarter than Euler explicit :-) * [integrators][dirdyn] Add a new integrator called 'AlphaM' for alpha method. It is explicit, fixed step-size but with two stages and a bit smarter than Euler explicit :-)
......
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Example of multibody system computed with MBsysPy using Python project files.
Summary
-------
This template loads the data file *.mbs and execute:
- the coordinate partitioning module
- the direct dynamic module (time integration of equations of motion).
- the equilibrium module
- the modal module
- the inverse dynamic module
""" """
# Author: Robotran Team
Universite catholique de Louvain # (c) Universite catholique de Louvain, 2021
CEREM : Centre for research in mechatronics
http://www.robotran.be
Contact : info@robotran.be
Main script template for complete model:
-----------------------------------------------
This template loads the data file *.mbs and execute:
- the coordinate partitioning module
- the direct dynamic module (time integration of
equations of motion).
- the equilibrium module
- the modal module
- the inverse dynamic module
It may be adapted and completed by the user.
(c) Universite catholique de Louvain
"""
#============================================================================== # %%===========================================================================
# Packages loading # Packages loading
#============================================================================== # =============================================================================
import sys import sys
sys.path.append("../../../MBsysC/mbs_interface") # Relative path for this example script # Add path to the MBsysC build folder
sys.path.insert(1, "../../../MBsysC/build/python")
import MBsysPy as Robotran import MBsysPy as Robotran
#============================================================================== # %%===========================================================================
# Project loading # Project loading
#============================================================================== # =============================================================================
mbs_data = Robotran.MbsData("../dataR/PendulumSpringC.mbs", user_path = "userfctR/userfctR_python", symbolic_path = "symbolicR/symbolicR_python") mbs_data = Robotran.MbsData("../dataR/PendulumSpringC.mbs",
user_path="userfctR/userfctR_python",
symbolic_path="symbolicR/symbolicR_python"
)
print(mbs_data) print(mbs_data)
#============================================================================== # %%===========================================================================
# Partitionning # Partitionning
#============================================================================== # =============================================================================
mbs_data.process = 1 mbs_data.process = 1
mbs_part = Robotran.MbsPart(mbs_data) mbs_part = Robotran.MbsPart(mbs_data)
mbs_part.set_options(rowperm = 1, verbose = 1) mbs_part.set_options(rowperm=1, verbose=1)
mbs_part.run() mbs_part.run()
#============================================================================== # %%===========================================================================
# Equilibrium # Equilibrium
#============================================================================== # =============================================================================
mbs_data.process = 2 mbs_data.process = 2
mbs_equil = Robotran.MbsEquil(mbs_data) mbs_equil = Robotran.MbsEquil(mbs_data)
mbs_equil.set_options(method = 1, senstol = 1e-2, verbose = 1) mbs_equil.set_options(method=1, senstol=1e-2, verbose=1)
mbs_equil.run() mbs_equil.run()
#============================================================================== # %%===========================================================================
# Modal Analysis # Modal Analysis
#============================================================================== # =============================================================================
mbs_data.process = 4 mbs_data.process = 4
mbs_modal = Robotran.MbsModal(mbs_data) mbs_modal = Robotran.MbsModal(mbs_data)
mbs_modal.set_options(save_result = 1, save_anim = 1, mode_ampl = 0.2) mbs_modal.set_options(save_result=1, save_anim=1, mode_ampl=0.2)
mbs_modal.run() mbs_modal.run()
#============================================================================== # %%===========================================================================
# Direct Dynamics # Direct Dynamics, oneshot
#============================================================================== # =============================================================================
mbs_data.process = 3
mbs_data.qd[1] = 1.5
mbs_dirdyn = Robotran.MbsDirdyn(mbs_data)
mbs_dirdyn.set_options(flag_oneshot=1)
mbs_dirdyn.run()
# %%===========================================================================
# Direct Dynamics, time integration
# =============================================================================
mbs_data.process = 3 mbs_data.process = 3
mbs_data.qd[1] = 1.5 mbs_data.qd[1] = 1.5
mbs_dirdyn = Robotran.MbsDirdyn(mbs_data) mbs_dirdyn = Robotran.MbsDirdyn(mbs_data)
mbs_dirdyn.set_options(dt0 = 1e-3, tf = 10.0, save2file = 1) mbs_dirdyn.set_options(dt0=1e-3, tf=0.1, save2file=1)
mbs_dirdyn.set_options(integrator = "RK4", resfilename = "RK4") mbs_dirdyn.set_options(integrator="RK4", resfilename="RK4")
mbs_dirdyn.run() mbs_dirdyn.run()
#============================================================================== # %%===========================================================================
# Inverse Dynamics # Inverse Dynamics
#============================================================================== # =============================================================================
mbs_data.process = 6 mbs_data.process = 6
mbs_data.reset() mbs_data.reset()
mbs_data.set_qa(4) mbs_data.set_qa(4)
...@@ -82,8 +86,8 @@ mbs_data.set_qa(1) ...@@ -82,8 +86,8 @@ mbs_data.set_qa(1)
mbs_data.set_qa(3) mbs_data.set_qa(3)
mbs_data.set_qa(2) mbs_data.set_qa(2)
mbs_invdyn = Robotran.MbsInvdyn(mbs_data) mbs_invdyn = Robotran.MbsInvdyn(mbs_data)
mbs_invdyn.set_options(trajectoryqname = "../resultsR/RK4_q.res") mbs_invdyn.set_options(trajectoryqname="../resultsR/RK4_q.res")
mbs_invdyn.set_options(trajectoryqdname = "../resultsR/RK4_qd.res") mbs_invdyn.set_options(trajectoryqdname="../resultsR/RK4_qd.res")
mbs_invdyn.set_options(trajectoryqddname = "../resultsR/RK4_qdd.res") mbs_invdyn.set_options(trajectoryqddname="../resultsR/RK4_qdd.res")
mbs_invdyn.set_options(t0 = 1.0, tf = 2.0, dt = 2.5e-3) mbs_invdyn.set_options(t0=1.0, tf=2.0, dt=2.5e-3)
mbs_invdyn.run() mbs_invdyn.run()
...@@ -74,6 +74,8 @@ MbsDirdyn* mbs_new_dirdyn_aux(MbsData* mbs_data, MbsAux* mbs_aux) ...@@ -74,6 +74,8 @@ MbsDirdyn* mbs_new_dirdyn_aux(MbsData* mbs_data, MbsAux* mbs_aux)
opts->compute_all_uxd = 1; opts->compute_all_uxd = 1;
opts->flag_oneshot = 0;
opts->flag_compute_Qc = COMPUTE_ALL_QC; opts->flag_compute_Qc = COMPUTE_ALL_QC;
// Initialization for fast computation of Qc // Initialization for fast computation of Qc
int i; int i;
...@@ -138,6 +140,38 @@ MbsDirdyn* mbs_new_dirdyn_aux(MbsData* mbs_data, MbsAux* mbs_aux) ...@@ -138,6 +140,38 @@ MbsDirdyn* mbs_new_dirdyn_aux(MbsData* mbs_data, MbsAux* mbs_aux)
return dirdyn; return dirdyn;
} }
int check_user_dirdyn_options(MbsDirdyn* dd, MbsData* mbs_data)
{
int err = 0;
// errors generated
if (dd->options->t0 > dd->options->tf)
{
err = _MBS_ERR_INIT;
mbs_msg("\t >Dirdyn> options error: t0 (%f) > tf (%f).\n", dd->options->t0, dd->options->tf);
mbs_msg("[%d] in check_user_dirdyn_options !! \n", err);
return err;
}
if (dd->options->dt0 <= 0.0)
{
err = _MBS_ERR_INIT;
mbs_msg("\t >Dirdyn> options error: dt0 (%f) is not strictly positive.\n", dd->options->dt0);
mbs_msg("[%d] in check_user_dirdyn_options !! \n", err);
return err;
}
if (dd->options->t0 == dd->options->tf)
{
err = _MBS_ERR_INIT;
mbs_msg("\t >Dirdyn> options error: t0 (%f) == tf (%f).\n", dd->options->t0, dd->options->tf);
mbs_msg("\t >Dirdyn> if you need one evaluation of the derivative function, see the oneshot option in dirdyn. \n");
mbs_msg("[%d] in check_user_dirdyn_options !! \n", err);
return err;
}
return err;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void mbs_delete_dirdyn(MbsDirdyn* dirdyn, MbsData* mbs_data) void mbs_delete_dirdyn(MbsDirdyn* dirdyn, MbsData* mbs_data)
...@@ -158,10 +192,11 @@ void mbs_delete_dirdyn(MbsDirdyn* dirdyn, MbsData* mbs_data) ...@@ -158,10 +192,11 @@ void mbs_delete_dirdyn(MbsDirdyn* dirdyn, MbsData* mbs_data)
int mbs_run_dirdyn(MbsDirdyn* dd, MbsData* mbs_data) int mbs_run_dirdyn(MbsDirdyn* dd, MbsData* mbs_data)
{ {
int err = 0; int err = 0;
// 1. Initialize the simulation // 1. Initialize the simulation
// - - - - - - - - - - - - - - // - - - - - - - - - - - - - -
err = mbs_dirdyn_init(dd, mbs_data); err = mbs_dirdyn_init(dd, mbs_data);
if (err < 0){ if (err < 0) {
// Freeing the buffers, without error catching // Freeing the buffers, without error catching
mbs_dirdyn_finish(dd, mbs_data); mbs_dirdyn_finish(dd, mbs_data);
mbs_error_msg("[%d] in mbs_run_dirdyn !! \n", _MBS_ERR_MOD_DIRDYN + err); mbs_error_msg("[%d] in mbs_run_dirdyn !! \n", _MBS_ERR_MOD_DIRDYN + err);
...@@ -170,14 +205,22 @@ int mbs_run_dirdyn(MbsDirdyn* dd, MbsData* mbs_data) ...@@ -170,14 +205,22 @@ int mbs_run_dirdyn(MbsDirdyn* dd, MbsData* mbs_data)
// 2. Run the simulation // 2. Run the simulation
// - - - - - - - - - - - // - - - - - - - - - - -
err = mbs_dirdyn_loop(dd, mbs_data); if (dd->options->flag_oneshot)
if (err < 0){ {
err = mbs_fct_dirdyn(dd->tsim, dd->y, dd->yd, mbs_data, dd);
}
else
{
err = mbs_dirdyn_loop(dd, mbs_data);
}
if (err < 0) {
// Freeing the buffers, without error catching // Freeing the buffers, without error catching
mbs_dirdyn_finish(dd, mbs_data); mbs_dirdyn_finish(dd, mbs_data);
mbs_error_msg("[%d] in mbs_run_dirdyn !! \n", _MBS_ERR_MOD_DIRDYN + err); mbs_error_msg("[%d] in mbs_run_dirdyn !! \n", _MBS_ERR_MOD_DIRDYN + err);
return _MBS_ERR_MOD_DIRDYN + err; return _MBS_ERR_MOD_DIRDYN + err;
} }
// 3. Finish the simulation // 3. Finish the simulation
// - - - - - - - - - - - - // - - - - - - - - - - - -
err = mbs_dirdyn_finish(dd, mbs_data); err = mbs_dirdyn_finish(dd, mbs_data);
...@@ -262,6 +305,10 @@ int mbs_dirdyn_init(MbsDirdyn* dd, MbsData* mbs_data) ...@@ -262,6 +305,10 @@ int mbs_dirdyn_init(MbsDirdyn* dd, MbsData* mbs_data)
if (dd->options->verbose) if (dd->options->verbose)
{ {
mbs_msg("\n>>DIRDYN>> Starting direct dynamics module.\n"); mbs_msg("\n>>DIRDYN>> Starting direct dynamics module.\n");
if (dd->options->flag_oneshot)
{
mbs_msg("\n>>DIRDYN>> One shot evaluation of the direct dynamics is activated.\n");
}
} }
// Checking mbs_data coherence // Checking mbs_data coherence
...@@ -377,6 +424,14 @@ int mbs_dirdyn_init(MbsDirdyn* dd, MbsData* mbs_data) ...@@ -377,6 +424,14 @@ int mbs_dirdyn_init(MbsDirdyn* dd, MbsData* mbs_data)
} }
user_dirdyn_init(mbs_data, dd); user_dirdyn_init(mbs_data, dd);
// Checking time options
err = check_user_dirdyn_options(dd, mbs_data);
if (err < 0) {
mbs_msg("\t >Dirdyn> Incoherence detected during module initialization! \n");
mbs_msg("[%d] in mbs_dirdyn_init !! \n", err);
return err;
}
/* TODO : Move in initialize_integrator when 2nd order integrator will be implemented */ /* TODO : Move in initialize_integrator when 2nd order integrator will be implemented */
// Simulation state initialization // Simulation state initialization
for (i = 1; i <= mbs_data->nqu; i++) for (i = 1; i <= mbs_data->nqu; i++)
...@@ -417,9 +472,14 @@ int mbs_dirdyn_init(MbsDirdyn* dd, MbsData* mbs_data) ...@@ -417,9 +472,14 @@ int mbs_dirdyn_init(MbsDirdyn* dd, MbsData* mbs_data)
bufElemNb = (int*)malloc(bufSize * sizeof(int)); bufElemNb = (int*)malloc(bufSize * sizeof(int));
// set the filename if not specified // set the filename if not specified
if (dd->options->resfilename == NULL) { if (dd->options->resfilename == NULL && !dd->options->flag_oneshot) {
resfilename = "dirdyn"; resfilename = "dirdyn";
} }
else if (dd->options->resfilename == NULL && dd->options->flag_oneshot)
{
resfilename = "oneshot";
mbs_msg("\n>>DIRDYN>> Output filename is called 'oneshot' by default.\n");
}
else { else {
resfilename = dd->options->resfilename; resfilename = dd->options->resfilename;
} }
...@@ -728,7 +788,7 @@ int mbs_dirdyn_loop(MbsDirdyn* dd, MbsData* mbs_data) ...@@ -728,7 +788,7 @@ int mbs_dirdyn_loop(MbsDirdyn* dd, MbsData* mbs_data)
mbs_msg("\t >Dirdyn> Error: in dirdyn loop during save realtime update ! \n"); mbs_msg("\t >Dirdyn> Error: in dirdyn loop during save realtime update ! \n");
} }
mbs_msg(">>DIRDYN>> [%d] during direct dynamics loop.\n", err); mbs_msg(">>DIRDYN>> [%d] during direct dynamics loop.\n", err);
return (err<0)?err:err2; return (err < 0) ? err : err2;
} }
// Update times // Update times
cur_t0 = cur_tf; cur_t0 = cur_tf;
...@@ -740,6 +800,7 @@ int mbs_dirdyn_loop(MbsDirdyn* dd, MbsData* mbs_data) ...@@ -740,6 +800,7 @@ int mbs_dirdyn_loop(MbsDirdyn* dd, MbsData* mbs_data)
return 0; return 0;
} }
} }
return 0; return 0;
} }
...@@ -1014,3 +1075,4 @@ int save_realtime_update(MbsDirdyn* dd, MbsData* mbs_data) ...@@ -1014,3 +1075,4 @@ int save_realtime_update(MbsDirdyn* dd, MbsData* mbs_data)
return 0; return 0;
} }
...@@ -174,4 +174,14 @@ int mbs_fct_dirdyn(double t, double y[], double dydt[], MbsData *s, MbsDirdyn *d ...@@ -174,4 +174,14 @@ int mbs_fct_dirdyn(double t, double y[], double dydt[], MbsData *s, MbsDirdyn *d
*/ */
int save_realtime_update(MbsDirdyn* dd, MbsData* mbs_data); int save_realtime_update(MbsDirdyn* dd, MbsData* mbs_data);
/*! \brief check that the dirdyn options performed by the user are correct
*
* \param[in] dd direct dynamics module
* \param[in] mbs_data Robotran main structure
*
* \return Error status, <0 in case of failure.
*/
int check_user_dirdyn_options(MbsDirdyn* dd, MbsData* mbs_data);
#endif #endif
...@@ -31,7 +31,7 @@ int mbs_estim_jac_acc(double x, double htry, double y[], double dydx[], int comp ...@@ -31,7 +31,7 @@ int mbs_estim_jac_acc(double x, double htry, double y[], double dydx[], int comp
int(*derivs)(double, double[], double[], MbsData *, MbsDirdyn *), MbsData *s, MbsDirdyn *dd) int(*derivs)(double, double[], double[], MbsData *, MbsDirdyn *), MbsData *s, MbsDirdyn *dd)
{ {
// setting the flag to ON // setting the flag to ON
dd->options->flag_ongoing_jac_computation = 1; dd->flag_ongoing_jac_computation = 1;
int i, j, err; int i, j, err;
double perturb; double perturb;
...@@ -100,7 +100,7 @@ int mbs_estim_jac_acc(double x, double htry, double y[], double dydx[], int comp ...@@ -100,7 +100,7 @@ int mbs_estim_jac_acc(double x, double htry, double y[], double dydx[], int comp
} }
// setting the flag to OFF // setting the flag to OFF
dd->options->flag_ongoing_jac_computation = 0; dd->flag_ongoing_jac_computation = 0;
return 0; return 0;
} }
...@@ -154,80 +154,90 @@ void set_integrator(MbsDirdyn *mbs_dd) { ...@@ -154,80 +154,90 @@ void set_integrator(MbsDirdyn *mbs_dd) {
int id = opts->integrator; int id = opts->integrator;
switch (id) { if (!opts->flag_oneshot)
{
case RK4: switch (id) {
mbs_dd->initialize_integrator = initialize_rk4;
mbs_dd->loop_integrator = loop_rk4; case RK4:
mbs_dd->finish_integrator = finish_rk4; mbs_dd->initialize_integrator = initialize_rk4;
mbs_msg(" >> Integrator : \t RK4 \n"); mbs_dd->loop_integrator = loop_rk4;
break; mbs_dd->finish_integrator = finish_rk4;
mbs_msg(" >> Integrator : \t RK4 \n");
case Dopri5: break;
mbs_dd->initialize_integrator = initialize_dopri5;
mbs_dd->loop_integrator = loop_dopri5; case Dopri5:
mbs_dd->finish_integrator = finish_dopri5; mbs_dd->initialize_integrator = initialize_dopri5;
mbs_msg(" >> Integrator : \t Dopri5 \n"); mbs_dd->loop_integrator = loop_dopri5;
break; mbs_dd->finish_integrator = finish_dopri5;
mbs_msg(" >> Integrator : \t Dopri5 \n");
case Rosenbrock: break;
mbs_dd->initialize_integrator = initialize_rosenbrock;
mbs_dd->loop_integrator = loop_rosenbrock; case Rosenbrock:
mbs_dd->finish_integrator = finish_rosenbrock; mbs_dd->initialize_integrator = initialize_rosenbrock;
mbs_msg(" >> Integrator : \t Rosenbrock \n"); mbs_dd->loop_integrator = loop_rosenbrock;
break; mbs_dd->finish_integrator = finish_rosenbrock;
mbs_msg(" >> Integrator : \t Rosenbrock \n");
case EulerEx: break;
mbs_dd->initialize_integrator = initialize_eulerEx;
mbs_dd->loop_integrator = loop_eulerEx; case EulerEx:
mbs_dd->finish_integrator = finish_eulerEx; mbs_dd->initialize_integrator = initialize_eulerEx;
mbs_msg(" >> Integrator : \t Euler Explicit \n"); mbs_dd->loop_integrator = loop_eulerEx;
break; mbs_dd->finish_integrator = finish_eulerEx;
mbs_msg(" >> Integrator : \t Euler Explicit \n");
case Eulaire: break;
mbs_dd->initialize_integrator = initialize_eulerEx;
mbs_dd->loop_integrator = loop_eulerEx; case Eulaire:
mbs_dd->finish_integrator = finish_eulerEx; mbs_dd->initialize_integrator = initialize_eulerEx;
mbs_msg(" >> Integrator : \t Eulaire \n"); mbs_dd->loop_integrator = loop_eulerEx;
break; mbs_dd->finish_integrator = finish_eulerEx;
case AlphaM: mbs_msg(" >> Integrator : \t Eulaire \n");
mbs_dd->initialize_integrator = initialize_eulerEx; break;
mbs_dd->loop_integrator = loop_eulerEx; case AlphaM:
mbs_dd->finish_integrator = finish_eulerEx; mbs_dd->initialize_integrator = initialize_eulerEx;
mbs_msg(" >> Integrator : \t Alpha Method \n"); mbs_dd->loop_integrator = loop_eulerEx;
break; mbs_dd->finish_integrator = finish_eulerEx;
case EulerIm: mbs_msg(" >> Integrator : \t Alpha Method \n");
mbs_dd->initialize_integrator = initialize_euler_implicit; break;
mbs_dd->loop_integrator = loop_euler_implicit; case EulerIm:
mbs_dd->finish_integrator = finish_euler_implicit; mbs_dd->initialize_integrator = initialize_euler_implicit;
mbs_msg(" >> Integrator : \t Euler Implicit \n"); mbs_dd->loop_integrator = loop_euler_implicit;
break; mbs_dd->finish_integrator = finish_euler_implicit;
case Bader: mbs_msg(" >> Integrator : \t Euler Implicit \n");
mbs_dd->initialize_integrator = initialize_bader; break;
mbs_dd->loop_integrator = loop_bader; case Bader:
mbs_dd->finish_integrator = finish_bader; mbs_dd->initialize_integrator = initialize_bader;
mbs_msg(" >> Integrator : \t Semi-implicit Bader-Deuflhard extrapolation method \n"); mbs_dd->loop_integrator = loop_bader;
break; mbs_dd->finish_integrator = finish_bader;
case WMethods: mbs_msg(" >> Integrator : \t Semi-implicit Bader-Deuflhard extrapolation method \n");
mbs_dd->initialize_integrator = initialize_w_methods; break;
mbs_dd->loop_integrator = loop_w_methods; case WMethods:
mbs_dd->finish_integrator = finish_w_methods; mbs_dd->initialize_integrator = initialize_w_methods;
mbs_msg(" >> Integrator : \t W Methods \n"); mbs_dd->loop_integrator = loop_w_methods;
break; mbs_dd->finish_integrator = finish_w_methods;
mbs_msg(" >> Integrator : \t W Methods \n");
case Custom: break;
mbs_dd->initialize_integrator = initialize_custom;
mbs_dd->loop_integrator = loop_custom; case Custom:
mbs_dd->finish_integrator = finish_custom; mbs_dd->initialize_integrator = initialize_custom;
mbs_msg(" >> Integrator : \t Custom \n"); mbs_dd->loop_integrator = loop_custom;
break; mbs_dd->finish_integrator = finish_custom;
mbs_msg(" >> Integrator : \t Custom \n");
default: break;
default:
mbs_dd->initialize_integrator = initialize_rk4;
mbs_dd->loop_integrator = loop_rk4;
mbs_dd->finish_integrator = finish_rk4;
mbs_warning_msg(" >> Integrator not found, possibly not yet supported !\n");
mbs_warning_msg(" >> Continuing with RK4 (Default) \n");
}
}
else
{
mbs_msg(" >> Integrator : \t rk4 is set but useless because oneshot option is activated \n");
mbs_dd->initialize_integrator = initialize_rk4; mbs_dd->initialize_integrator = initialize_rk4;
mbs_dd->loop_integrator = loop_rk4; mbs_dd->loop_integrator = loop_rk4;
mbs_dd->finish_integrator = finish_rk4; mbs_dd->finish_integrator = finish_rk4;
mbs_warning_msg(" >> Integrator not found, possibly not yet supported !\n");
mbs_warning_msg(" >> Continuing with RK4 (Default) \n");
} }
} }
......
...@@ -49,7 +49,8 @@ typedef struct MbsDirdynOptions ...@@ -49,7 +49,8 @@ typedef struct MbsDirdynOptions
* default = 1 * default = 1
*/ */
int save2file; int save2file;
/** The keyword used for determining the name of result files */ /** The keyword used for determining the name of result files
Default: 'dirdyn', or 'oneshot' in case the flag_oneshot is activated*/
char* resfilename; char* resfilename;
/** Path in which result file are saved. /** Path in which result file are saved.
* Default: the resultsR folder of the project * Default: the resultsR folder of the project
...@@ -87,6 +88,10 @@ typedef struct MbsDirdynOptions ...@@ -87,6 +88,10 @@ typedef struct MbsDirdynOptions