diff --git a/src/lib/netlist/solver/nld_ms_direct.h b/src/lib/netlist/solver/nld_ms_direct.h index ab67795507f..586b71a2bbe 100644 --- a/src/lib/netlist/solver/nld_ms_direct.h +++ b/src/lib/netlist/solver/nld_ms_direct.h @@ -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::~matrix_solver_direct_t() } template -ATTR_HOT nl_double matrix_solver_direct_t::compute_next_timestep() +nl_double matrix_solver_direct_t::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::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::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::vsetup(analog_net_t::lis template -ATTR_HOT void matrix_solver_direct_t::build_LE_A() +void matrix_solver_direct_t::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::build_LE_A() } template -ATTR_HOT void matrix_solver_direct_t::build_LE_RHS() +void matrix_solver_direct_t::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::build_LE_RHS() } template -ATTR_HOT void matrix_solver_direct_t::LE_solve() +void matrix_solver_direct_t::LE_solve() { const unsigned kN = N(); @@ -481,7 +481,7 @@ ATTR_HOT void matrix_solver_direct_t::LE_solve() } template -ATTR_HOT void matrix_solver_direct_t::LE_back_subst( +void matrix_solver_direct_t::LE_back_subst( nl_double * RESTRICT x) { const unsigned kN = N(); @@ -517,7 +517,7 @@ ATTR_HOT void matrix_solver_direct_t::LE_back_subst( } template -ATTR_HOT void matrix_solver_direct_t::LE_back_subst_full( +void matrix_solver_direct_t::LE_back_subst_full( nl_double * RESTRICT x) { const unsigned kN = N(); @@ -551,7 +551,7 @@ ATTR_HOT void matrix_solver_direct_t::LE_back_subst_full( } template -ATTR_HOT nl_double matrix_solver_direct_t::delta( +nl_double matrix_solver_direct_t::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::delta( } template -ATTR_HOT void matrix_solver_direct_t::store( +void matrix_solver_direct_t::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::store( } } -template -ATTR_HOT nl_double matrix_solver_direct_t::vsolve() -{ - this->solve_base(this); - return this->compute_next_timestep(); -} - template -ATTR_HOT int matrix_solver_direct_t::solve_non_dynamic(ATTR_UNUSED const bool newton_raphson) +int matrix_solver_direct_t::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::solve_non_dynamic(ATTR_UNU } template -ATTR_HOT inline int matrix_solver_direct_t::vsolve_non_dynamic(const bool newton_raphson) +inline int matrix_solver_direct_t::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::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); } diff --git a/src/lib/netlist/solver/nld_ms_direct1.h b/src/lib/netlist/solver/nld_ms_direct1.h index 81e8c329edf..909792a2787 100644 --- a/src/lib/netlist/solver/nld_ms_direct1.h +++ b/src/lib/netlist/solver/nld_ms_direct1.h @@ -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(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(); diff --git a/src/lib/netlist/solver/nld_ms_direct2.h b/src/lib/netlist/solver/nld_ms_direct2.h index 4a6d768fe06..2488e573bf2 100644 --- a/src/lib/netlist/solver/nld_ms_direct2.h +++ b/src/lib/netlist/solver/nld_ms_direct2.h @@ -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(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(); diff --git a/src/lib/netlist/solver/nld_ms_direct_lu.h b/src/lib/netlist/solver/nld_ms_direct_lu.h index 07b3b9cb568..5efbe38ddab 100644 --- a/src/lib/netlist/solver/nld_ms_direct_lu.h +++ b/src/lib/netlist/solver/nld_ms_direct_lu.h @@ -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 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 inline nl_ext_double &A(const T1 r, const T2 c) { return m_A[r][c]; } @@ -171,7 +169,7 @@ matrix_solver_direct_t::~matrix_solver_direct_t() } template -ATTR_HOT nl_double matrix_solver_direct_t::compute_next_timestep() +nl_double matrix_solver_direct_t::compute_next_timestep() { nl_double new_solver_timestep = m_params.m_max_timestep; @@ -245,7 +243,7 @@ ATTR_COLD void matrix_solver_direct_t::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::vsetup(analog_net_t::lis template -ATTR_HOT void matrix_solver_direct_t::build_LE_A() +void matrix_solver_direct_t::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::build_LE_A() } template -ATTR_HOT void matrix_solver_direct_t::build_LE_RHS(nl_double * RESTRICT rhs) +void matrix_solver_direct_t::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::build_LE_RHS(nl_double * #else // Crout algo template -ATTR_HOT void matrix_solver_direct_t::LE_solve() +void matrix_solver_direct_t::LE_solve() { const unsigned kN = N(); @@ -509,7 +507,7 @@ ATTR_HOT void matrix_solver_direct_t::LE_solve() #endif template -ATTR_HOT void matrix_solver_direct_t::LE_back_subst( +void matrix_solver_direct_t::LE_back_subst( nl_double * RESTRICT x) { const unsigned kN = N(); @@ -543,7 +541,7 @@ ATTR_HOT void matrix_solver_direct_t::LE_back_subst( } template -ATTR_HOT nl_double matrix_solver_direct_t::delta( +nl_double matrix_solver_direct_t::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::delta( } template -ATTR_HOT void matrix_solver_direct_t::store( +void matrix_solver_direct_t::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::store( } } -template -ATTR_HOT nl_double matrix_solver_direct_t::vsolve() -{ - this->solve_base(this); - return this->compute_next_timestep(); -} - template -ATTR_HOT int matrix_solver_direct_t::solve_non_dynamic(ATTR_UNUSED const bool newton_raphson) +int matrix_solver_direct_t::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::solve_non_dynamic(ATTR_UNU } template -ATTR_HOT inline int matrix_solver_direct_t::vsolve_non_dynamic(const bool newton_raphson) +inline int matrix_solver_direct_t::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::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); } diff --git a/src/lib/netlist/solver/nld_ms_gmres.h b/src/lib/netlist/solver/nld_ms_gmres.h index 0ae7f5eab56..483decbd05d 100644 --- a/src/lib/netlist/solver/nld_ms_gmres.h +++ b/src/lib/netlist/solver/nld_ms_gmres.h @@ -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::vsetup(analog_net_t::list_t &nets) } template -ATTR_HOT nl_double matrix_solver_GMRES_t::vsolve() -{ - this->solve_base(this); - return this->compute_next_timestep(); -} - -template -ATTR_HOT inline int matrix_solver_GMRES_t::vsolve_non_dynamic(const bool newton_raphson) +int matrix_solver_GMRES_t::vsolve_non_dynamic(const bool newton_raphson) { const unsigned iN = this->N(); diff --git a/src/lib/netlist/solver/nld_ms_sor.h b/src/lib/netlist/solver/nld_ms_sor.h index 556e9fddd7f..1805b23a9d0 100644 --- a/src/lib/netlist/solver/nld_ms_sor.h +++ b/src/lib/netlist/solver/nld_ms_sor.h @@ -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::vsetup(analog_net_t::list_t &nets) } template -ATTR_HOT nl_double matrix_solver_SOR_t::vsolve() -{ - this->solve_base(this); - return this->compute_next_timestep(); -} - -template -ATTR_HOT inline int matrix_solver_SOR_t::vsolve_non_dynamic(const bool newton_raphson) +int matrix_solver_SOR_t::vsolve_non_dynamic(const bool newton_raphson) { const unsigned iN = this->N(); bool resched = false; diff --git a/src/lib/netlist/solver/nld_ms_sor_mat.h b/src/lib/netlist/solver/nld_ms_sor_mat.h index 34c40c34d79..a4fce8dec2a 100644 --- a/src/lib/netlist/solver/nld_ms_sor_mat.h +++ b/src/lib/netlist/solver/nld_ms_sor_mat.h @@ -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::vsetup(analog_net_t::list_t &nets this->save(NLNAME(m_Vdelta)); } - +#if 0 +//FIXME: move to solve_base template -ATTR_HOT nl_double matrix_solver_SOR_mat_t::vsolve() +nl_double matrix_solver_SOR_mat_t::vsolve() { /* * enable linear prediction on first newton pass @@ -111,9 +110,10 @@ ATTR_HOT nl_double matrix_solver_SOR_mat_t::vsolve() return this->compute_next_timestep(); } +#endif template -ATTR_HOT inline int matrix_solver_SOR_mat_t::vsolve_non_dynamic(const bool newton_raphson) +int matrix_solver_SOR_mat_t::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::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::solve_non_dynamic(newton_raphson); } else { diff --git a/src/lib/netlist/solver/nld_solver.cpp b/src/lib/netlist/solver/nld_solver.cpp index 701e418d4ef..39e4fdaacf2 100644 --- a/src/lib/netlist/solver/nld_solver.cpp +++ b/src/lib/netlist/solver/nld_solver.cpp @@ -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; iset_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 -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); diff --git a/src/lib/netlist/solver/nld_solver.h b/src/lib/netlist/solver/nld_solver.h index 06a98d063c6..93d1e18be0e 100644 --- a/src/lib/netlist/solver/nld_solver.h +++ b/src/lib/netlist/solver/nld_solver.h @@ -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 - 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 &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 m_nets; pvector_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;