- Simply solver code.
- Remove ATTR_HOT from solver code.
- make virtual members protected
This commit is contained in:
couriersud 2016-03-26 17:59:25 +01:00
parent f852490d9e
commit 2e21930b27
9 changed files with 102 additions and 158 deletions

View File

@ -39,33 +39,31 @@ public:
virtual void vsetup(analog_net_t::list_t &nets) override; virtual void vsetup(analog_net_t::list_t &nets) override;
virtual void reset() override { matrix_solver_t::reset(); } 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: protected:
virtual void add_term(int net_idx, terminal_t *term) override; virtual void add_term(int net_idx, terminal_t *term) override;
ATTR_HOT virtual nl_double vsolve() override; int solve_non_dynamic(const bool newton_raphson);
void build_LE_A();
ATTR_HOT int solve_non_dynamic(const bool newton_raphson); void build_LE_RHS();
ATTR_HOT void build_LE_A(); void LE_solve();
ATTR_HOT void build_LE_RHS(); void LE_back_subst(nl_double * RESTRICT x);
ATTR_HOT void LE_solve();
ATTR_HOT void LE_back_subst(nl_double * RESTRICT x);
/* Full LU back substitution, not used currently, in for future use */ /* 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); nl_double delta(const nl_double * RESTRICT V);
ATTR_HOT void store(const nl_double * RESTRICT V); void store(const nl_double * RESTRICT V);
/* bring the whole system to the current time /* bring the whole system to the current time
* Don't schedule a new calculation time. The recalculation has to be * Don't schedule a new calculation time. The recalculation has to be
* triggered by the caller after the netlist element was changed. * 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) #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> 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; 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) if (new_net_timestep < new_solver_timestep)
new_solver_timestep = new_net_timestep; new_solver_timestep = new_net_timestep;
m_last_V[k] = n->Q_Analog();
} }
if (new_solver_timestep < m_params.m_min_timestep) if (new_solver_timestep < m_params.m_min_timestep)
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(); m_rails_temp[k].clear();
} }
matrix_solver_t::setup(nets); matrix_solver_t::setup_base(nets);
for (unsigned k = 0; k < N(); k++) 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> 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(); const unsigned iN = N();
for (unsigned k = 0; k < iN; k++) 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> 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(); const unsigned iN = N();
for (unsigned k = 0; k < iN; k++) 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> 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(); 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> 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) nl_double * RESTRICT x)
{ {
const unsigned kN = N(); 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> 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) nl_double * RESTRICT x)
{ {
const unsigned kN = N(); 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> 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) const nl_double * RESTRICT V)
{ {
/* FIXME: Ideally we should also include currents (RHS) here. This would /* 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> 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) const nl_double * RESTRICT V)
{ {
for (unsigned i = 0, iN=N(); i < iN; i++) 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> 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 }; nl_double new_V[_storage_N]; // = { 0.0 };
this->LE_solve();
this->LE_back_subst(new_V); this->LE_back_subst(new_V);
if (newton_raphson) 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> 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_A();
this->build_LE_RHS(); 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++) for (unsigned i=0, iN=N(); i < iN; i++)
m_last_RHS[i] = RHS(i); m_last_RHS[i] = RHS(i);
this->LE_solve();
this->m_stat_calculations++; this->m_stat_calculations++;
return this->solve_non_dynamic(newton_raphson); return this->solve_non_dynamic(newton_raphson);
} }

View File

@ -20,23 +20,15 @@ public:
matrix_solver_direct1_t(const solver_parameters_t *params) matrix_solver_direct1_t(const solver_parameters_t *params)
: matrix_solver_direct_t<1, 1>(params, 1) : matrix_solver_direct_t<1, 1>(params, 1)
{} {}
ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson); virtual int vsolve_non_dynamic(const bool newton_raphson) override;
protected:
ATTR_HOT virtual nl_double vsolve() override;
private:
}; };
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// matrix_solver - Direct1 // matrix_solver - Direct1
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
ATTR_HOT nl_double matrix_solver_direct1_t::vsolve() inline int matrix_solver_direct1_t::vsolve_non_dynamic(ATTR_UNUSED const bool newton_raphson)
{
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)
{ {
analog_net_t *net = m_nets[0]; analog_net_t *net = m_nets[0];
this->build_LE_A(); this->build_LE_A();

View File

@ -20,23 +20,15 @@ public:
matrix_solver_direct2_t(const solver_parameters_t *params) matrix_solver_direct2_t(const solver_parameters_t *params)
: matrix_solver_direct_t<2, 2>(params, 2) : matrix_solver_direct_t<2, 2>(params, 2)
{} {}
ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson); virtual int vsolve_non_dynamic(const bool newton_raphson) override;
protected:
ATTR_HOT virtual nl_double vsolve() override;
private:
}; };
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// matrix_solver - Direct2 // matrix_solver - Direct2
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
ATTR_HOT nl_double matrix_solver_direct2_t::vsolve() inline int matrix_solver_direct2_t::vsolve_non_dynamic(ATTR_UNUSED const bool newton_raphson)
{
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)
{ {
build_LE_A(); build_LE_A();
build_LE_RHS(); build_LE_RHS();

View File

@ -33,18 +33,16 @@ public:
virtual void vsetup(analog_net_t::list_t &nets) override; virtual void vsetup(analog_net_t::list_t &nets) override;
virtual void reset() override { matrix_solver_t::reset(); } 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: protected:
virtual void add_term(int net_idx, terminal_t *term) override; virtual void add_term(int net_idx, terminal_t *term) override;
ATTR_HOT virtual nl_double vsolve() override; int solve_non_dynamic(const bool newton_raphson);
void build_LE_A();
ATTR_HOT int solve_non_dynamic(const bool newton_raphson); void build_LE_RHS(nl_double * RESTRICT rhs);
ATTR_HOT void build_LE_A();
ATTR_HOT void build_LE_RHS(nl_double * RESTRICT rhs);
template<unsigned k> template<unsigned k>
void LEk() void LEk()
@ -68,7 +66,7 @@ protected:
} }
} }
ATTR_HOT void LE_solve() void LE_solve()
{ {
const unsigned kN = N(); const unsigned kN = N();
unsigned sk = 1; unsigned sk = 1;
@ -127,15 +125,15 @@ protected:
} }
} }
} }
ATTR_HOT void LE_back_subst(nl_double * RESTRICT x); void LE_back_subst(nl_double * RESTRICT x);
ATTR_HOT nl_double delta(const nl_double * RESTRICT V); nl_double delta(const nl_double * RESTRICT V);
ATTR_HOT void store(const nl_double * RESTRICT V); void store(const nl_double * RESTRICT V);
/* bring the whole system to the current time /* bring the whole system to the current time
* Don't schedule a new calculation time. The recalculation has to be * Don't schedule a new calculation time. The recalculation has to be
* triggered by the caller after the netlist element was changed. * 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> template <typename T1, typename T2>
inline nl_ext_double &A(const T1 r, const T2 c) { return m_A[r][c]; } 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> 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; 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(); m_rails_temp[k].clear();
} }
matrix_solver_t::setup(nets); matrix_solver_t::setup_base(nets);
for (unsigned k = 0; k < N(); k++) 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> 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(); const unsigned iN = N();
for (unsigned k = 0; k < iN; k++) 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> 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(); const unsigned iN = N();
for (unsigned k = 0; k < iN; k++) 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 #else
// Crout algo // Crout algo
template <unsigned m_N, unsigned _storage_N> 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(); const unsigned kN = N();
@ -509,7 +507,7 @@ ATTR_HOT void matrix_solver_direct_t<m_N, _storage_N>::LE_solve()
#endif #endif
template <unsigned m_N, unsigned _storage_N> 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) nl_double * RESTRICT x)
{ {
const unsigned kN = N(); 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> 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) const nl_double * RESTRICT V)
{ {
/* FIXME: Ideally we should also include currents (RHS) here. This would /* 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> 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) const nl_double * RESTRICT V)
{ {
for (unsigned i = 0, iN=N(); i < iN; i++) 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> 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 }; 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> 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_A();
this->build_LE_RHS(m_last_RHS); 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++) for (unsigned i=0, iN=N(); i < iN; i++)
m_RHS[i] = m_last_RHS[i]; m_RHS[i] = m_last_RHS[i];
this->LE_solve();
return this->solve_non_dynamic(newton_raphson); return this->solve_non_dynamic(newton_raphson);
} }

View File

@ -54,9 +54,7 @@ public:
} }
virtual void vsetup(analog_net_t::list_t &nets) override; virtual void vsetup(analog_net_t::list_t &nets) override;
ATTR_HOT virtual int vsolve_non_dynamic(const bool newton_raphson); virtual int vsolve_non_dynamic(const bool newton_raphson) override;
protected:
ATTR_HOT virtual nl_double vsolve() override;
private: 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> template <unsigned m_N, unsigned _storage_N>
ATTR_HOT nl_double matrix_solver_GMRES_t<m_N, _storage_N>::vsolve() int matrix_solver_GMRES_t<m_N, _storage_N>::vsolve_non_dynamic(const bool newton_raphson)
{
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)
{ {
const unsigned iN = this->N(); const unsigned iN = this->N();

View File

@ -33,9 +33,7 @@ public:
virtual ~matrix_solver_SOR_t() {} virtual ~matrix_solver_SOR_t() {}
virtual void vsetup(analog_net_t::list_t &nets) override; virtual void vsetup(analog_net_t::list_t &nets) override;
ATTR_HOT virtual int vsolve_non_dynamic(const bool newton_raphson); virtual int vsolve_non_dynamic(const bool newton_raphson) override;
protected:
ATTR_HOT virtual nl_double vsolve() override;
private: private:
nl_double m_lp_fact; 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> template <unsigned m_N, unsigned _storage_N>
ATTR_HOT nl_double matrix_solver_SOR_t<m_N, _storage_N>::vsolve() int matrix_solver_SOR_t<m_N, _storage_N>::vsolve_non_dynamic(const bool newton_raphson)
{
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)
{ {
const unsigned iN = this->N(); const unsigned iN = this->N();
bool resched = false; bool resched = false;

View File

@ -37,9 +37,7 @@ public:
virtual void vsetup(analog_net_t::list_t &nets) override; virtual void vsetup(analog_net_t::list_t &nets) override;
ATTR_HOT inline int vsolve_non_dynamic(const bool newton_raphson); virtual int vsolve_non_dynamic(const bool newton_raphson) override;
protected:
ATTR_HOT virtual nl_double vsolve() override;
private: private:
nl_double m_Vdelta[_storage_N]; 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)); this->save(NLNAME(m_Vdelta));
} }
#if 0
//FIXME: move to solve_base
template <unsigned m_N, unsigned _storage_N> 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 * 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(); return this->compute_next_timestep();
} }
#endif
template <unsigned m_N, unsigned _storage_N> 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 matrix based code looks a lot nicer but actually is 30% slower than
* the optimized code which works directly on the data structures. * 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->netlist().warning("Falling back to direct solver .. Consider increasing RESCHED_LOOPS");
this->m_gs_fail++; this->m_gs_fail++;
this->LE_solve();
return matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic(newton_raphson); return matrix_solver_direct_t<m_N, _storage_N>::solve_non_dynamic(newton_raphson);
} }
else { else {

View File

@ -105,7 +105,7 @@ ATTR_COLD matrix_solver_t::~matrix_solver_t()
m_inps.clear_and_free(); 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"); 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 // avoid recursive calls. Inputs are updated outside this call
for (std::size_t i=0; i<m_inps.size(); i++) for (std::size_t i=0; i<m_inps.size(); i++)
m_inps[i]->set_Q(m_inps[i]->m_proxied_net->Q_Analog()); 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 */ /* update all non-linear devices */
for (std::size_t i=0; i < m_dynamic_devices.size(); i++) 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)); 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(); const nl_double dd = delta.as_double();
for (std::size_t k=0; k < m_step_devices.size(); k++) for (std::size_t k=0; k < m_step_devices.size(); k++)
m_step_devices[k]->step_time(dd); m_step_devices[k]->step_time(dd);
} }
template<class C > nl_double matrix_solver_t::solve_base()
void matrix_solver_t::solve_base(C *p)
{ {
m_stat_vsolver_calls++; m_stat_vsolver_calls++;
if (is_dynamic()) if (is_dynamic())
@ -255,7 +254,7 @@ void matrix_solver_t::solve_base(C *p)
{ {
update_dynamic(); update_dynamic();
// Gauss-Seidel will revert to Gaussian elemination if steps exceeded. // 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++; newton_loops++;
} while (this_resched > 1 && newton_loops < m_params.m_nr_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 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 now = netlist().time();
const netlist_time delta = now - m_last_step; const netlist_time delta = now - m_last_step;
@ -289,7 +289,7 @@ ATTR_HOT nl_double matrix_solver_t::solve()
step(delta); step(delta);
const nl_double next_time_step = vsolve(); const nl_double next_time_step = solve_base();
update_inputs(); update_inputs();
return next_time_step; return next_time_step;
@ -358,7 +358,7 @@ NETLIB_START(solver)
/* automatic time step */ /* automatic time step */
register_param("DYNAMIC_TS", m_dynamic, 0); 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("MIN_TIMESTEP", m_min_timestep, 1e-6); // nl_double timestep resolution
register_param("LOG_STATS", m_log_stats, 1); // 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); register_sub(pfmt("Solver_{1}")(m_mat_solvers.size()), *ms);
ms->vsetup(grp); ms->setup(grp);
m_mat_solvers.push_back(ms); m_mat_solvers.push_back(ms);

View File

@ -68,14 +68,14 @@ class terms_t
ATTR_COLD void add(terminal_t *term, int net_other, bool sorted); 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(); } inline terminal_t **terms() { return m_term.data(); }
ATTR_HOT inline int *net_other() { return m_net_other.data(); } inline int *net_other() { return m_net_other.data(); }
ATTR_HOT inline nl_double *gt() { return m_gt.data(); } inline nl_double *gt() { return m_gt.data(); }
ATTR_HOT inline nl_double *go() { return m_go.data(); } inline nl_double *go() { return m_go.data(); }
ATTR_HOT inline nl_double *Idr() { return m_Idr.data(); } inline nl_double *Idr() { return m_Idr.data(); }
ATTR_HOT inline nl_double **other_curanalog() { return m_other_curanalog.data(); } inline nl_double **other_curanalog() { return m_other_curanalog.data(); }
ATTR_COLD void set_pointers(); ATTR_COLD void set_pointers();
@ -108,43 +108,42 @@ public:
ATTR_COLD matrix_solver_t(const eSolverType type, const solver_parameters_t *params); ATTR_COLD matrix_solver_t(const eSolverType type, const solver_parameters_t *params);
virtual ~matrix_solver_t(); 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> nl_double solve_base();
void solve_base(C *p);
ATTR_HOT nl_double solve(); nl_double solve();
ATTR_HOT inline bool is_dynamic() { return m_dynamic_devices.size() > 0; } inline bool is_dynamic() const { return m_dynamic_devices.size() > 0; }
ATTR_HOT inline bool is_timestep() { return m_step_devices.size() > 0; } inline bool is_timestep() const { return m_step_devices.size() > 0; }
ATTR_HOT void update_forced(); void update_forced();
ATTR_HOT inline void update_after(const netlist_time after) void update_after(const netlist_time after)
{ {
m_Q_sync.net().reschedule_in_queue(after); m_Q_sync.net().reschedule_in_queue(after);
} }
/* netdevice functions */ /* netdevice functions */
ATTR_HOT virtual void update() override; virtual void update() override;
virtual void start() override; virtual void start() override;
virtual void reset() override; virtual void reset() override;
ATTR_COLD int get_net_idx(net_t *net); 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(); } plog_base<NL_DEBUG> &log() { return netlist().log(); }
virtual void log_stats(); virtual void log_stats();
protected: protected:
ATTR_COLD void setup(analog_net_t::list_t &nets); ATTR_COLD void setup_base(analog_net_t::list_t &nets);
ATTR_HOT void update_dynamic(); void update_dynamic();
// should return next time step
ATTR_HOT virtual nl_double vsolve() = 0;
virtual void add_term(int net_idx, terminal_t *term) = 0; 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_net_t *> m_nets;
pvector_t<analog_output_t *> m_inps; pvector_t<analog_output_t *> m_inps;
@ -157,7 +156,7 @@ protected:
const solver_parameters_t &m_params; 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: private:
netlist_time m_last_step; netlist_time m_last_step;
@ -168,9 +167,9 @@ private:
logic_input_t m_fb_sync; logic_input_t m_fb_sync;
logic_output_t m_Q_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; const eSolverType m_type;
}; };
@ -188,13 +187,13 @@ public:
ATTR_COLD void post_start(); ATTR_COLD void post_start();
ATTR_COLD void stop() override; ATTR_COLD void stop() override;
ATTR_HOT inline nl_double gmin() { return m_gmin.Value(); } inline nl_double gmin() { return m_gmin.Value(); }
protected: protected:
ATTR_HOT void update() override; void update() override;
ATTR_HOT void start() override; void start() override;
ATTR_HOT void reset() override; void reset() override;
ATTR_HOT void update_param() override; void update_param() override;
logic_input_t m_fb_step; logic_input_t m_fb_step;
logic_output_t m_Q_step; logic_output_t m_Q_step;