diff options
Diffstat (limited to 'src/lib/netlist/solver/nld_matrix_solver.h')
-rw-r--r-- | src/lib/netlist/solver/nld_matrix_solver.h | 159 |
1 files changed, 100 insertions, 59 deletions
diff --git a/src/lib/netlist/solver/nld_matrix_solver.h b/src/lib/netlist/solver/nld_matrix_solver.h index 71c28236c67..e4cff24c43a 100644 --- a/src/lib/netlist/solver/nld_matrix_solver.h +++ b/src/lib/netlist/solver/nld_matrix_solver.h @@ -10,9 +10,12 @@ #include "netlist/nl_base.h" #include "netlist/nl_errstr.h" -#include "netlist/plib/palloc.h" -#include "netlist/plib/putil.h" -#include "netlist/plib/vector_ops.h" +#include "plib/palloc.h" +#include "plib/pmatrix2d.h" +#include "plib/putil.h" +#include "plib/vector_ops.h" + +#include <cmath> namespace netlist { @@ -50,49 +53,6 @@ namespace devices std::size_t count() const { return m_terms.size(); } terminal_t **terms() { return m_terms.data(); } - int *connected_net_idx() { return m_connected_net_idx.data(); } - nl_double *gt() { return m_gt.data(); } - nl_double *go() { return m_go.data(); } - nl_double *Idr() { return m_Idr.data(); } - nl_double * const *connected_net_V() const { return m_connected_net_V.data(); } - - void set_pointers(); - - /* FIXME: this works a bit better for larger matrices */ - template <typename AP, typename FT> - void fill_matrix/*_larger*/(AP &tcr, FT &RHS) - { - - const std::size_t term_count = this->count(); - const std::size_t railstart = this->m_railstart; - - for (std::size_t i = 0; i < railstart; i++) - *tcr[i] -= m_go[i]; - - #if 1 - FT gtot_t = 0.0; - FT RHS_t = 0.0; - - for (std::size_t i = 0; i < term_count; i++) - { - gtot_t += m_gt[i]; - RHS_t += m_Idr[i]; - } - // FIXME: Code above is faster than vec_sum - Check this - #else - auto gtot_t = plib::vec_sum<FT>(term_count, m_gt); - auto RHS_t = plib::vec_sum<FT>(term_count, m_Idr); - #endif - - for (std::size_t i = railstart; i < term_count; i++) - { - RHS_t += (/*m_Idr[i]*/ + m_go[i] * *m_connected_net_V[i]); - } - - RHS = RHS_t; - // update diagonal element ... - *tcr[railstart] += gtot_t; //mat.A[mat.diag[k]] += gtot_t; - } std::size_t m_railstart; @@ -105,12 +65,8 @@ namespace devices nl_double m_DD_n_m_1; nl_double m_h_n_m_1; - private: std::vector<int> m_connected_net_idx; - plib::aligned_vector<nl_double, PALIGN_VECTOROPT> m_go; - plib::aligned_vector<nl_double, PALIGN_VECTOROPT> m_gt; - plib::aligned_vector<nl_double, PALIGN_VECTOROPT> m_Idr; - plib::aligned_vector<nl_double *, PALIGN_VECTOROPT> m_connected_net_V; + private: std::vector<terminal_t *> m_terms; }; @@ -212,6 +168,91 @@ namespace devices template <typename T> void build_LE_RHS(T &child); + void set_pointers() + { + const std::size_t iN = this->m_nets.size(); + + std::size_t max_count = 0; + std::size_t max_rail = 0; + for (std::size_t k = 0; k < iN; k++) + { + max_count = std::max(max_count, m_terms[k]->count()); + max_rail = std::max(max_rail, m_terms[k]->m_railstart); + } + + m_mat_ptr.resize(iN, max_rail+1); + m_gtn.resize(iN, max_count); + m_gonn.resize(iN, max_count); + m_Idrn.resize(iN, max_count); + m_connected_net_Vn.resize(iN, max_count); + + for (std::size_t k = 0; k < iN; k++) + { + auto count = m_terms[k]->count(); + + for (std::size_t i = 0; i < count; i++) + { + m_terms[k]->terms()[i]->set_ptrs(&m_gtn[k][i], &m_gonn[k][i], &m_Idrn[k][i]); + m_connected_net_Vn[k][i] = m_terms[k]->terms()[i]->otherterm()->net().Q_Analog_state_ptr(); + } + } + } + + template <typename AP, typename FT> + void fill_matrix(std::size_t N, AP &tcr, FT &RHS) + { + for (std::size_t k = 0; k < N; k++) + { + auto *net = m_terms[k].get(); + auto **tcr_r = &(tcr[k][0]); + + const std::size_t term_count = net->count(); + const std::size_t railstart = net->m_railstart; + const auto &go = m_gonn[k]; + const auto > = m_gtn[k]; + const auto &Idr = m_Idrn[k]; + const auto &cnV = m_connected_net_Vn[k]; + + for (std::size_t i = 0; i < railstart; i++) + *tcr_r[i] += go[i]; + + typename FT::value_type gtot_t = 0.0; + typename FT::value_type RHS_t = 0.0; + + for (std::size_t i = 0; i < term_count; i++) + { + gtot_t += gt[i]; + RHS_t += Idr[i]; + } + // FIXME: Code above is faster than vec_sum - Check this + #if 0 + auto gtot_t = plib::vec_sum<FT>(term_count, m_gt); + auto RHS_t = plib::vec_sum<FT>(term_count, m_Idr); + #endif + + for (std::size_t i = railstart; i < term_count; i++) + { + RHS_t += (/*m_Idr[i]*/ (- go[i]) * *cnV[i]); + } + + RHS[k] = RHS_t; + // update diagonal element ... + *tcr_r[railstart] += gtot_t; //mat.A[mat.diag[k]] += gtot_t; + } + + } + + template <typename T> + using aligned_alloc = plib::aligned_allocator<T, PALIGN_VECTOROPT>; + + plib::pmatrix2d<nl_double, aligned_alloc<nl_double>> m_gonn; + plib::pmatrix2d<nl_double, aligned_alloc<nl_double>> m_gtn; + plib::pmatrix2d<nl_double, aligned_alloc<nl_double>> m_Idrn; + plib::pmatrix2d<nl_double *, aligned_alloc<nl_double *>> m_mat_ptr; + plib::pmatrix2d<nl_double *, aligned_alloc<nl_double *>> m_connected_net_Vn; + + plib::pmatrix2d<nl_double> m_test; + std::vector<plib::unique_ptr<terms_for_net_t>> m_terms; std::vector<analog_net_t *> m_nets; std::vector<poolptr<proxied_analog_output_t>> m_inps; @@ -284,7 +325,7 @@ namespace devices const std::size_t terms_count = terms->count(); const std::size_t railstart = terms->m_railstart; - const float_type * const gt = terms->gt(); + const float_type * const gt = m_gtn[k]; { float_type akk = 0.0; @@ -294,11 +335,11 @@ namespace devices Ak[k] = akk; } - const float_type * const go = terms->go(); - int * net_other = terms->connected_net_idx(); + const float_type * const go = m_gonn[k]; + int * net_other = terms->m_connected_net_idx.data(); for (std::size_t i = 0; i < railstart; i++) - Ak[net_other[i]] -= go[i]; + Ak[net_other[i]] += go[i]; } } @@ -315,16 +356,16 @@ namespace devices float_type rhsk_b = 0.0; const std::size_t terms_count = m_terms[k]->count(); - const float_type * const go = m_terms[k]->go(); - const float_type * const Idr = m_terms[k]->Idr(); - const float_type * const * other_cur_analog = m_terms[k]->connected_net_V(); + const float_type * const go = m_gonn[k]; + const float_type * const Idr = m_Idrn[k]; + const float_type * const * other_cur_analog = m_connected_net_Vn[k]; for (std::size_t i = 0; i < terms_count; i++) rhsk_a = rhsk_a + Idr[i]; for (std::size_t 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]; + rhsk_b = rhsk_b - go[i] * *other_cur_analog[i]; child.RHS(k) = rhsk_a + rhsk_b; } |