Fixed reset for proxy devices. In addition, documented how to achieve a

reliable voltage stop criteria in gmres solver. (nw)
This commit is contained in:
couriersud 2015-06-20 19:16:06 +02:00
parent 3d6498c7e7
commit ff2bb580ce
8 changed files with 48 additions and 26 deletions

View File

@ -294,8 +294,8 @@ void netlist_mame_device_t::device_start()
//printf("clock is %d\n", clock());
m_netlist = global_alloc_clear(netlist_mame_t(*this));
m_setup = global_alloc_clear(netlist::setup_t(m_netlist));
m_netlist = global_alloc(netlist_mame_t(*this));
m_setup = global_alloc(netlist::setup_t(m_netlist));
netlist().init_object(*m_netlist, "netlist");
m_setup->init();
@ -459,7 +459,7 @@ void netlist_mame_cpu_device_t::device_start()
{
netlist_mame_device_t::device_start();
LOG_DEV_CALLS(("device_start %s\n", tag()));
LOG_DEV_CALLS(("cpu device_start %s\n", tag()));
// State support
@ -550,12 +550,11 @@ netlist_mame_sound_device_t::netlist_mame_sound_device_t(const machine_config &m
{
}
void netlist_mame_sound_device_t::device_start()
{
netlist_mame_device_t::device_start();
LOG_DEV_CALLS(("device_start %s\n", tag()));
LOG_DEV_CALLS(("sound device_start %s\n", tag()));
// Configure outputs

View File

@ -38,7 +38,7 @@
NET_CONNECT(_name, A, _A)
#define TTL_7404_DIP(_name) \
NET_REGISTER_DEV(7402_dip, _name)
NET_REGISTER_DEV(7404_dip, _name)
NETLIB_NAMESPACE_DEVICES_START()

View File

@ -191,15 +191,17 @@ void nld_d_to_a_proxy::start()
register_subalias("Q", m_RV.m_P);
connect(m_RV.m_N, m_Q);
m_Q.initial(0.0);
save(NLNAME(m_last_state));
}
void nld_d_to_a_proxy::reset()
{
m_Q.initial(0.0);
m_last_state = -1;
m_RV.do_reset();
m_is_timestep = m_RV.m_P.net().as_analog().solver()->is_timestep();
m_RV.set(NL_FCONST(1.0) / logic_family().m_R_low, logic_family().m_low_V, 0.0);
}
ATTR_HOT void nld_d_to_a_proxy::update()

View File

@ -342,6 +342,7 @@ protected:
ATTR_HOT void update()
{
//printf("%s: %f\n", name().cstr(), m_I.Q_Analog());
if (m_I.Q_Analog() > logic_family().m_high_thresh_V)
OUTLOGIC(m_Q, 1, NLTIME_FROM_NS(1));
else if (m_I.Q_Analog() < logic_family().m_low_thresh_V)

View File

@ -50,11 +50,12 @@
#define NETLIST_NAME(_name) netlist ## _ ## _name
#define NETLIST_EXTERNAL(_name) \
ATTR_COLD void NETLIST_NAME(_name)(netlist::setup_t &setup)
ATTR_COLD void NETLIST_NAME(_name)(netlist::setup_t &setup);
#define NETLIST_START(_name) \
ATTR_COLD void NETLIST_NAME(_name)(netlist::setup_t &setup) \
{
#define NETLIST_END() }
#define LOCAL_SOURCE(_name) \

View File

@ -30,6 +30,7 @@ public:
: matrix_solver_direct_t<m_N, _storage_N>(matrix_solver_t::GAUSS_SEIDEL, params, size)
, m_use_iLU_preconditioning(true)
, m_use_more_precise_stop_condition(false)
, m_accuracy_mult(1.0)
, m_gs_fail(0)
, m_gs_total(0)
{
@ -82,6 +83,8 @@ private:
double * RESTRICT m_v[_storage_N + 1]; /*(mr + 1), n */
//double m_y[_storage_N]; /* mr + 1 */
double m_accuracy_mult;
int m_gs_fail;
int m_gs_total;
};
@ -218,7 +221,7 @@ ATTR_HOT inline int matrix_solver_GMRES_t<m_N, _storage_N>::vsolve_non_dynamic(c
#if 1
int mr = std::min(iN-1,(int) sqrt(iN));
int iter = 4;
int gsl = solve_ilu_gmres(new_V, RHS, iter, mr, accuracy * 2.0); // * (double) (iN));
int gsl = solve_ilu_gmres(new_V, RHS, iter, mr, accuracy);
int failed = mr * iter;
#else
int failed = 6;
@ -294,6 +297,7 @@ int matrix_solver_GMRES_t<m_N, _storage_N>::solve_ilu_gmres (double * RESTRICT x
*------------------------------------------------------------------------*/
unsigned itr_used = 0;
double rho_delta = 0.0;
const unsigned n = this->N();
@ -323,10 +327,10 @@ int matrix_solver_GMRES_t<m_N, _storage_N>::solve_ilu_gmres (double * RESTRICT x
//printf("rho/accuracy = %f\n", rho_to_accuracy);
accuracy *= rho_to_accuracy;
rho_delta = accuracy * rho_to_accuracy;
}
else
accuracy *= std::sqrt((double) n);
rho_delta = accuracy * std::sqrt((double) n) * m_accuracy_mult;
for (unsigned itr = 0; itr < restart_max; itr++)
{
@ -391,7 +395,7 @@ int matrix_solver_GMRES_t<m_N, _storage_N>::solve_ilu_gmres (double * RESTRICT x
itr_used = itr_used + 1;
if (rho <= accuracy)
if (rho <= rho_delta)
{
last_k = k;
break;
@ -419,10 +423,25 @@ int matrix_solver_GMRES_t<m_N, _storage_N>::solve_ilu_gmres (double * RESTRICT x
for (unsigned i = 0; i <= last_k; i++)
vec_add_mult_scalar(n, m_v[i], m_y[i], x);
if (rho <= accuracy)
#if 1
if (rho <= rho_delta)
{
break;
}
#else
/* we try to approximate the x difference between to steps using m_v[last_k] */
double xdelta = m_y[last_k] * vec_maxabs(n, m_v[last_k]);
if (xdelta < accuracy)
{
if (m_accuracy_mult < 16384.0)
m_accuracy_mult = m_accuracy_mult * 2.0;
break;
}
else
m_accuracy_mult = m_accuracy_mult / 2.0;
#endif
}
return itr_used;

View File

@ -428,8 +428,8 @@ matrix_solver_t * NETLIB_NAME(solver)::create_solver(int size, const int gs_thre
}
else
{
typedef matrix_solver_SOR_t<m_N,_storage_N> solver_GS;
//typedef matrix_solver_GMRES_t<m_N,_storage_N> solver_GS;
//typedef matrix_solver_SOR_t<m_N,_storage_N> solver_GS;
typedef matrix_solver_GMRES_t<m_N,_storage_N> solver_GS;
return palloc(solver_GS, &m_params, size);
}
}
@ -501,7 +501,6 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start()
switch (net_count)
{
#if 1
case 1:
ms = create_solver<1,1>(1, gs_threshold, use_specific);
break;
@ -532,9 +531,7 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start()
case 87:
ms = create_solver<87,87>(87, gs_threshold, use_specific);
break;
#endif
default:
#if 0
if (net_count <= 16)
{
ms = create_solver<0,16>(net_count, gs_threshold, use_specific);
@ -548,7 +545,6 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start()
ms = create_solver<0,64>(net_count, gs_threshold, use_specific);
}
else
#endif
if (net_count <= 128)
{
ms = create_solver<0,128>(net_count, gs_threshold, use_specific);

View File

@ -70,17 +70,13 @@ inline void vec_mult_scalar (const int n, const double * RESTRICT v, const doubl
inline void vec_add_mult_scalar (const int n, const double * RESTRICT v, const double scalar, double * RESTRICT result)
{
for ( unsigned i = 0; i < n; i++ )
{
result[i] += scalar * v[i];
}
}
inline void vec_add_ip(const int n, const double * RESTRICT v, double * RESTRICT result)
{
for ( unsigned i = 0; i < n; i++ )
{
result[i] += v[i];
}
}
inline void vec_sub(const int n, const double * RESTRICT v1, const double * RESTRICT v2, double * RESTRICT result)
@ -89,13 +85,21 @@ inline void vec_sub(const int n, const double * RESTRICT v1, const double * REST
result[i] = v1[i] - v2[i];
}
inline void vec_scale (const int n, double * RESTRICT v, const double scalar)
{
for ( unsigned i = 0; i < n; i++ )
{
v[i] = scalar * v[i];
}
}
inline double vec_maxabs(const int n, const double * RESTRICT v)
{
double ret = 0.0;
for ( unsigned i = 0; i < n; i++ )
ret = std::max(ret, std::abs(v[i]));
return ret;
}
#endif /* MAT_CR_H_ */