summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/solver/nld_matrix_solver.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/solver/nld_matrix_solver.h')
-rw-r--r--src/lib/netlist/solver/nld_matrix_solver.h159
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 &gt = 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;
}