diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h index 264f5826b87..58947144ff5 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.h +++ b/src/lib/netlist/solver/nld_matrix_solver.h @@ -10,6 +10,8 @@ #include "solver/nld_solver.h" +#include + NETLIB_NAMESPACE_DEVICES_START() class terms_t @@ -120,6 +122,11 @@ protected: template T delta(const T * RESTRICT V); + template + void build_LE_A(T & child); + template + void build_LE_RHS(T & child); + pvector_t m_terms; pvector_t m_nets; pvector_t m_inps; @@ -174,6 +181,61 @@ void matrix_solver_t::store(const T * RESTRICT V) this->m_nets[i]->m_cur_Analog = V[i]; } +template +void matrix_solver_t::build_LE_A(T & child) +{ + static_assert(std::is_base_of::value, "T must derive from matrix_solver_t"); + + const unsigned iN = child.N(); + for (unsigned k = 0; k < iN; k++) + { + for (unsigned i=0; i < iN; i++) + child.A(k,i) = 0.0; + + const unsigned terms_count = m_terms[k]->count(); + const unsigned railstart = m_terms[k]->m_railstart; + const nl_double * RESTRICT gt = m_terms[k]->gt(); + + { + nl_double akk = 0.0; + for (unsigned i = 0; i < terms_count; i++) + akk += gt[i]; + + child.A(k,k) = akk; + } + + const nl_double * RESTRICT go = m_terms[k]->go(); + const int * RESTRICT net_other = m_terms[k]->net_other(); + + for (unsigned i = 0; i < railstart; i++) + child.A(k,net_other[i]) -= go[i]; + } +} + +template +void matrix_solver_t::build_LE_RHS(T & child) +{ + const unsigned iN = child.N(); + for (unsigned k = 0; k < iN; k++) + { + nl_double rhsk_a = 0.0; + nl_double rhsk_b = 0.0; + + const unsigned terms_count = m_terms[k]->count(); + const nl_double * RESTRICT go = m_terms[k]->go(); + const nl_double * RESTRICT Idr = m_terms[k]->Idr(); + const nl_double * const * RESTRICT other_cur_analog = m_terms[k]->other_curanalog(); + + for (unsigned i = 0; i < terms_count; i++) + rhsk_a = rhsk_a + Idr[i]; + + for (unsigned i = m_terms[k]->m_railstart; i < terms_count; i++) + //rhsk = rhsk + go[i] * terms[i]->m_otherterm->net().as_analog().Q_Analog(); + rhsk_b = rhsk_b + go[i] * *other_cur_analog[i]; + + child.RHS(k) = rhsk_a + rhsk_b; + } +} NETLIB_NAMESPACE_DEVICES_END() diff --git a/src/lib/netlist/solver/nld_ms_direct.h b/src/lib/netlist/solver/nld_ms_direct.h index b360c748019..2b0ae80b855 100644 --- a/src/lib/netlist/solver/nld_ms_direct.h +++ b/src/lib/netlist/solver/nld_ms_direct.h @@ -118,6 +118,7 @@ class matrix_solver_direct_t: public matrix_solver_t, public thr_intf class matrix_solver_direct_t: public matrix_solver_t #endif { + friend class matrix_solver_t; public: matrix_solver_direct_t(const solver_parameters_t *params, const int size); @@ -134,8 +135,6 @@ protected: inline unsigned N() const { if (m_N == 0) return m_dim; else return m_N; } - void build_LE_A(); - void build_LE_RHS(); void LE_solve(); template @@ -360,59 +359,6 @@ ATTR_COLD void matrix_solver_direct_t::vsetup(analog_net_t::lis } -template -void matrix_solver_direct_t::build_LE_A() -{ - const unsigned iN = N(); - for (unsigned k = 0; k < iN; k++) - { - for (unsigned i=0; i < iN; i++) - A(k,i) = 0.0; - - const unsigned terms_count = m_terms[k]->count(); - const unsigned railstart = m_terms[k]->m_railstart; - const nl_double * RESTRICT gt = m_terms[k]->gt(); - - { - nl_double akk = 0.0; - for (unsigned i = 0; i < terms_count; i++) - akk += gt[i]; - - A(k,k) = akk; - } - - const nl_double * RESTRICT go = m_terms[k]->go(); - const int * RESTRICT net_other = m_terms[k]->net_other(); - - for (unsigned i = 0; i < railstart; i++) - A(k,net_other[i]) -= go[i]; - } -} - -template -void matrix_solver_direct_t::build_LE_RHS() -{ - const unsigned iN = N(); - for (unsigned k = 0; k < iN; k++) - { - nl_double rhsk_a = 0.0; - nl_double rhsk_b = 0.0; - - const unsigned terms_count = m_terms[k]->count(); - const nl_double * RESTRICT go = m_terms[k]->go(); - const nl_double * RESTRICT Idr = m_terms[k]->Idr(); - const nl_double * const * RESTRICT other_cur_analog = m_terms[k]->other_curanalog(); - - for (unsigned i = 0; i < terms_count; i++) - rhsk_a = rhsk_a + Idr[i]; - - for (unsigned i = m_terms[k]->m_railstart; i < terms_count; i++) - //rhsk = rhsk + go[i] * terms[i]->m_otherterm->net().as_analog().Q_Analog(); - rhsk_b = rhsk_b + go[i] * *other_cur_analog[i]; - - RHS(k) = rhsk_a + rhsk_b; - } -} #if TEST_PARALLEL template @@ -622,8 +568,8 @@ int matrix_solver_direct_t::solve_non_dynamic(ATTR_UNUSED const template inline int matrix_solver_direct_t::vsolve_non_dynamic(const bool newton_raphson) { - this->build_LE_A(); - this->build_LE_RHS(); + this->build_LE_A(*this); + this->build_LE_RHS(*this); for (unsigned i=0, iN=N(); i < iN; i++) m_last_RHS[i] = RHS(i); diff --git a/src/lib/netlist/solver/nld_ms_direct1.h b/src/lib/netlist/solver/nld_ms_direct1.h index ab19c92a4cb..abf9518bfbe 100644 --- a/src/lib/netlist/solver/nld_ms_direct1.h +++ b/src/lib/netlist/solver/nld_ms_direct1.h @@ -30,8 +30,8 @@ public: inline int matrix_solver_direct1_t::vsolve_non_dynamic(ATTR_UNUSED const bool newton_raphson) { - this->build_LE_A(); - this->build_LE_RHS(); + this->build_LE_A(*this); + this->build_LE_RHS(*this); //NL_VERBOSE_OUT(("{1} {2}\n", new_val, m_RHS[0] / m_A[0][0]); nl_double new_val[1] = { RHS(0) / A(0,0) }; diff --git a/src/lib/netlist/solver/nld_ms_direct2.h b/src/lib/netlist/solver/nld_ms_direct2.h index 2488e573bf2..f71133d95f0 100644 --- a/src/lib/netlist/solver/nld_ms_direct2.h +++ b/src/lib/netlist/solver/nld_ms_direct2.h @@ -30,8 +30,8 @@ public: inline int matrix_solver_direct2_t::vsolve_non_dynamic(ATTR_UNUSED const bool newton_raphson) { - build_LE_A(); - build_LE_RHS(); + build_LE_A(*this); + build_LE_RHS(*this); const nl_double a = A(0,0); const nl_double b = A(0,1); diff --git a/src/lib/netlist/solver/nld_ms_sm.h b/src/lib/netlist/solver/nld_ms_sm.h index f9585b441f2..bff8197127c 100644 --- a/src/lib/netlist/solver/nld_ms_sm.h +++ b/src/lib/netlist/solver/nld_ms_sm.h @@ -48,6 +48,8 @@ NETLIB_NAMESPACE_DEVICES_START() template class matrix_solver_sm_t: public matrix_solver_t { + friend class matrix_solver_t; + public: matrix_solver_sm_t(const solver_parameters_t *params, const int size); @@ -64,8 +66,6 @@ protected: inline unsigned N() const { if (m_N == 0) return m_dim; else return m_N; } - void build_LE_A(); - void build_LE_RHS(); void LE_invert(); template @@ -243,59 +243,6 @@ ATTR_COLD void matrix_solver_sm_t::vsetup(analog_net_t::list_t } -template -void matrix_solver_sm_t::build_LE_A() -{ - const unsigned iN = N(); - for (unsigned k = 0; k < iN; k++) - { - for (unsigned i=0; i < iN; i++) - A(k,i) = 0.0; - - const unsigned terms_count = m_terms[k]->count(); - const unsigned railstart = m_terms[k]->m_railstart; - const nl_double * RESTRICT gt = m_terms[k]->gt(); - - { - nl_double akk = 0.0; - for (unsigned i = 0; i < terms_count; i++) - akk += gt[i]; - - A(k,k) = akk; - } - - const nl_double * RESTRICT go = m_terms[k]->go(); - const int * RESTRICT net_other = m_terms[k]->net_other(); - - for (unsigned i = 0; i < railstart; i++) - A(k,net_other[i]) -= go[i]; - } -} - -template -void matrix_solver_sm_t::build_LE_RHS() -{ - const unsigned iN = N(); - for (unsigned k = 0; k < iN; k++) - { - nl_double rhsk_a = 0.0; - nl_double rhsk_b = 0.0; - - const unsigned terms_count = m_terms[k]->count(); - const nl_double * RESTRICT go = m_terms[k]->go(); - const nl_double * RESTRICT Idr = m_terms[k]->Idr(); - const nl_double * const * RESTRICT other_cur_analog = m_terms[k]->other_curanalog(); - - for (unsigned i = 0; i < terms_count; i++) - rhsk_a = rhsk_a + Idr[i]; - - for (unsigned i = m_terms[k]->m_railstart; i < terms_count; i++) - //rhsk = rhsk + go[i] * terms[i]->m_otherterm->net().as_analog().Q_Analog(); - rhsk_b = rhsk_b + go[i] * *other_cur_analog[i]; - - RHS(k) = rhsk_a + rhsk_b; - } -} template void matrix_solver_sm_t::LE_invert() @@ -473,8 +420,8 @@ int matrix_solver_sm_t::solve_non_dynamic(ATTR_UNUSED const boo template inline int matrix_solver_sm_t::vsolve_non_dynamic(const bool newton_raphson) { - this->build_LE_A(); - this->build_LE_RHS(); + this->build_LE_A(*this); + this->build_LE_RHS(*this); for (unsigned i=0, iN=N(); i < iN; i++) m_last_RHS[i] = RHS(i); diff --git a/src/lib/netlist/solver/nld_ms_sor_mat.h b/src/lib/netlist/solver/nld_ms_sor_mat.h index a4fce8dec2a..10192717a90 100644 --- a/src/lib/netlist/solver/nld_ms_sor_mat.h +++ b/src/lib/netlist/solver/nld_ms_sor_mat.h @@ -128,8 +128,8 @@ int matrix_solver_SOR_mat_t::vsolve_non_dynamic(const bool newt int resched_cnt = 0; - this->build_LE_A(); - this->build_LE_RHS(); + this->build_LE_A(*this); + this->build_LE_RHS(*this); #if 0 static int ws_cnt = 0; diff --git a/src/lib/netlist/solver/nld_ms_w.h b/src/lib/netlist/solver/nld_ms_w.h index 7a4ee61dd8c..aa6f7104c6c 100644 --- a/src/lib/netlist/solver/nld_ms_w.h +++ b/src/lib/netlist/solver/nld_ms_w.h @@ -55,6 +55,7 @@ NETLIB_NAMESPACE_DEVICES_START() template class matrix_solver_w_t: public matrix_solver_t { + friend class matrix_solver_t; public: matrix_solver_w_t(const solver_parameters_t *params, const int size); @@ -71,8 +72,6 @@ protected: inline unsigned N() const { if (m_N == 0) return m_dim; else return m_N; } - void build_LE_A(); - void build_LE_RHS(); void LE_invert(); template @@ -257,59 +256,6 @@ ATTR_COLD void matrix_solver_w_t::vsetup(analog_net_t::list_t & } -template -void matrix_solver_w_t::build_LE_A() -{ - const unsigned iN = N(); - for (unsigned k = 0; k < iN; k++) - { - for (unsigned i=0; i < iN; i++) - A(k,i) = 0.0; - - const unsigned terms_count = m_terms[k]->count(); - const unsigned railstart = m_terms[k]->m_railstart; - const nl_double * RESTRICT gt = m_terms[k]->gt(); - - { - nl_double akk = 0.0; - for (unsigned i = 0; i < terms_count; i++) - akk += gt[i]; - - A(k,k) = akk; - } - - const nl_double * RESTRICT go = m_terms[k]->go(); - const int * RESTRICT net_other = m_terms[k]->net_other(); - - for (unsigned i = 0; i < railstart; i++) - A(k,net_other[i]) -= go[i]; - } -} - -template -void matrix_solver_w_t::build_LE_RHS() -{ - const unsigned iN = N(); - for (unsigned k = 0; k < iN; k++) - { - nl_double rhsk_a = 0.0; - nl_double rhsk_b = 0.0; - - const unsigned terms_count = m_terms[k]->count(); - const nl_double * RESTRICT go = m_terms[k]->go(); - const nl_double * RESTRICT Idr = m_terms[k]->Idr(); - const nl_double * const * RESTRICT other_cur_analog = m_terms[k]->other_curanalog(); - - for (unsigned i = 0; i < terms_count; i++) - rhsk_a = rhsk_a + Idr[i]; - - for (unsigned i = m_terms[k]->m_railstart; i < terms_count; i++) - //rhsk = rhsk + go[i] * terms[i]->m_otherterm->net().as_analog().Q_Analog(); - rhsk_b = rhsk_b + go[i] * *other_cur_analog[i]; - - RHS(k) = rhsk_a + rhsk_b; - } -} template void matrix_solver_w_t::LE_invert() @@ -536,8 +482,8 @@ int matrix_solver_w_t::solve_non_dynamic(ATTR_UNUSED const bool template inline int matrix_solver_w_t::vsolve_non_dynamic(const bool newton_raphson) { - this->build_LE_A(); - this->build_LE_RHS(); + this->build_LE_A(*this); + this->build_LE_RHS(*this); for (unsigned i=0, iN=N(); i < iN; i++) m_last_RHS[i] = RHS(i);