mirror of
https://github.com/holub/mame
synced 2025-04-20 23:42:22 +03:00
netlist:
- Simply solver code. - Remove ATTR_HOT from solver code. - make virtual members protected
This commit is contained in:
parent
f852490d9e
commit
2e21930b27
@ -39,33 +39,31 @@ public:
|
||||
virtual void vsetup(analog_net_t::list_t &nets) override;
|
||||
virtual void reset() override { matrix_solver_t::reset(); }
|
||||
|
||||
ATTR_HOT inline unsigned N() const { if (m_N == 0) return m_dim; else return m_N; }
|
||||
inline unsigned N() const { if (m_N == 0) return m_dim; else return m_N; }
|
||||
|
||||
ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson);
|
||||
virtual int vsolve_non_dynamic(const bool newton_raphson) override;
|
||||
|
||||
protected:
|
||||
virtual void add_term(int net_idx, terminal_t *term) override;
|
||||
|
||||
ATTR_HOT virtual nl_double vsolve() override;
|
||||
|
||||
ATTR_HOT int solve_non_dynamic(const bool newton_raphson);
|
||||
ATTR_HOT void build_LE_A();
|
||||
ATTR_HOT void build_LE_RHS();
|
||||
ATTR_HOT void LE_solve();
|
||||
ATTR_HOT void LE_back_subst(nl_double * RESTRICT x);
|
||||
int solve_non_dynamic(const bool newton_raphson);
|
||||
void build_LE_A();
|
||||
void build_LE_RHS();
|
||||
void LE_solve();
|
||||
void LE_back_subst(nl_double * RESTRICT x);
|
||||
|
||||
/* Full LU back substitution, not used currently, in for future use */
|
||||
|
||||
ATTR_HOT void LE_back_subst_full(nl_double * RESTRICT x);
|
||||
void LE_back_subst_full(nl_double * RESTRICT x);
|
||||
|
||||
ATTR_HOT nl_double delta(const nl_double * RESTRICT V);
|
||||
ATTR_HOT void store(const nl_double * RESTRICT V);
|
||||
nl_double delta(const nl_double * RESTRICT V);
|
||||
void store(const nl_double * RESTRICT V);
|
||||
|
||||
/* bring the whole system to the current time
|
||||
* Don't schedule a new calculation time. The recalculation has to be
|
||||
* triggered by the caller after the netlist element was changed.
|
||||
*/
|
||||
ATTR_HOT nl_double compute_next_timestep();
|
||||
virtual nl_double compute_next_timestep() override;
|
||||
|
||||
|
||||
#if (NL_USE_DYNAMIC_ALLOCATION)
|
||||
@ -117,7 +115,7 @@ matrix_solver_direct_t<m_N, _storage_N>::~matrix_solver_direct_t()
|
||||
}
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT nl_double matrix_solver_direct_t<m_N, _storage_N>::compute_next_timestep()
|
||||
nl_double matrix_solver_direct_t<m_N, _storage_N>::compute_next_timestep()
|
||||
{
|
||||
nl_double new_solver_timestep = m_params.m_max_timestep;
|
||||
|
||||
@ -146,6 +144,8 @@ ATTR_HOT nl_double matrix_solver_direct_t<m_N, _storage_N>::compute_next_timeste
|
||||
|
||||
if (new_net_timestep < new_solver_timestep)
|
||||
new_solver_timestep = new_net_timestep;
|
||||
|
||||
m_last_V[k] = n->Q_Analog();
|
||||
}
|
||||
if (new_solver_timestep < m_params.m_min_timestep)
|
||||
new_solver_timestep = m_params.m_min_timestep;
|
||||
@ -191,7 +191,7 @@ ATTR_COLD void matrix_solver_direct_t<m_N, _storage_N>::vsetup(analog_net_t::lis
|
||||
m_rails_temp[k].clear();
|
||||
}
|
||||
|
||||
matrix_solver_t::setup(nets);
|
||||
matrix_solver_t::setup_base(nets);
|
||||
|
||||
for (unsigned k = 0; k < N(); k++)
|
||||
{
|
||||
@ -347,7 +347,7 @@ ATTR_COLD void matrix_solver_direct_t<m_N, _storage_N>::vsetup(analog_net_t::lis
|
||||
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::build_LE_A()
|
||||
void matrix_solver_direct_t<m_N, _storage_N>::build_LE_A()
|
||||
{
|
||||
const unsigned iN = N();
|
||||
for (unsigned k = 0; k < iN; k++)
|
||||
@ -376,7 +376,7 @@ ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::build_LE_A()
|
||||
}
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::build_LE_RHS()
|
||||
void matrix_solver_direct_t<m_N, _storage_N>::build_LE_RHS()
|
||||
{
|
||||
const unsigned iN = N();
|
||||
for (unsigned k = 0; k < iN; k++)
|
||||
@ -401,7 +401,7 @@ ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::build_LE_RHS()
|
||||
}
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::LE_solve()
|
||||
void matrix_solver_direct_t<m_N, _storage_N>::LE_solve()
|
||||
{
|
||||
const unsigned kN = N();
|
||||
|
||||
@ -481,7 +481,7 @@ ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::LE_solve()
|
||||
}
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::LE_back_subst(
|
||||
void matrix_solver_direct_t<m_N, _storage_N>::LE_back_subst(
|
||||
nl_double * RESTRICT x)
|
||||
{
|
||||
const unsigned kN = N();
|
||||
@ -517,7 +517,7 @@ ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::LE_back_subst(
|
||||
}
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::LE_back_subst_full(
|
||||
void matrix_solver_direct_t<m_N, _storage_N>::LE_back_subst_full(
|
||||
nl_double * RESTRICT x)
|
||||
{
|
||||
const unsigned kN = N();
|
||||
@ -551,7 +551,7 @@ ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::LE_back_subst_full(
|
||||
}
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT nl_double matrix_solver_direct_t<m_N, _storage_N>::delta(
|
||||
nl_double matrix_solver_direct_t<m_N, _storage_N>::delta(
|
||||
const nl_double * RESTRICT V)
|
||||
{
|
||||
/* FIXME: Ideally we should also include currents (RHS) here. This would
|
||||
@ -567,7 +567,7 @@ ATTR_HOT nl_double matrix_solver_direct_t<m_N, _storage_N>::delta(
|
||||
}
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::store(
|
||||
void matrix_solver_direct_t<m_N, _storage_N>::store(
|
||||
const nl_double * RESTRICT V)
|
||||
{
|
||||
for (unsigned i = 0, iN=N(); i < iN; i++)
|
||||
@ -576,19 +576,13 @@ ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::store(
|
||||
}
|
||||
}
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT nl_double matrix_solver_direct_t<m_N, _storage_N>::vsolve()
|
||||
{
|
||||
this->solve_base(this);
|
||||
return this->compute_next_timestep();
|
||||
}
|
||||
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT int matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic(ATTR_UNUSED const bool newton_raphson)
|
||||
int matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic(ATTR_UNUSED const bool newton_raphson)
|
||||
{
|
||||
nl_double new_V[_storage_N]; // = { 0.0 };
|
||||
|
||||
this->LE_solve();
|
||||
this->LE_back_subst(new_V);
|
||||
|
||||
if (newton_raphson)
|
||||
@ -607,7 +601,7 @@ ATTR_HOT int matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic(ATTR_UNU
|
||||
}
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT inline int matrix_solver_direct_t<m_N, _storage_N>::vsolve_non_dynamic(const bool newton_raphson)
|
||||
inline int matrix_solver_direct_t<m_N, _storage_N>::vsolve_non_dynamic(const bool newton_raphson)
|
||||
{
|
||||
this->build_LE_A();
|
||||
this->build_LE_RHS();
|
||||
@ -615,10 +609,7 @@ ATTR_HOT inline int matrix_solver_direct_t<m_N, _storage_N>::vsolve_non_dynamic(
|
||||
for (unsigned i=0, iN=N(); i < iN; i++)
|
||||
m_last_RHS[i] = RHS(i);
|
||||
|
||||
this->LE_solve();
|
||||
|
||||
this->m_stat_calculations++;
|
||||
|
||||
return this->solve_non_dynamic(newton_raphson);
|
||||
}
|
||||
|
||||
|
@ -20,23 +20,15 @@ public:
|
||||
matrix_solver_direct1_t(const solver_parameters_t *params)
|
||||
: matrix_solver_direct_t<1, 1>(params, 1)
|
||||
{}
|
||||
ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson);
|
||||
protected:
|
||||
ATTR_HOT virtual nl_double vsolve() override;
|
||||
private:
|
||||
virtual int vsolve_non_dynamic(const bool newton_raphson) override;
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// matrix_solver - Direct1
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
ATTR_HOT nl_double matrix_solver_direct1_t::vsolve()
|
||||
{
|
||||
solve_base<matrix_solver_direct1_t>(this);
|
||||
return this->compute_next_timestep();
|
||||
}
|
||||
|
||||
ATTR_HOT inline int matrix_solver_direct1_t::vsolve_non_dynamic(ATTR_UNUSED const bool newton_raphson)
|
||||
inline int matrix_solver_direct1_t::vsolve_non_dynamic(ATTR_UNUSED const bool newton_raphson)
|
||||
{
|
||||
analog_net_t *net = m_nets[0];
|
||||
this->build_LE_A();
|
||||
|
@ -20,23 +20,15 @@ public:
|
||||
matrix_solver_direct2_t(const solver_parameters_t *params)
|
||||
: matrix_solver_direct_t<2, 2>(params, 2)
|
||||
{}
|
||||
ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson);
|
||||
protected:
|
||||
ATTR_HOT virtual nl_double vsolve() override;
|
||||
private:
|
||||
virtual int vsolve_non_dynamic(const bool newton_raphson) override;
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
// matrix_solver - Direct2
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
ATTR_HOT nl_double matrix_solver_direct2_t::vsolve()
|
||||
{
|
||||
solve_base<matrix_solver_direct2_t>(this);
|
||||
return this->compute_next_timestep();
|
||||
}
|
||||
|
||||
ATTR_HOT inline int matrix_solver_direct2_t::vsolve_non_dynamic(ATTR_UNUSED const bool newton_raphson)
|
||||
inline int matrix_solver_direct2_t::vsolve_non_dynamic(ATTR_UNUSED const bool newton_raphson)
|
||||
{
|
||||
build_LE_A();
|
||||
build_LE_RHS();
|
||||
|
@ -33,18 +33,16 @@ public:
|
||||
virtual void vsetup(analog_net_t::list_t &nets) override;
|
||||
virtual void reset() override { matrix_solver_t::reset(); }
|
||||
|
||||
ATTR_HOT inline unsigned N() const { if (m_N == 0) return m_dim; else return m_N; }
|
||||
inline unsigned N() const { if (m_N == 0) return m_dim; else return m_N; }
|
||||
|
||||
ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson);
|
||||
inline int vsolve_non_dynamic(const bool newton_raphson);
|
||||
|
||||
protected:
|
||||
virtual void add_term(int net_idx, terminal_t *term) override;
|
||||
|
||||
ATTR_HOT virtual nl_double vsolve() override;
|
||||
|
||||
ATTR_HOT int solve_non_dynamic(const bool newton_raphson);
|
||||
ATTR_HOT void build_LE_A();
|
||||
ATTR_HOT void build_LE_RHS(nl_double * RESTRICT rhs);
|
||||
int solve_non_dynamic(const bool newton_raphson);
|
||||
void build_LE_A();
|
||||
void build_LE_RHS(nl_double * RESTRICT rhs);
|
||||
|
||||
template<unsigned k>
|
||||
void LEk()
|
||||
@ -68,7 +66,7 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
ATTR_HOT void LE_solve()
|
||||
void LE_solve()
|
||||
{
|
||||
const unsigned kN = N();
|
||||
unsigned sk = 1;
|
||||
@ -127,15 +125,15 @@ protected:
|
||||
}
|
||||
}
|
||||
}
|
||||
ATTR_HOT void LE_back_subst(nl_double * RESTRICT x);
|
||||
ATTR_HOT nl_double delta(const nl_double * RESTRICT V);
|
||||
ATTR_HOT void store(const nl_double * RESTRICT V);
|
||||
void LE_back_subst(nl_double * RESTRICT x);
|
||||
nl_double delta(const nl_double * RESTRICT V);
|
||||
void store(const nl_double * RESTRICT V);
|
||||
|
||||
/* bring the whole system to the current time
|
||||
* Don't schedule a new calculation time. The recalculation has to be
|
||||
* triggered by the caller after the netlist element was changed.
|
||||
*/
|
||||
ATTR_HOT nl_double compute_next_timestep();
|
||||
nl_double compute_next_timestep();
|
||||
|
||||
template <typename T1, typename T2>
|
||||
inline nl_ext_double &A(const T1 r, const T2 c) { return m_A[r][c]; }
|
||||
@ -171,7 +169,7 @@ matrix_solver_direct_t<m_N, _storage_N>::~matrix_solver_direct_t()
|
||||
}
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT nl_double matrix_solver_direct_t<m_N, _storage_N>::compute_next_timestep()
|
||||
nl_double matrix_solver_direct_t<m_N, _storage_N>::compute_next_timestep()
|
||||
{
|
||||
nl_double new_solver_timestep = m_params.m_max_timestep;
|
||||
|
||||
@ -245,7 +243,7 @@ ATTR_COLD void matrix_solver_direct_t<m_N, _storage_N>::vsetup(analog_net_t::lis
|
||||
m_rails_temp[k].clear();
|
||||
}
|
||||
|
||||
matrix_solver_t::setup(nets);
|
||||
matrix_solver_t::setup_base(nets);
|
||||
|
||||
for (unsigned k = 0; k < N(); k++)
|
||||
{
|
||||
@ -373,7 +371,7 @@ ATTR_COLD void matrix_solver_direct_t<m_N, _storage_N>::vsetup(analog_net_t::lis
|
||||
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::build_LE_A()
|
||||
void matrix_solver_direct_t<m_N, _storage_N>::build_LE_A()
|
||||
{
|
||||
const unsigned iN = N();
|
||||
for (unsigned k = 0; k < iN; k++)
|
||||
@ -399,7 +397,7 @@ ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::build_LE_A()
|
||||
}
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::build_LE_RHS(nl_double * RESTRICT rhs)
|
||||
void matrix_solver_direct_t<m_N, _storage_N>::build_LE_RHS(nl_double * RESTRICT rhs)
|
||||
{
|
||||
const unsigned iN = N();
|
||||
for (unsigned k = 0; k < iN; k++)
|
||||
@ -427,7 +425,7 @@ ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::build_LE_RHS(nl_double *
|
||||
#else
|
||||
// Crout algo
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::LE_solve()
|
||||
void matrix_solver_direct_t<m_N, _storage_N>::LE_solve()
|
||||
{
|
||||
const unsigned kN = N();
|
||||
|
||||
@ -509,7 +507,7 @@ ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::LE_solve()
|
||||
#endif
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::LE_back_subst(
|
||||
void matrix_solver_direct_t<m_N, _storage_N>::LE_back_subst(
|
||||
nl_double * RESTRICT x)
|
||||
{
|
||||
const unsigned kN = N();
|
||||
@ -543,7 +541,7 @@ ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::LE_back_subst(
|
||||
}
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT nl_double matrix_solver_direct_t<m_N, _storage_N>::delta(
|
||||
nl_double matrix_solver_direct_t<m_N, _storage_N>::delta(
|
||||
const nl_double * RESTRICT V)
|
||||
{
|
||||
/* FIXME: Ideally we should also include currents (RHS) here. This would
|
||||
@ -559,7 +557,7 @@ ATTR_HOT nl_double matrix_solver_direct_t<m_N, _storage_N>::delta(
|
||||
}
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::store(
|
||||
void matrix_solver_direct_t<m_N, _storage_N>::store(
|
||||
const nl_double * RESTRICT V)
|
||||
{
|
||||
for (unsigned i = 0, iN=N(); i < iN; i++)
|
||||
@ -568,16 +566,9 @@ ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::store(
|
||||
}
|
||||
}
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT nl_double matrix_solver_direct_t<m_N, _storage_N>::vsolve()
|
||||
{
|
||||
this->solve_base(this);
|
||||
return this->compute_next_timestep();
|
||||
}
|
||||
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT int matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic(ATTR_UNUSED const bool newton_raphson)
|
||||
int matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic(ATTR_UNUSED const bool newton_raphson)
|
||||
{
|
||||
nl_double new_V[_storage_N]; // = { 0.0 };
|
||||
|
||||
@ -599,7 +590,7 @@ ATTR_HOT int matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic(ATTR_UNU
|
||||
}
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT inline int matrix_solver_direct_t<m_N, _storage_N>::vsolve_non_dynamic(const bool newton_raphson)
|
||||
inline int matrix_solver_direct_t<m_N, _storage_N>::vsolve_non_dynamic(const bool newton_raphson)
|
||||
{
|
||||
this->build_LE_A();
|
||||
this->build_LE_RHS(m_last_RHS);
|
||||
@ -607,8 +598,6 @@ ATTR_HOT inline int matrix_solver_direct_t<m_N, _storage_N>::vsolve_non_dynamic(
|
||||
for (unsigned i=0, iN=N(); i < iN; i++)
|
||||
m_RHS[i] = m_last_RHS[i];
|
||||
|
||||
this->LE_solve();
|
||||
|
||||
return this->solve_non_dynamic(newton_raphson);
|
||||
}
|
||||
|
||||
|
@ -54,9 +54,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void vsetup(analog_net_t::list_t &nets) override;
|
||||
ATTR_HOT virtual int vsolve_non_dynamic(const bool newton_raphson);
|
||||
protected:
|
||||
ATTR_HOT virtual nl_double vsolve() override;
|
||||
virtual int vsolve_non_dynamic(const bool newton_raphson) override;
|
||||
|
||||
private:
|
||||
|
||||
@ -126,14 +124,7 @@ void matrix_solver_GMRES_t<m_N, _storage_N>::vsetup(analog_net_t::list_t &nets)
|
||||
}
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT nl_double matrix_solver_GMRES_t<m_N, _storage_N>::vsolve()
|
||||
{
|
||||
this->solve_base(this);
|
||||
return this->compute_next_timestep();
|
||||
}
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT inline int matrix_solver_GMRES_t<m_N, _storage_N>::vsolve_non_dynamic(const bool newton_raphson)
|
||||
int matrix_solver_GMRES_t<m_N, _storage_N>::vsolve_non_dynamic(const bool newton_raphson)
|
||||
{
|
||||
const unsigned iN = this->N();
|
||||
|
||||
|
@ -33,9 +33,7 @@ public:
|
||||
virtual ~matrix_solver_SOR_t() {}
|
||||
|
||||
virtual void vsetup(analog_net_t::list_t &nets) override;
|
||||
ATTR_HOT virtual int vsolve_non_dynamic(const bool newton_raphson);
|
||||
protected:
|
||||
ATTR_HOT virtual nl_double vsolve() override;
|
||||
virtual int vsolve_non_dynamic(const bool newton_raphson) override;
|
||||
|
||||
private:
|
||||
nl_double m_lp_fact;
|
||||
@ -54,14 +52,7 @@ void matrix_solver_SOR_t<m_N, _storage_N>::vsetup(analog_net_t::list_t &nets)
|
||||
}
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT nl_double matrix_solver_SOR_t<m_N, _storage_N>::vsolve()
|
||||
{
|
||||
this->solve_base(this);
|
||||
return this->compute_next_timestep();
|
||||
}
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT inline int matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dynamic(const bool newton_raphson)
|
||||
int matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dynamic(const bool newton_raphson)
|
||||
{
|
||||
const unsigned iN = this->N();
|
||||
bool resched = false;
|
||||
|
@ -37,9 +37,7 @@ public:
|
||||
|
||||
virtual void vsetup(analog_net_t::list_t &nets) override;
|
||||
|
||||
ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson);
|
||||
protected:
|
||||
ATTR_HOT virtual nl_double vsolve() override;
|
||||
virtual int vsolve_non_dynamic(const bool newton_raphson) override;
|
||||
|
||||
private:
|
||||
nl_double m_Vdelta[_storage_N];
|
||||
@ -65,9 +63,10 @@ void matrix_solver_SOR_mat_t<m_N, _storage_N>::vsetup(analog_net_t::list_t &nets
|
||||
this->save(NLNAME(m_Vdelta));
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
//FIXME: move to solve_base
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT nl_double matrix_solver_SOR_mat_t<m_N, _storage_N>::vsolve()
|
||||
nl_double matrix_solver_SOR_mat_t<m_N, _storage_N>::vsolve()
|
||||
{
|
||||
/*
|
||||
* enable linear prediction on first newton pass
|
||||
@ -111,9 +110,10 @@ ATTR_HOT nl_double matrix_solver_SOR_mat_t<m_N, _storage_N>::vsolve()
|
||||
|
||||
return this->compute_next_timestep();
|
||||
}
|
||||
#endif
|
||||
|
||||
template <unsigned m_N, unsigned _storage_N>
|
||||
ATTR_HOT inline int matrix_solver_SOR_mat_t<m_N, _storage_N>::vsolve_non_dynamic(const bool newton_raphson)
|
||||
int matrix_solver_SOR_mat_t<m_N, _storage_N>::vsolve_non_dynamic(const bool newton_raphson)
|
||||
{
|
||||
/* The matrix based code looks a lot nicer but actually is 30% slower than
|
||||
* the optimized code which works directly on the data structures.
|
||||
@ -204,7 +204,6 @@ ATTR_HOT inline int matrix_solver_SOR_mat_t<m_N, _storage_N>::vsolve_non_dynamic
|
||||
//this->netlist().warning("Falling back to direct solver .. Consider increasing RESCHED_LOOPS");
|
||||
this->m_gs_fail++;
|
||||
|
||||
this->LE_solve();
|
||||
return matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic(newton_raphson);
|
||||
}
|
||||
else {
|
||||
|
@ -105,7 +105,7 @@ ATTR_COLD matrix_solver_t::~matrix_solver_t()
|
||||
m_inps.clear_and_free();
|
||||
}
|
||||
|
||||
ATTR_COLD void matrix_solver_t::setup(analog_net_t::list_t &nets)
|
||||
ATTR_COLD void matrix_solver_t::setup_base(analog_net_t::list_t &nets)
|
||||
{
|
||||
log().debug("New solver setup\n");
|
||||
|
||||
@ -185,14 +185,14 @@ ATTR_COLD void matrix_solver_t::setup(analog_net_t::list_t &nets)
|
||||
}
|
||||
|
||||
|
||||
ATTR_HOT void matrix_solver_t::update_inputs()
|
||||
void matrix_solver_t::update_inputs()
|
||||
{
|
||||
// avoid recursive calls. Inputs are updated outside this call
|
||||
for (std::size_t i=0; i<m_inps.size(); i++)
|
||||
m_inps[i]->set_Q(m_inps[i]->m_proxied_net->Q_Analog());
|
||||
}
|
||||
|
||||
ATTR_HOT void matrix_solver_t::update_dynamic()
|
||||
void matrix_solver_t::update_dynamic()
|
||||
{
|
||||
/* update all non-linear devices */
|
||||
for (std::size_t i=0; i < m_dynamic_devices.size(); i++)
|
||||
@ -236,15 +236,14 @@ ATTR_COLD void matrix_solver_t::update_forced()
|
||||
m_Q_sync.net().reschedule_in_queue(netlist_time::from_double(m_params.m_min_timestep));
|
||||
}
|
||||
|
||||
ATTR_HOT void matrix_solver_t::step(const netlist_time delta)
|
||||
void matrix_solver_t::step(const netlist_time delta)
|
||||
{
|
||||
const nl_double dd = delta.as_double();
|
||||
for (std::size_t k=0; k < m_step_devices.size(); k++)
|
||||
m_step_devices[k]->step_time(dd);
|
||||
}
|
||||
|
||||
template<class C >
|
||||
void matrix_solver_t::solve_base(C *p)
|
||||
nl_double matrix_solver_t::solve_base()
|
||||
{
|
||||
m_stat_vsolver_calls++;
|
||||
if (is_dynamic())
|
||||
@ -255,7 +254,7 @@ void matrix_solver_t::solve_base(C *p)
|
||||
{
|
||||
update_dynamic();
|
||||
// Gauss-Seidel will revert to Gaussian elemination if steps exceeded.
|
||||
this_resched = p->vsolve_non_dynamic(true);
|
||||
this_resched = this->vsolve_non_dynamic(true);
|
||||
newton_loops++;
|
||||
} while (this_resched > 1 && newton_loops < m_params.m_nr_loops);
|
||||
|
||||
@ -269,11 +268,12 @@ void matrix_solver_t::solve_base(C *p)
|
||||
}
|
||||
else
|
||||
{
|
||||
p->vsolve_non_dynamic(false);
|
||||
this->vsolve_non_dynamic(false);
|
||||
}
|
||||
return this->compute_next_timestep();
|
||||
}
|
||||
|
||||
ATTR_HOT nl_double matrix_solver_t::solve()
|
||||
nl_double matrix_solver_t::solve()
|
||||
{
|
||||
const netlist_time now = netlist().time();
|
||||
const netlist_time delta = now - m_last_step;
|
||||
@ -289,7 +289,7 @@ ATTR_HOT nl_double matrix_solver_t::solve()
|
||||
|
||||
step(delta);
|
||||
|
||||
const nl_double next_time_step = vsolve();
|
||||
const nl_double next_time_step = solve_base();
|
||||
|
||||
update_inputs();
|
||||
return next_time_step;
|
||||
@ -358,7 +358,7 @@ NETLIB_START(solver)
|
||||
|
||||
/* automatic time step */
|
||||
register_param("DYNAMIC_TS", m_dynamic, 0);
|
||||
register_param("LTE", m_lte, 5e-5); // diff/timestep
|
||||
register_param("DYNAMIC_LTE", m_lte, 5e-5); // diff/timestep
|
||||
register_param("MIN_TIMESTEP", m_min_timestep, 1e-6); // nl_double timestep resolution
|
||||
|
||||
register_param("LOG_STATS", m_log_stats, 1); // nl_double timestep resolution
|
||||
@ -618,7 +618,7 @@ ATTR_COLD void NETLIB_NAME(solver)::post_start()
|
||||
|
||||
register_sub(pfmt("Solver_{1}")(m_mat_solvers.size()), *ms);
|
||||
|
||||
ms->vsetup(grp);
|
||||
ms->setup(grp);
|
||||
|
||||
m_mat_solvers.push_back(ms);
|
||||
|
||||
|
@ -68,14 +68,14 @@ class terms_t
|
||||
|
||||
ATTR_COLD void add(terminal_t *term, int net_other, bool sorted);
|
||||
|
||||
ATTR_HOT inline unsigned count() { return m_term.size(); }
|
||||
inline unsigned count() { return m_term.size(); }
|
||||
|
||||
ATTR_HOT inline terminal_t **terms() { return m_term.data(); }
|
||||
ATTR_HOT inline int *net_other() { return m_net_other.data(); }
|
||||
ATTR_HOT inline nl_double *gt() { return m_gt.data(); }
|
||||
ATTR_HOT inline nl_double *go() { return m_go.data(); }
|
||||
ATTR_HOT inline nl_double *Idr() { return m_Idr.data(); }
|
||||
ATTR_HOT inline nl_double **other_curanalog() { return m_other_curanalog.data(); }
|
||||
inline terminal_t **terms() { return m_term.data(); }
|
||||
inline int *net_other() { return m_net_other.data(); }
|
||||
inline nl_double *gt() { return m_gt.data(); }
|
||||
inline nl_double *go() { return m_go.data(); }
|
||||
inline nl_double *Idr() { return m_Idr.data(); }
|
||||
inline nl_double **other_curanalog() { return m_other_curanalog.data(); }
|
||||
|
||||
ATTR_COLD void set_pointers();
|
||||
|
||||
@ -108,43 +108,42 @@ public:
|
||||
ATTR_COLD matrix_solver_t(const eSolverType type, const solver_parameters_t *params);
|
||||
virtual ~matrix_solver_t();
|
||||
|
||||
virtual void vsetup(analog_net_t::list_t &nets) = 0;
|
||||
void setup(analog_net_t::list_t &nets) { vsetup(nets); }
|
||||
|
||||
template<class C>
|
||||
void solve_base(C *p);
|
||||
nl_double solve_base();
|
||||
|
||||
ATTR_HOT nl_double solve();
|
||||
nl_double solve();
|
||||
|
||||
ATTR_HOT inline bool is_dynamic() { return m_dynamic_devices.size() > 0; }
|
||||
ATTR_HOT inline bool is_timestep() { return m_step_devices.size() > 0; }
|
||||
inline bool is_dynamic() const { return m_dynamic_devices.size() > 0; }
|
||||
inline bool is_timestep() const { return m_step_devices.size() > 0; }
|
||||
|
||||
ATTR_HOT void update_forced();
|
||||
ATTR_HOT inline void update_after(const netlist_time after)
|
||||
void update_forced();
|
||||
void update_after(const netlist_time after)
|
||||
{
|
||||
m_Q_sync.net().reschedule_in_queue(after);
|
||||
}
|
||||
|
||||
/* netdevice functions */
|
||||
ATTR_HOT virtual void update() override;
|
||||
virtual void update() override;
|
||||
virtual void start() override;
|
||||
virtual void reset() override;
|
||||
|
||||
ATTR_COLD int get_net_idx(net_t *net);
|
||||
|
||||
inline eSolverType type() const { return m_type; }
|
||||
eSolverType type() const { return m_type; }
|
||||
plog_base<NL_DEBUG> &log() { return netlist().log(); }
|
||||
|
||||
virtual void log_stats();
|
||||
|
||||
protected:
|
||||
|
||||
ATTR_COLD void setup(analog_net_t::list_t &nets);
|
||||
ATTR_HOT void update_dynamic();
|
||||
|
||||
// should return next time step
|
||||
ATTR_HOT virtual nl_double vsolve() = 0;
|
||||
ATTR_COLD void setup_base(analog_net_t::list_t &nets);
|
||||
void update_dynamic();
|
||||
|
||||
virtual void add_term(int net_idx, terminal_t *term) = 0;
|
||||
virtual void vsetup(analog_net_t::list_t &nets) = 0;
|
||||
virtual int vsolve_non_dynamic(const bool newton_raphson) = 0;
|
||||
virtual nl_double compute_next_timestep() = 0;
|
||||
|
||||
pvector_t<analog_net_t *> m_nets;
|
||||
pvector_t<analog_output_t *> m_inps;
|
||||
@ -157,7 +156,7 @@ protected:
|
||||
|
||||
const solver_parameters_t &m_params;
|
||||
|
||||
ATTR_HOT inline nl_double current_timestep() { return m_cur_ts; }
|
||||
inline nl_double current_timestep() { return m_cur_ts; }
|
||||
private:
|
||||
|
||||
netlist_time m_last_step;
|
||||
@ -168,9 +167,9 @@ private:
|
||||
logic_input_t m_fb_sync;
|
||||
logic_output_t m_Q_sync;
|
||||
|
||||
ATTR_HOT void step(const netlist_time delta);
|
||||
void step(const netlist_time delta);
|
||||
|
||||
ATTR_HOT void update_inputs();
|
||||
void update_inputs();
|
||||
|
||||
const eSolverType m_type;
|
||||
};
|
||||
@ -188,13 +187,13 @@ public:
|
||||
ATTR_COLD void post_start();
|
||||
ATTR_COLD void stop() override;
|
||||
|
||||
ATTR_HOT inline nl_double gmin() { return m_gmin.Value(); }
|
||||
inline nl_double gmin() { return m_gmin.Value(); }
|
||||
|
||||
protected:
|
||||
ATTR_HOT void update() override;
|
||||
ATTR_HOT void start() override;
|
||||
ATTR_HOT void reset() override;
|
||||
ATTR_HOT void update_param() override;
|
||||
void update() override;
|
||||
void start() override;
|
||||
void reset() override;
|
||||
void update_param() override;
|
||||
|
||||
logic_input_t m_fb_step;
|
||||
logic_output_t m_Q_step;
|
||||
|
Loading…
Reference in New Issue
Block a user