1. add mesh analysis, 2. add bridge_algorithm.c, 3. delete some code for capacity...
authoryu.dongliang <18588496441@163.com>
Sat, 11 May 2024 12:25:35 +0000 (20:25 +0800)
committeryu.dongliang <18588496441@163.com>
Sat, 11 May 2024 12:25:35 +0000 (20:25 +0800)
37 files changed:
Makefile
examples/add.cpk [new file with mode: 0644]
examples/add.pack [deleted file]
examples/add2.cpk [new file with mode: 0644]
examples/add2.pack [deleted file]
examples/and.cpk [new file with mode: 0644]
examples/and.pack [deleted file]
examples/or.cpk [new file with mode: 0644]
examples/or.pack [deleted file]
examples/oscillator.pack [deleted file]
examples/sin_oscillator.cpk [new file with mode: 0644]
main.c
scf_eda_pack.c
scf_eda_pack.h
scf_vector.h
ses_core.h
ses_flow.c [new file with mode: 0644]
ses_layout.c
ses_mesh_analysis.c [new file with mode: 0644]
ses_path.c [new file with mode: 0644]
ses_step_a_stat.c [new file with mode: 0644]
ses_step_dc_transistor.c
ses_step_jr.c
ses_step_open.c
ses_step_simplify.c
ses_step_simplify2.c [new file with mode: 0644]
ses_step_status.c [new file with mode: 0644]
ses_step_topo.c
ses_step_va.c
ses_step_va_bridge.c [deleted file]
ses_step_va_capacitor.c
ses_step_va_diode.c
ses_step_va_transistor.c
ses_steps.c
ses_utils.c
test/bridge_algorithm.c
test/main.c

index 3c1bf1818919d9649f9dc822eb2684991bf26364..12181bc49ee1acdb451acb56b711f053835da654 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,9 +1,15 @@
 CFILES += main.c
+
 CFILES += scf_eda_pack.c
 CFILES += pack/scf_pack.c
+
 CFILES += ses_layout.c
 CFILES += ses_graph.c
+
 CFILES += ses_utils.c
+CFILES += ses_path.c
+CFILES += ses_flow.c
+CFILES += ses_mesh_analysis.c
 
 CFILES += ses_steps.c
 CFILES += ses_step_battery.c
@@ -13,18 +19,22 @@ CFILES += ses_step_dc_transistor.c
 
 CFILES += ses_step_topo.c
 
-CFILES += ses_step_jr.c 
+CFILES += ses_step_jr.c
 CFILES += ses_step_va_diode.c
 CFILES += ses_step_va_transistor.c
-CFILES += ses_step_va.c 
-CFILES += ses_step_va_bridge.c
+CFILES += ses_step_va.c
+CFILES += ses_step_status.c
+
 CFILES += ses_step_va_line.c
 
 CFILES += ses_step_open.c
 CFILES += ses_step_va_capacitor.c
 
+CFILES += ses_step_a_stat.c
+
 CFILES += ses_step_output.c
 CFILES += ses_step_simplify.c
+CFILES += ses_step_simplify2.c
 
 CFLAGS += -g -D_GNU_SOURCE
 CFLAGS += -I./
@@ -32,6 +42,7 @@ CFLAGS += -I./pack
 
 LDFLAGS += -lm
 LDFLAGS += -lcairo
+LDFLAGS += -lgsl -lgslcblas
 
 all:
        gcc $(CFLAGS) $(CFILES) $(LDFLAGS)
diff --git a/examples/add.cpk b/examples/add.cpk
new file mode 100644 (file)
index 0000000..ed6037b
Binary files /dev/null and b/examples/add.cpk differ
diff --git a/examples/add.pack b/examples/add.pack
deleted file mode 100644 (file)
index 846a755..0000000
Binary files a/examples/add.pack and /dev/null differ
diff --git a/examples/add2.cpk b/examples/add2.cpk
new file mode 100644 (file)
index 0000000..5c7bdc3
Binary files /dev/null and b/examples/add2.cpk differ
diff --git a/examples/add2.pack b/examples/add2.pack
deleted file mode 100644 (file)
index 955d1a5..0000000
Binary files a/examples/add2.pack and /dev/null differ
diff --git a/examples/and.cpk b/examples/and.cpk
new file mode 100644 (file)
index 0000000..0907c7d
Binary files /dev/null and b/examples/and.cpk differ
diff --git a/examples/and.pack b/examples/and.pack
deleted file mode 100644 (file)
index 2dca83e..0000000
Binary files a/examples/and.pack and /dev/null differ
diff --git a/examples/or.cpk b/examples/or.cpk
new file mode 100644 (file)
index 0000000..888bc0b
Binary files /dev/null and b/examples/or.cpk differ
diff --git a/examples/or.pack b/examples/or.pack
deleted file mode 100644 (file)
index fd4867b..0000000
Binary files a/examples/or.pack and /dev/null differ
diff --git a/examples/oscillator.pack b/examples/oscillator.pack
deleted file mode 100644 (file)
index 6346f89..0000000
Binary files a/examples/oscillator.pack and /dev/null differ
diff --git a/examples/sin_oscillator.cpk b/examples/sin_oscillator.cpk
new file mode 100644 (file)
index 0000000..b6dd5c5
Binary files /dev/null and b/examples/sin_oscillator.cpk differ
diff --git a/main.c b/main.c
index 58aeeba5f07fc09d1a0d86be6c686a93ed9fc131..869dd09bb9c2a4995c1146eaeb216883d14a1fb5 100644 (file)
--- a/main.c
+++ b/main.c
@@ -107,7 +107,7 @@ int main(int argc, char* argv[])
 
                printf("f: %s\n", f->name);
 
-               ses_steps_analyse(f, 300, 1);
+               ses_steps_analyse(f, 100, 1);
        }
 #endif
 
index 8d3988b3fe343cca00d469db86fe7dcc341c480b..c837e73ea6eef4f4a91304d96a02833643aaf3bc 100644 (file)
@@ -1,5 +1,4 @@
 #include "scf_eda_pack.h"
-//#include "scf_def.h"
 
 static int component_pins[SCF_EDA_Components_NB] =
 {
@@ -18,7 +17,7 @@ static int component_pins[SCF_EDA_Components_NB] =
 static scf_edata_t  component_datas[] =
 {
        {SCF_EDA_None,       0,                   0, 0, 0,    0,   0,   0, 0},
-       {SCF_EDA_Battery,    0, SCF_EDA_Battery_POS, 0, 0,    0,   0,   0, 0},
+       {SCF_EDA_Battery,    0, SCF_EDA_Battery_POS, 0, 0, 1e-9, 1e9,   0, 0},
 
        {SCF_EDA_Resistor,   0,                   0, 0, 0,  1e4,   0,   0, 0},
        {SCF_EDA_Capacitor,  0,                   0, 0, 0,   10, 0.1,   0, 0},
index 2cf8303057c0e89cde1d11771e952ad9d2d5b736..1f48b4cfd256374096f68a4d9ec0bbb75d1b9387 100644 (file)
@@ -119,15 +119,11 @@ struct scf_epin_s
        SCF_PACK_DEF_VAR(double, uh);
        SCF_PACK_DEF_VAR(double, hfe);
 
-       SCF_PACK_DEF_VAR(double, jdr);
        SCF_PACK_DEF_VAR(double, dr);
 
        SCF_PACK_DEF_VAR(double, sr);
        SCF_PACK_DEF_VAR(double, pr);
 
-       SCF_PACK_DEF_VAR(double, jsr);
-       SCF_PACK_DEF_VAR(double, jpr);
-
        SCF_PACK_DEF_VAR(uint64_t, path);
 
        SCF_PACK_DEF_VAR(int, x);
@@ -158,13 +154,9 @@ SCF_PACK_INFO_VAR(ScfEpin, uf),
 SCF_PACK_INFO_VAR(ScfEpin, uh),
 SCF_PACK_INFO_VAR(ScfEpin, hfe),
 
-SCF_PACK_INFO_VAR(ScfEpin, jdr),
 SCF_PACK_INFO_VAR(ScfEpin, dr),
-
 SCF_PACK_INFO_VAR(ScfEpin, sr),
 SCF_PACK_INFO_VAR(ScfEpin, pr),
-SCF_PACK_INFO_VAR(ScfEpin, jsr),
-SCF_PACK_INFO_VAR(ScfEpin, jpr),
 
 SCF_PACK_INFO_VAR(ScfEpin, path),
 SCF_PACK_INFO_VAR(ScfEpin, x),
@@ -199,7 +191,8 @@ typedef struct {
        SCF_PACK_DEF_OBJS(ScfLine, lines);
 
        SCF_PACK_DEF_VAR(double, v);
-       SCF_PACK_DEF_VAR(double, a);
+       SCF_PACK_DEF_VAR(double, ain);
+       SCF_PACK_DEF_VAR(double, aout);
        SCF_PACK_DEF_VAR(uint8_t, vconst);
        SCF_PACK_DEF_VAR(uint8_t, aconst);
        SCF_PACK_DEF_VAR(uint8_t, vflag);
@@ -217,7 +210,8 @@ SCF_PACK_INFO_OBJS(ScfEline, conns, ScfEconn),
 SCF_PACK_INFO_OBJS(ScfEline, lines, ScfLine),
 
 SCF_PACK_INFO_VAR(ScfEline, v),
-SCF_PACK_INFO_VAR(ScfEline, a),
+SCF_PACK_INFO_VAR(ScfEline, ain),
+SCF_PACK_INFO_VAR(ScfEline, aout),
 SCF_PACK_INFO_VAR(ScfEline, vconst),
 SCF_PACK_INFO_VAR(ScfEline, aconst),
 SCF_PACK_INFO_VAR(ScfEline, vflag),
@@ -234,7 +228,6 @@ struct scf_ecomponent_s
        SCF_PACK_DEF_VAR(double, a);
 
        SCF_PACK_DEF_VAR(double, dr);
-       SCF_PACK_DEF_VAR(double, jdr);
 
        SCF_PACK_DEF_VAR(double, r);
        SCF_PACK_DEF_VAR(double, uf);
@@ -261,7 +254,6 @@ SCF_PACK_INFO_VAR(ScfEcomponent, v),
 SCF_PACK_INFO_VAR(ScfEcomponent, a),
 
 SCF_PACK_INFO_VAR(ScfEcomponent, dr),
-SCF_PACK_INFO_VAR(ScfEcomponent, jdr),
 
 SCF_PACK_INFO_VAR(ScfEcomponent, r),
 SCF_PACK_INFO_VAR(ScfEcomponent, uf),
index d4249ca9c6d4cc40e3fbe1639734edc5bb13aad1..c0a88ebcd5b2bf2183feefe3e48a981dc0dcfc65 100644 (file)
@@ -157,6 +157,15 @@ static inline int scf_vector_qsort(const scf_vector_t* v, int (*cmp)(const void*
        return 0;
 }
 
+static inline void scf_vector_mov_first(scf_vector_t* v, int i, void* d)
+{
+       int j;
+       for (j = i - 1; j >= 0; j--)
+               v->data[j + 1] = v->data[j];
+
+       v->data[0] = d;
+}
+
 static inline void scf_vector_clear(scf_vector_t* v, void (*type_free)(void*))
 {
        if (!v || !v->data)
@@ -195,4 +204,3 @@ static inline void scf_vector_free(scf_vector_t* v)
 }
 
 #endif
-
index eb50c7d3ac217da6c4e9ea95ee08df3ad9da8ade..3b926509314f6aa02e28f4899d7e49c6f2f33273 100644 (file)
@@ -5,9 +5,14 @@
 #include"scf_eda_pack.h"
 
 typedef struct ses_step_s    ses_step_t;
+
 typedef struct ses_path_s    ses_path_t;
+typedef struct ses_edge_s    ses_edge_t;
 typedef struct ses_flow_s    ses_flow_t;
+typedef struct ses_mesh_s    ses_mesh_t;
+
 typedef struct ses_info_s    ses_info_t;
+typedef struct ses_data_s    ses_data_t;
 typedef struct ses_ctx_s     ses_ctx_t;
 
 struct ses_flow_s
@@ -15,7 +20,9 @@ struct ses_flow_s
        scf_vector_t*  paths;
 
        ScfEpin*       vip;
-       ScfEpin*       vip_n;
+       int            vip_i;
+       int            vip_m;
+       int            vip_n;
 
        int            pos_pins;
        int            neg_pins;
@@ -29,6 +36,9 @@ struct ses_flow_s
        double         pos_r;
        double         neg_r;
 
+       double         pos_cv;
+       double         neg_cv;
+
        double         v;
        double         a;
 };
@@ -46,8 +56,32 @@ struct ses_info_s
        int            n_capacitors;
 };
 
+typedef struct __ses_data_s
+{
+       uint64_t       id;
+
+       double         dr;
+       double         v;
+       double         a;
+       int            n_pins;
+} __ses_data_t;
+
+struct ses_data_s
+{
+       uint64_t       id;
+
+       double         dr;
+       double         v;
+       double         a;
+
+       int            n_pins;
+       __ses_data_t   pins[0];
+};
+
 struct ses_path_s
 {
+       int            refs;
+
        scf_vector_t*  pins;
        scf_vector_t*  infos;
 
@@ -60,31 +94,61 @@ struct ses_path_s
        int            parent_p1;
 
        double         parent_pr;
-       double         parent_jpr;
 
        double         sr;
        double         pr;
 
-       double         jsr;
-       double         jpr;
-
        double         v;
        double         a;
 
        double         a0;
-       double         da;
+       double         cda;
 
        int            type;
        int            index;
 
        int            n_capacitors;
        int            n_diodes;
+       int            n_NPNs;
        int            n_transistors;
        int            n_layers;
 
        uint8_t        vflag:1;
 };
 
+struct ses_edge_s
+{
+       int            refs;
+
+       ses_path_t*    path;
+       int            vip_m;
+       int            vip_n;
+
+       int            n_diodes;
+       int            n_NPNs;
+
+       double         cv;
+       double         r;
+
+       double         v;
+       double         a;
+       double         a0;
+};
+
+struct ses_mesh_s
+{
+       scf_vector_t*  edges;
+
+       int            n_diodes;
+       int            n_NPNs;
+
+       double         cv;
+       double         r;
+
+       double         a;
+       double         a0;
+};
+
 struct ses_ctx_s
 {
        scf_vector_t*  paths;
@@ -101,16 +165,35 @@ struct ses_step_s
        void*          priv;
 };
 
+void        ses_data_free(scf_vector_t* vec);
+
 ses_path_t* ses_path_alloc();
 void        ses_path_free (ses_path_t* path);
 void        ses_path_print(ses_path_t* path);
+ses_path_t* ses_path_ref  (ses_path_t* src);
 int         ses_path_add  (ses_path_t* path, ses_path_t* child, ScfEfunction* f);
 int         ses_path_xchg (ses_path_t* path0, int k0, ses_path_t* path1, int k1);
 
-ses_path_t* ses_path_save (ses_path_t* src);
-int         ses_path_load (ses_path_t* dst, ses_path_t* src);
+int         ses_path_save (ScfEfunction* f, ses_path_t* path, scf_vector_t** data);
+int         ses_path_load (ScfEfunction* f, ses_path_t* path, scf_vector_t*  data);
 
+int         ses_path_is_child(ses_path_t* parent, ses_path_t* child);
 ses_path_t* ses_path_find_child(ses_path_t* path, int m, int n);
+ses_path_t* ses_path_find_bridge(ses_path_t* path, int m, int n);
+void        ses_path_sort_childs(ses_path_t* path);
+
+ses_edge_t* ses_edge_alloc(ses_path_t* path, int first, int last);
+void        ses_edge_free (ses_edge_t* edge);
+void        ses_edge_print(ses_edge_t* edge);
+
+ses_mesh_t* ses_mesh_alloc();
+void        ses_mesh_free (ses_mesh_t* mesh);
+void        ses_mesh_print(ses_mesh_t* mesh);
+
+int         ses_mesh_ref_edge(ses_mesh_t* mesh, ses_edge_t* edge);
+int         ses_mesh_add_edge(ses_mesh_t* mesh, ses_path_t* path, int m, int n, ses_edge_t** pp);
+void        ses_meshs_print(scf_vector_t* meshs);
+void        ses_meshs_free (scf_vector_t* meshs);
 
 ses_flow_t* ses_flow_alloc();
 void        ses_flow_free (ses_flow_t* flow);
@@ -123,11 +206,13 @@ void        ses_flow_jr   (ses_flow_t* flow, ScfEfunction* f);
 ses_ctx_t*  ses_ctx_alloc();
 void        ses_ctx_free (ses_ctx_t* ctx);
 
+void ses_components_print(ScfEfunction* f);
+void ses_elines_print    (ScfEfunction* f);
 
 int ses_layout_board (ScfEboard*    b);
 int ses_steps_analyse(ScfEfunction* f, int64_t ns, int64_t count);
 
-int ses_flows_make_path(ses_path_t** ppath, ses_flow_t* pos, ses_flow_t* neg, ses_path_t* bridge, int reverse);
+int ses_simplify_draw(ScfEfunction* f, const char* file, uint32_t bx, uint32_t by, uint32_t bw, uint32_t bh);
 
 int ses_paths_find_flow(ses_flow_t* flow, scf_vector_t* paths, ScfEpin* vip,  ses_path_t* bridge);
 int ses_flow_find_pos  (ses_flow_t* flow, scf_vector_t* paths, ScfEfunction* f);
@@ -145,17 +230,25 @@ void __ses_status_check_line(ScfEfunction* f, ScfEline* el, int* changed);
 
 int  __ses_path_capacitors(ScfEfunction* f, ses_path_t* path, int m, int n, double* cv);
 
+int __ses_meshs_PPN       (ScfEfunction* f, ses_flow_t* flow, ses_path_t* bridge, scf_vector_t** meshs);
+int __ses_meshs_path      (ScfEfunction* f, ses_path_t* path, scf_vector_t** meshs);
+int __ses_meshs_path2     (ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, int vip_i, scf_vector_t** meshs);
+int __ses_meshs_path_solve(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, int* changed, int64_t ns, int64_t count);
+int __ses_meshs_PPN_solve (ScfEfunction* f, ses_flow_t* flow, ses_path_t* bridge, int* changed, int64_t ns, int64_t count);
+
 int  __ses_path_jr (ScfEfunction* f, ses_path_t* path);
 void __ses_path_pr (ScfEfunction* f, ses_path_t* path, int i, int j, ses_path_t* child, double* r);
 void __ses_path_jpr(ScfEfunction* f, ses_path_t* path, int i, int j, ses_path_t* child, double* jr);
 void __ses_path_sr (ScfEfunction* f, ses_path_t* path, int i, int j, double* r);
 void __ses_path_jsr(ScfEfunction* f, ses_path_t* path, int i, int j, double* jr);
-int  __ses_path_va (ScfEfunction* f, ses_path_t* path, int m, int n, int *changed, int64_t ns, int64_t count);
+
+int  __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count);
+int  __ses_path_va2(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count);
+int  __ses_path_va (ScfEfunction* f, ses_path_t* path, int *changed, int64_t ns, int64_t count);
+int  __ses_flow_va (ScfEfunction* f, ses_flow_t* flow, double* rp, double* rn, int* changed, int64_t ns, int64_t count);
+
 int  __ses_path_pos(ScfEfunction* f, ScfEline*   el);
 int  __ses_path_neg(ScfEfunction* f, ScfEline*   el);
-void __ses_npn_epr (ScfEfunction* f, ScfEpin*    pe, double* r);
-void __ses_npn_dr (ScfEcomponent* c, ScfEpin*    pb, ScfEpin* pe);
-void __ses_pn_dr  (ScfEcomponent* c, ScfEpin*    pb, ScfEpin* pe);
 
 
 static inline void vertical(int* px, int* py, int dx, int dy, int d)
@@ -264,4 +357,109 @@ static inline void ses_merge_r(double* tr, double* jtr, double r0, double jr0, d
                *jtr = jr0 / -R;
 }
 
+static inline void ses_va_PNN(double U0, double U1, double U2,
+               double  R0,  double  R1,  double  R2,
+               double* pi0, double* pi1, double* pi2, double* pVb0)
+{
+       double i1 = (R0 * (U2 - U1) + R2 * (U0 - U1)) / (R0 * R1 + R1 * R2 + R0 * R2);
+       double i0 = (U0 - U1 - i1 * R1) / R0;
+       double i2 = i0 - i1;
+
+       double V0 = i0 * R0;
+       double V1 = i1 * R1;
+       double V2 = i2 * R2;
+
+       scf_logi("U0: %lg, U1: %lg, U2: %lg, R0: %lg, R1: %lg, R2: %lg, i0: %lg, i1: %lg, i2: %lg, V0: %lg, V1: %lg, V2: %lg\n",
+                       U0, U1, U2, R0, R1, R2, i0, i1, i2, V0, V1, V2);
+
+       if (pi0)
+               *pi0 = i0;
+
+       if (pi1)
+               *pi1 = i1;
+
+       if (pi2)
+               *pi2 = i2;
+
+       if (*pVb0)
+               *pVb0 = U0 - V0;
+}
+
+static inline void ses_va_PPN(double U0, double U1, double U2,
+               double  R0,  double  R1,  double  R2,
+               double* pi0, double* pi1, double* pi2, double* pVb1)
+{
+       double i1 = (R0 * (U2 - U1) + R2 * (U0 - U1)) / (R0 * R1 + R1 * R2 + R0 * R2);
+       double i0 = (U0 - U1 - i1 * R1) / R0;
+       double i2 = i1 - i0;
+
+       double V0 = i0 * R0;
+       double V1 = i1 * R1;
+       double V2 = i2 * R2;
+
+       scf_logi("U0: %lg, U1: %lg, U2: %lg, R0: %lg, R1: %lg, R2: %lg, i0: %lg, i1: %lg, i2: %lg, V0: %lg, V1: %lg, V2: %lg\n",
+                       U0, U1, U2, R0, R1, R2, i0, i1, i2, V0, V1, V2);
+
+       if (pi0)
+               *pi0 = i0;
+
+       if (pi1)
+               *pi1 = i1;
+
+       if (pi2)
+               *pi2 = i2;
+
+       if (*pVb1)
+               *pVb1 = U1 + V1;
+}
+
+static inline void ses_va_bridge(
+               double  U0,  double  U1,  double  U2,  double  U3,  double  Vbc,
+               double  R0,  double  R1,  double  R2,  double  R3,  double  Rb,
+               double* pi0, double* pi1, double* pi2, double* pi3, double* pib,
+               double* pVb0, double* pVb1)
+{
+       scf_logw("R0: %lg, R1: %lg, R2: %lg, R3: %lg, Vbc: %lg, U0: %lg, U1: %lg, U2: %lg, U3: %lg\n", R0, R1, R2, R3, Vbc, U0, U1, U2, U3);
+
+       double i1 = (R0 * R3 * (U2 - U1 + Vbc) - R0 * R2 * (U1 - U3 - Vbc) + (R2 * R3 + R3 * Rb + R2 * Rb) * (U0 - U1))
+                     / ((R2 + R3) * (R0 * R1 + Rb * (R0 + R1)) + R2 * R3 * (R0 + R1));
+
+       double ib = (U0 - U1 - i1 * (R0 + R1)) / R0;
+       double i0 = i1 + ib;
+       double i3 = (R0 * (U1 - U3 - Vbc) - Rb * (U0 - U1) + i1 * (R0 * R1 + Rb * (R0 + R1))) / R0 / R3;
+       double i2 = i3 - ib;
+
+       double V0 = i0 * R0;
+       double V1 = i1 * R1;
+       double V2 = i2 * R2;
+       double V3 = i3 * R3;
+       double Vb = ib * Rb;
+
+       scf_logi("i0: %lg, i1: %lg, i2: %lg, i3: %lg, ib: %lg\n", i0, i1, i2, i3, ib);
+
+       double Vb0 = U1 + V1;
+       double Vb1 = U3 + V3;
+
+       if (pi0)
+               *pi0 = i0;
+
+       if (pi1)
+               *pi1 = i1;
+
+       if (pi2)
+               *pi2 = i2;
+
+       if (pi3)
+               *pi3 = i3;
+
+       if (pib)
+               *pib = ib;
+
+       if (pVb0)
+               *pVb0 = Vb0;
+
+       if (pVb1)
+               *pVb1 = Vb1;
+}
+
 #endif
diff --git a/ses_flow.c b/ses_flow.c
new file mode 100644 (file)
index 0000000..fc559a7
--- /dev/null
@@ -0,0 +1,414 @@
+#include"ses_core.h"
+
+ses_flow_t* ses_flow_alloc()
+{
+       ses_flow_t* flow = calloc(1, sizeof(ses_flow_t));
+       if (!flow)
+               return NULL;
+
+       flow->paths = scf_vector_alloc();
+       if (!flow->paths) {
+               ses_flow_free(flow);
+               return NULL;
+       }
+
+       return flow;
+}
+
+void ses_flow_free(ses_flow_t* flow)
+{
+       if (flow) {
+               if (flow->paths)
+                       scf_vector_free(flow->paths);
+
+               free(flow);
+       }
+}
+
+int ses_paths_find_flow(ses_flow_t* flow, scf_vector_t* paths, ScfEpin* vip, ses_path_t* bridge)
+{
+       ses_path_t* path;
+       ScfEpin*    p;
+
+       int i;
+       int j;
+
+       for (i = 0; i < paths->size; i++) {
+               path      = paths->data[i];
+
+               if (path == bridge)
+                       continue;
+
+               for (j = 0; j < path->pins->size; j++) {
+                       p  =        path->pins->data[j];
+
+                       if (vip->lid == p->lid) {
+
+                               if (j + 1 >= path->pins->size)
+                                       break;
+
+                               if (scf_vector_add(flow->paths, path) < 0)
+                                       return -1;
+
+                               flow->vip   = p;
+                               flow->vip_i = j;
+                               flow->vip_m = 0;
+                               flow->vip_n = path->pins->size - 1;
+                               return 1;
+                       }
+               }
+
+               if (path->childs) {
+                       int ret = ses_paths_find_flow(flow, path->childs, vip, bridge);
+                       if (ret < 0)
+                               return ret;
+
+                       if (1 == ret) {
+                               if (scf_vector_add(flow->paths, path) < 0)
+                                       return -ENOMEM;
+                               return 1;
+                       }
+               }
+
+               if (path->bridges) {
+                       int ret = ses_paths_find_flow(flow, path->bridges, vip, bridge);
+                       if (ret < 0)
+                               return ret;
+
+                       if (1 == ret) {
+                               if (scf_vector_add(flow->paths, path) < 0)
+                                       return -ENOMEM;
+                               return 1;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+int ses_flow_find_neg(ses_flow_t* flow, scf_vector_t* paths, ScfEfunction* f)
+{
+       if (flow->paths->size <= 0)
+               return 0;
+
+       ses_path_t*    path = flow->paths->data[flow->paths->size - 1];
+       ScfEpin*       vp   = flow->vip;
+       ScfEpin*       p    = path->pins->data[path->pins->size - 1];
+
+       ScfEcomponent* B    = f->components[0];
+       ScfEpin*       Bn   = B->pins[SCF_EDA_Battery_NEG];
+
+       while (p->lid != Bn->lid) {
+               int ret = ses_paths_find_flow(flow, paths, p, path);
+               if (ret < 0)
+                       return ret;
+
+               path = flow->paths->data[flow->paths->size - 1];
+               p    = path->pins ->data[path->pins->size - 1];
+       }
+
+       flow->vip = vp;
+       return 0;
+}
+
+int ses_flow_find_pos(ses_flow_t* flow, scf_vector_t* paths, ScfEfunction* f)
+{
+       if (flow->paths->size <= 0)
+               return 0;
+
+       ses_path_t*    path = flow->paths->data[flow->paths->size - 1];
+       ScfEpin*       vp   = flow->vip;
+       ScfEpin*       p    = path->pins->data[0];
+
+       ScfEcomponent* B    = f->components[0];
+       ScfEpin*       Bp   = B->pins[SCF_EDA_Battery_POS];
+
+       while (p->lid != Bp->lid) {
+               int ret = ses_paths_find_flow(flow, paths, p, path);
+               if (ret < 0)
+                       return ret;
+
+               path = flow->paths->data[flow->paths->size - 1];
+               p    = path->pins ->data[0];
+       }
+
+       flow->vip = vp;
+       return 0;
+}
+
+void ses_flow_jr(ses_flow_t* flow, ScfEfunction* f)
+{
+       if (!flow)
+               return;
+
+       flow->pos_pins = 0;
+       flow->neg_pins = 0;
+
+       flow->pos_r = 0;
+       flow->neg_r = 0;
+
+       flow->pos_cv = 0;
+       flow->neg_cv = 0;
+
+       if (!flow->paths || !flow->vip)
+               return;
+
+       ses_path_t*    path;
+       ses_path_t*    child;
+       ScfEcomponent* c;
+       ScfEpin*       p;
+       ScfEpin*       p0;
+       ScfEpin*       vip = flow->vip;
+
+       int i;
+       int j;
+       int m;
+       int n;
+
+       for (i   = 0; i < flow->paths->size; i++) {
+               path =        flow->paths->data[i];
+
+               if (0 == i) {
+                       m =  flow->vip_m;
+                       n =  flow->vip_n;
+               } else {
+                       m = 0;
+                       n = path->pins->size - 1;
+               }
+
+               for (j = m; j <= n; j++) {
+                       p  = path->pins->data[j];
+
+                       ++flow->pos_pins;
+
+                       c = f->components[p->cid];
+
+                       if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_B == p->id)
+                               flow->pos_NPNs++;
+                       else if (SCF_EDA_Diode == c->type && SCF_EDA_Diode_POS == p->id)
+                               flow->pos_diodes++;
+
+                       else if (SCF_EDA_Capacitor == c->type && (j & 0x1)) {
+                               int sign = !p->id - p->id;
+
+                               flow->pos_cv += c->v * sign;
+                       }
+
+                       if (p->lid == vip->lid) {
+                               vip = path->pins->data[0];
+
+                               child = ses_path_find_child(path, 0, j);
+                               if (!child)
+                                       child = ses_path_find_bridge(path, 0, j);
+
+                               if (child) {
+                                       flow->pos_r += child->parent_pr;
+
+                               } else if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_E == p->id) {
+                                       p = path->pins->data[j - 1];
+
+                                       flow->pos_r += p->pr + p->r + p->dr;
+                               } else
+                                       flow->pos_r += p->pr;
+
+                               scf_logd("flow->pos_r: %lg, c%ldp%ld->pr: %lg, vip c%ldp%ld->pr: %lg\n",
+                                               flow->pos_r, p->cid, p->id, p->pr, vip->cid, vip->id, vip->pr);
+                               break;
+                       }
+               }
+       }
+
+       vip = flow->vip;
+
+       for (i   = 0; i < flow->paths->size; i++) {
+               path =        flow->paths->data[i];
+
+               if (0 == i) {
+                       m =  flow->vip_m;
+                       n =  flow->vip_n;
+               } else {
+                       m = 0;
+                       n = path->pins->size - 1;
+               }
+
+               int parallel = 0;
+               int j0;
+
+               p0 = NULL;
+               for (j = m; j <= n; j++) {
+                       p  = path->pins->data[j];
+
+                       if (!p0) {
+                               if (!(j & 0x1) && p->lid == vip->lid) {
+                                       p0 = p;
+                                       j0 = j;
+
+                                       child = ses_path_find_child(path, j0, n);
+                                       if (child)
+                                               parallel = 1;
+                               } else
+                                       continue;
+                       }
+
+                       ++flow->neg_pins;
+
+                       c = f->components[p->cid];
+
+                       if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_B == p->id)
+                               flow->neg_NPNs++;
+                       else if (SCF_EDA_Diode == c->type && SCF_EDA_Diode_POS == p->id)
+                               flow->neg_diodes++;
+
+                       else if (SCF_EDA_Capacitor == c->type && (j & 0x1)) {
+                               int sign = !p->id - p->id;
+
+                               flow->neg_cv += c->v * sign;
+                       }
+
+                       if (parallel)
+                               continue;
+
+                       if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_E == p->id) {
+                               p = path->pins->data[j - 1];
+
+                               if (p->lid == p0->lid)
+                                       flow->neg_r += p->r + p->dr;
+                               else
+                                       flow->neg_r += p->pr - p0->pr;
+
+                               scf_logd("flow->neg_r: %lg, c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n",
+                                               flow->neg_r, p->cid, p->id, p->sr, p0->cid, p0->id, p0->pr);
+
+                               if (j + 1 <= n) {
+                                       p0    = path->pins->data[j + 1];
+                                       j0    = j + 1;
+                               } else {
+                                       p0    = path->pins->data[j];
+                                       j0    = j;
+                               }
+
+                       } else if (p->sr != p->pr) {
+
+                               child = ses_path_find_child(path, j0, j);
+                               if (!child)
+                                       child = ses_path_find_bridge(path, j0, j);
+
+                               if (child)
+                                       flow->neg_r += child->parent_pr - p0->pr;
+                               else
+                                       flow->neg_r += p->sr - p0->pr;
+
+                               scf_logd("flow->neg_r: %lg, c%ldp%ld->sr: %lg, p->pr: %lg, p0 c%ldp%ld->pr: %lg\n",
+                                               flow->neg_r, p->cid, p->id, p->sr, p->pr, p0->cid, p0->id, p0->pr);
+
+                               p0 = p;
+                               j0 = j;
+                       }
+               }
+
+               if (p0) {
+                       vip = path->pins->data[j - 1];
+                       c   = f->components[vip->cid];
+
+                       if (vip != p0) {
+                               child = ses_path_find_child(path, j0, j - 1);
+                               if (child)
+                                       flow->neg_r += child->parent_pr - p0->pr;
+                               else
+                                       flow->neg_r += vip->sr - p0->pr;
+                       }
+
+                       scf_logd("flow->neg_r: %lg, vip c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n",
+                                       flow->neg_r, vip->cid, vip->id, vip->sr, p0->cid, p0->id, p0->pr);
+
+                       if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_E == vip->id)
+                               vip->pr = path->parent_pr;
+               }
+
+               scf_logd("flow->neg_r: %lg, vip c%ldp%ld->sr: %lg\n", flow->neg_r, vip->cid, vip->id, vip->sr);
+       }
+
+       scf_loge("flow pos_r: %lg, neg_r: %lg, pos_cv: %lg, neg_cv: %lg, vip: c%ldp%ld, pos_diodes: %d, pos_NPNs: %d, neg_diodes: %d, neg_NPNs: %d\n",
+                       flow->pos_r, flow->neg_r, flow->pos_cv, flow->neg_cv, flow->vip->cid, flow->vip->id, flow->pos_diodes, flow->pos_NPNs, flow->neg_diodes, flow->neg_NPNs);
+}
+
+void ses_flow_print(ses_flow_t* flow)
+{
+       if (!flow || !flow->paths || !flow->vip)
+               return;
+
+       ses_path_t* path;
+       ScfEpin*    p;
+       ScfEpin*    vip = flow->vip;
+
+       int i;
+       int j;
+       int m;
+       int n;
+
+       for (i = flow->paths->size - 1; i >= 0; i--) {
+
+               if (i > 0) {
+                       path = flow->paths->data[i - 1];
+
+                       vip = path->pins->data[0];
+                       m   = 0;
+                       n   = path->pins->size - 1;
+               } else {
+                       vip = flow->vip;
+                       m   = flow->vip_m;
+                       n   = flow->vip_n;
+               }
+
+               path = flow->paths->data[i];
+
+               for (j = m; j <= n; j++) {
+                       p  = path->pins->data[j];
+
+                       printf("c%ldp%ld ", p->cid, p->id);
+
+                       if (p->lid == vip->lid)
+                               break;
+               }
+
+               if (i > 0)
+                       printf(", ");
+       }
+
+       printf(";\n");
+
+       vip = flow->vip;
+
+       for (i   = 0; i < flow->paths->size; i++) {
+               path =        flow->paths->data[i];
+
+               if (i > 0) {
+                       m = 0;
+                       n = path->pins->size - 1;
+               } else {
+                       m = flow->vip_m;
+                       n = flow->vip_n;
+               }
+
+               int flag = 0;
+
+               for (j = m; j <= n; j++) {
+                       p  = path->pins->data[j];
+
+                       if (!flag) {
+                               if (p->lid == vip->lid)
+                                       flag = 1;
+                               continue;
+                       }
+
+                       printf("c%ldp%ld ", p->cid, p->id);
+               }
+
+               if (flag)
+                       printf(", ");
+
+               vip = path->pins->data[j - 1];
+       }
+
+       printf(".\n");
+}
index 6906dc4e26ecc96b6779e6daa08fb70de3735337..0d4212e544f6e3a5dfe3bb3a0155b1b8a2d9c9a7 100644 (file)
@@ -1793,7 +1793,7 @@ int ses_layout_board(ScfEboard* b)
 
                ses_lines_same_components(f);
 
-               int ret = ses_layout_function(f, 60);
+               int ret = ses_layout_function(f, 90);
                if (ret < 0) {
                        scf_loge("\n");
                        return ret;
diff --git a/ses_mesh_analysis.c b/ses_mesh_analysis.c
new file mode 100644 (file)
index 0000000..ae44d9e
--- /dev/null
@@ -0,0 +1,448 @@
+#include"ses_core.h"
+#include <gsl/gsl_linalg.h>
+
+int ses_mesh_ref_edge(ses_mesh_t* mesh, ses_edge_t* edge)
+{
+       int ret = scf_vector_add(mesh->edges, edge);
+       if (ret < 0)
+               return ret;
+
+       edge->refs++;
+       return 0;
+}
+
+int ses_mesh_add_edge(ses_mesh_t* mesh, ses_path_t* path, int m, int n, ses_edge_t** pp)
+{
+       ses_edge_t* edge = ses_edge_alloc(path, m, n);
+       if (!edge)
+               return -ENOMEM;
+
+       int ret = scf_vector_add(mesh->edges, edge);
+       if (ret < 0) {
+               ses_edge_free(edge);
+               return ret;
+       }
+
+       if (pp)
+               *pp = edge;
+       return 0;
+}
+
+int __ses_meshs_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, int vip_i, scf_vector_t** meshs)
+{
+       scf_vector_t* vec;
+       ses_path_t*   child;
+
+       ses_edge_t*   edge = NULL;
+       ses_edge_t*   prev = NULL;
+       ses_mesh_t*   mesh;
+       ses_mesh_t*   right = NULL;
+
+       int ret = -1;
+
+       vec = scf_vector_alloc();
+       if (!vec)
+               return -ENOMEM;
+
+       right = ses_mesh_alloc();
+       if (!right) {
+               ret = -ENOMEM;
+               goto error;
+       }
+
+       int i;
+       int j = vip_i;
+       int k;
+
+       for (i = vip_i - 1; i >= vip_m; i -= 2) {
+
+               ScfEpin* p = path->pins->data[i];
+
+               if (!path->childs)
+                       continue;
+
+               for (k = 0; k < path->childs->size; k++) {
+                       child     = path->childs->data[k];
+
+                       if (child->parent_p0 == i && child->parent_p1 == vip_n)
+                               break;
+               }
+
+               if (k >= path->childs->size)
+                       continue;
+               scf_logd("c%ldp%ld\n", p->cid, p->id);
+
+               mesh = ses_mesh_alloc();
+               if (!mesh) {
+                       ret = -ENOMEM;
+                       goto error;
+               }
+
+               ret = scf_vector_add(vec, mesh);
+               if (ret < 0) {
+                       ses_mesh_free(mesh);
+                       goto error;
+               }
+
+               if (prev) {
+                       ret = ses_mesh_add_edge(mesh, prev->path, prev->vip_n, prev->vip_m, NULL);
+                       if (ret < 0)
+                               goto error;
+               }
+
+               ret = ses_mesh_add_edge(mesh, path, j, i, &edge);
+               if (ret < 0)
+                       goto error;
+               ret = ses_mesh_ref_edge(right, edge);
+               if (ret < 0)
+                       goto error;
+
+               ret = ses_mesh_add_edge(mesh, child, 0, child->pins->size - 1, &prev);
+               if (ret < 0)
+                       goto error;
+
+               j = i - 1;
+       }
+
+       if (j > vip_m) {
+               ret = ses_mesh_add_edge(right, path, j, vip_m, NULL);
+               if (ret < 0)
+                       goto error;
+       }
+
+       ret = scf_vector_add(vec, right);
+       if (ret < 0)
+               goto error;
+
+       *meshs = vec;
+       return 0;
+
+error:
+       if (right)
+               ses_mesh_free(right);
+
+       scf_vector_clear(vec, (void (*)(void*) )ses_mesh_free);
+       scf_vector_free(vec);
+       return ret;
+}
+
+int __ses_meshs_path(ScfEfunction* f, ses_path_t* path, scf_vector_t** meshs)
+{
+       int n = path->pins->size - 1;
+
+       return __ses_meshs_path2(f, path, 0, n, n, meshs);
+}
+
+/*
+ a[vip_n, 0]     = Iright + I[0]
+ a[0,     1]     = Iright + I[1]
+ a[1,     2]     = Iright + I[2]
+ ...
+ a[n - 2, n - 1] = Iright + I[n - 1]
+ a[n - 1, vip_m] = Iright
+
+ a[0]            = I[0]   - I[1]
+ a[1]            = I[1]   - I[2]
+ ...
+ a[n - 1]        = I[n - 1]
+
+-----------------------------
+ v[0]                - a[0]               * R[0]            = C[0]            + Vn
+ v[1]                - a[1]               * R[1]            = C[1]            + Vn
+...
+ v[n - 1]            - a[n - 1]           * R[n - 1]        = C[n - 1]        + Vn
+
+
+ v[vip_n]     - v[0] - a[vip_n,     0]    * R[vip_n,     0] = C[vip_n,     0]
+ v[0]         - v[1] - a[0,         1]    * R[0,         1] = C[0,         1]
+...
+ v[n - 2] - v[n - 1] - a[n - 2, n - 1]    * R[n - 2, n - 1] = C[n - 2, n - 1]
+ v[n - 1]            - a[n - 1,     m]    * R[n - 1, m]     = C[n - 1, m]     + Vm
+
+-----------------------------
+ v[0]                - (I[0]    -   I[1]) * R[0]            = C[0]            + Vn
+ v[1]                - (I[1]    -   I[2]) * R[1]            = C[1]            + Vn
+...
+ v[n - 2]            - (I[n -2] - I[n-1]) * R[n - 2]        = C[n - 2]        + Vn
+ v[n - 1]            -  I[n -1]           * R[n - 1]        = C[n - 1]        + Vn
+
+              - v[0] - (Iright  +   I[0]) * R[vip_n,     0] = C[vip_n,     0] - Vn
+ v[0]         - v[1] - (Iright  +   I[1]) * R[0,         1] = C[0,         1]
+...
+ v[n - 2] - v[n - 1] - (Iright  + I[n-1]) * R[n - 2, n - 1] = C[n - 2, n - 1]
+ v[n - 1]            -  Iright            * R[n - 1, m]     = C[n - 1, m]     + Vm
+
+-----------------------------
+    0:   v[0]
+    1:   v[1]
+       ...
+n - 1:   v[n - 1]
+
+n    :   I[0]
+n + 1:   I[1]
+    ...
+2n -1:   I[n - 1]
+2n   :   Iright
+*/
+
+int __ses_meshs_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, scf_vector_t* meshs, int* changed, int64_t ns, int64_t count)
+{
+       ses_mesh_t*   mesh;
+       ses_edge_t*   edge;
+
+       ScfEline*     el;
+       ScfEpin*      pm = path->pins->data[vip_m];
+       ScfEpin*      pn = path->pins->data[vip_n];
+       ScfEpin*      p0;
+       ScfEpin*      p1;
+
+       int ret = 0;
+
+       int n = meshs->size - 1;
+       int N = 2 * n + 1;
+       int i;
+
+       scf_logi("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, n_childs: %d, N: %d\n", pm->cid, pm->id, pm->v, pn->cid, pn->id, pn->v, n, N);
+
+       double* A = calloc(N * N + N + N, sizeof(double));
+       if (!A)
+               return -ENOMEM;
+
+       double* b = A + N * N;
+       double* X = b + N;
+       double cv;
+       double pr;
+
+       __ses_path_jr(f, path);
+
+       for (i = 0; i < meshs->size - 1; i++) {
+               mesh      = meshs->data[i];
+
+               edge = mesh->edges->data[mesh->edges->size - 1];
+
+               __ses_path_capacitors(f, edge->path, edge->vip_m, edge->vip_n, &cv);
+               b[i] = cv + pn->v;
+
+               __ses_path_pr(f, edge->path, edge->vip_m, edge->vip_n, NULL, &pr);
+
+               edge->r = pr;
+
+               p0 = edge->path->pins->data[edge->vip_m];
+               p1 = edge->path->pins->data[edge->vip_n];
+               scf_logi("c%ldp%ld-c%ldp%ld, pr: %lg, cv: %lg\n", p0->cid, p0->id, p1->cid, p1->id, pr, cv);
+
+               A[i * N     + i] = 1;
+               A[i * N + n + i] = -pr;
+
+               if (i < n - 1)
+                       A[i * N + n + i + 1] =  pr;
+       }
+
+       mesh = meshs->data[meshs->size - 1];
+
+       for (i = 0; i < mesh->edges->size; i++) {
+               edge      = mesh->edges->data[i];
+
+               if (edge->vip_m > edge->vip_n) {
+
+                       if (0 == edge->vip_n && edge->vip_m == edge->path->pins->size - 1)
+                               pr = edge->path->pr;
+                       else
+                               __ses_path_pr(f, edge->path, edge->vip_n, edge->vip_m, NULL, &pr);
+
+                       __ses_path_capacitors(f, edge->path, edge->vip_n, edge->vip_m, &cv);
+                       b[n + i] = -cv;
+               } else {
+                       __ses_path_capacitors(f, edge->path, edge->vip_m, edge->vip_n, &cv);
+                       b[n + i] = cv;
+
+                       if (0 == edge->vip_m && edge->vip_n == edge->path->pins->size - 1)
+                               pr = edge->path->pr;
+                       else
+                               __ses_path_pr(f, edge->path, edge->vip_m, edge->vip_n, NULL, &pr);
+               }
+
+               if (i > 0)
+                       A[(n + i) * N + i - 1] = 1;
+               else
+                       b[n + i] -= pn->v;
+
+               if (i < n) {
+                       A[(n + i) * N     + i] = -1;
+                       A[(n + i) * N + n + i] = -pr;
+               } else
+                       b[n + i] += pm->v;
+
+               A[(n + i) * N + 2 * n] = -pr;
+
+               p0 = edge->path->pins->data[edge->vip_m];
+               p1 = edge->path->pins->data[edge->vip_n];
+       
+               edge->r = pr;
+
+               scf_logi("c%ldp%ld-c%ldp%ld, pr: %lg, cv: %lg, vip_m: %d, vip_n: %d\n", p0->cid, p0->id, p1->cid, p1->id, pr, cv, edge->vip_m, edge->vip_n);
+       }
+
+       gsl_matrix_view _A = gsl_matrix_view_array(A, N, N);
+       gsl_vector_view _b = gsl_vector_view_array(b, N);
+       gsl_vector_view _X = gsl_vector_view_array(X, N);
+
+       int s;
+       gsl_permutation* _P = gsl_permutation_alloc(N);
+       if (!_P) {
+               ret = -ENOMEM;
+               goto P_failed;
+       }
+
+       gsl_linalg_LU_decomp(&_A.matrix, _P, &s);
+       gsl_linalg_LU_solve (&_A.matrix, _P, &_b.vector, &_X.vector);
+
+       scf_logi("X:\n");
+       gsl_vector_fprintf(stdout, &_X.vector, "%lg");
+#if 1
+       for (i = 0; i < meshs->size - 1; i++) {
+               mesh      = meshs->data[i];
+
+               edge = mesh->edges->data[mesh->edges->size - 1];
+
+               p0 = edge->path->pins->data[edge->vip_m];
+               p1 = edge->path->pins->data[edge->vip_n];
+
+               el    = f->elines[p0->lid];
+               el->v = X[i];
+
+               ret = __ses_path_va2(f, edge->path, edge->vip_m, edge->vip_n, edge->r, changed, ns, count);
+               if (ret < 0)
+                       goto error;
+       }
+
+       mesh = meshs->data[meshs->size - 1];
+
+       for (i = 0; i < mesh->edges->size; i++) {
+               edge      = mesh->edges->data[i];
+
+               p0 = edge->path->pins->data[edge->vip_m];
+               p1 = edge->path->pins->data[edge->vip_n];
+
+               ret = __ses_path_va2(f, edge->path, edge->vip_n, edge->vip_m, edge->r, changed, ns, count);
+               if (ret < 0)
+                       goto error;
+       }
+#endif
+error:
+       gsl_permutation_free(_P);
+P_failed:
+       free(A);
+       return ret;
+}
+
+int __ses_meshs_path_solve(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, int* changed, int64_t ns, int64_t count)
+{
+       scf_vector_t* meshs = NULL;
+       ses_mesh_t*   mesh;
+       ses_edge_t*   edge;
+
+       ScfEline*     el;
+       ScfEpin*      pm = path->pins->data[vip_m];
+       ScfEpin*      pn = path->pins->data[vip_n];
+       ScfEpin*      p0;
+       ScfEpin*      p1;
+
+       int ret = __ses_meshs_path2(f, path, vip_m, vip_n, vip_n, &meshs);
+       if (ret < 0)
+               return ret;
+
+       ses_meshs_print(meshs);
+
+       ret = __ses_meshs_path_solve2(f, path, vip_m, vip_n, meshs, changed, ns, count);
+
+       scf_vector_clear(meshs, (void (*)(void*) )ses_mesh_free);
+       scf_vector_free(meshs);
+
+       return ret;
+}
+
+int __ses_meshs_PPN(ScfEfunction* f, ses_flow_t* flow, ses_path_t* bridge, scf_vector_t** meshs)
+{
+       scf_vector_t* vec  = NULL;
+       ses_path_t*   path = flow->paths->data[0];
+
+       ses_edge_t*   edge0 = NULL;
+       ses_edge_t*   edge1 = NULL;
+       ses_mesh_t*   mesh;
+       ses_mesh_t*   left;
+       ses_mesh_t*   right;
+
+       int ret = __ses_meshs_path2(f, path, flow->vip_m, flow->vip_n, flow->vip_i, &vec);
+       if (ret < 0)
+               return ret;
+
+       mesh  = vec->data[0];
+       right = vec->data[vec->size - 1];
+
+       left = ses_mesh_alloc();
+       if (!left) {
+               ret = -ENOMEM;
+               goto error;
+       }
+
+       ret = scf_vector_add(vec, left);
+       if (ret < 0) {
+               ses_mesh_free(left);
+               goto error;
+       }
+       scf_vector_mov_first(vec, vec->size - 1, left);
+
+       ret = ses_mesh_add_edge(left, bridge, 0, bridge->pins->size - 1, &edge0);
+       if (ret < 0)
+               goto error;
+
+       ret = ses_mesh_ref_edge(right, edge0);
+       if (ret < 0)
+               goto error;
+
+       ret = ses_mesh_add_edge(left, path, flow->vip_i + 1, flow->vip_n, NULL);
+       if (ret < 0)
+               goto error;
+
+       ret = ses_mesh_add_edge(mesh, path, flow->vip_n, flow->vip_i + 1, &edge1);
+       if (ret < 0)
+               goto error;
+
+       scf_vector_mov_first(right->edges, right->edges->size - 1, edge0);
+       scf_vector_mov_first(mesh ->edges, mesh ->edges->size - 1, edge1);
+
+       *meshs = vec;
+       return 0;
+
+error:
+       scf_vector_clear(vec, (void (*)(void*) )ses_mesh_free);
+       scf_vector_free(vec);
+       return ret;
+}
+
+int __ses_meshs_PPN_solve(ScfEfunction* f, ses_flow_t* flow, ses_path_t* bridge, int* changed, int64_t ns, int64_t count)
+{
+       scf_vector_t* meshs = NULL;
+       ses_path_t*   path  = flow->paths->data[0];
+       ses_mesh_t*   mesh;
+       ses_edge_t*   edge;
+
+       ScfEline*     el;
+       ScfEpin*      pm = path->pins->data[flow->vip_m];
+       ScfEpin*      pn = path->pins->data[flow->vip_n];
+       ScfEpin*      p0;
+       ScfEpin*      p1;
+
+       int ret = __ses_meshs_PPN(f, flow, bridge, &meshs);
+       if (ret < 0)
+               return ret;
+
+       ses_meshs_print(meshs);
+
+       ret = __ses_meshs_path_solve2(f, path, flow->vip_m, flow->vip_n, meshs, changed, ns, count);
+
+       scf_vector_clear(meshs, (void (*)(void*) )ses_mesh_free);
+       scf_vector_free(meshs);
+       return ret;
+}
diff --git a/ses_path.c b/ses_path.c
new file mode 100644 (file)
index 0000000..7061ec5
--- /dev/null
@@ -0,0 +1,712 @@
+#include"ses_core.h"
+
+ses_path_t* ses_path_alloc()
+{
+       ses_path_t* path = calloc(1, sizeof(ses_path_t));
+       if (!path)
+               return NULL;
+
+       path->pins = scf_vector_alloc();
+       if (!path->pins) {
+               free(path);
+               return NULL;
+       }
+
+       path->infos = scf_vector_alloc();
+       if (!path->infos) {
+               scf_vector_free(path->pins);
+               free(path);
+               return NULL;
+       }
+
+       path->refs = 1;
+       return path;
+}
+
+void ses_path_free(ses_path_t* path)
+{
+       if (path) {
+               if (--path->refs > 0)
+                       return;
+
+               assert(0 == path->refs);
+
+               if (path->pins)
+                       scf_vector_free(path->pins);
+
+               if (path->infos) {
+                       scf_vector_clear(path->infos, ( void (*)(void*) )free);
+                       scf_vector_free (path->infos);
+               }
+
+               if (path->childs) {
+                       scf_vector_clear(path->childs, ( void (*)(void*) )ses_path_free);
+                       scf_vector_free (path->childs);
+               }
+
+               if (path->bridges) {
+                       scf_vector_clear(path->bridges, ( void (*)(void*) )ses_path_free);
+                       scf_vector_free (path->bridges);
+               }
+
+               scf_logd("path: %d\n", path->index);
+
+               free(path);
+       }
+}
+
+ses_path_t* ses_path_ref(ses_path_t* src)
+{
+       if (!src)
+               return NULL;
+
+       ses_path_t* dst = ses_path_alloc();
+       if (!dst)
+               return NULL;
+
+       dst->pins = scf_vector_clone(src->pins);
+       if (!dst->pins) {
+               ses_path_free(dst);
+               return NULL;
+       }
+
+       if (src->childs) {
+               dst->childs = scf_vector_clone(src->childs);
+
+               if (!dst->childs) {
+                       ses_path_free(dst);
+                       return NULL;
+               }
+
+               ses_path_t* child;
+               int i;
+
+               for (i = 0; i < dst->childs->size; i++) {
+                       child     = dst->childs->data[i];
+                       child->refs++;
+               }
+       }
+
+       dst->index = src->index;
+       return dst;
+}
+
+void ses_path_print(ses_path_t* path)
+{
+       if (!path)
+               return;
+
+       ses_path_t* path2;
+       ScfEpin*    p;
+
+       int i;
+
+       if (!path->parent)
+               printf("\033[31mpath  : %d, n_diodes: %d, n_NPNs: %d, n_capacitors: %d, infos->size: %d, \033[0m",
+                               path->index, path->n_diodes, path->n_NPNs, path->n_capacitors, path->infos->size);
+
+       for (i = 0; i < path->pins->size; i++) {
+               p  =        path->pins->data[i];
+
+               printf("c%ldp%ld ", p->cid, p->id);
+       }
+       printf("\n");
+
+       if (path->childs) {
+               for (i = 0; i < path->childs->size; i++) {
+                       path2     = path->childs->data[i];
+
+                       printf("\033[32mchild : %d, n_diodes: %d, n_NPNs: %d, n_capacitors: %d, infos->size: %d, parent: %d, \033[0m",
+                                       path2->index, path2->n_diodes, path2->n_NPNs, path2->n_capacitors, path2->infos->size, path->index);
+
+                       ses_path_print(path2);
+               }
+       }
+
+       if (path->bridges) {
+               for (i = 0; i < path->bridges->size; i++) {
+                       path2     = path->bridges->data[i];
+
+                       printf("\033[33mbridge: %d, n_diodes: %d, n_NPNs: %d, n_capacitors: %d, infos->size: %d, parent: %d, \033[0m",
+                                       path2->index, path2->n_diodes, path2->n_NPNs, path2->n_capacitors, path2->infos->size, path->index);
+
+                       ses_path_print(path2);
+               }
+       }
+}
+
+int ses_path_is_child(ses_path_t* parent, ses_path_t* child)
+{
+       ScfEpin* cp0 = child->pins->data[0];
+       ScfEpin* cp1 = child->pins->data[child->pins->size - 1];
+       ScfEpin* p;
+
+       int i;
+       int j = -1;
+
+       for (i = 0; i < parent->pins->size; i++) {
+               p  =        parent->pins->data[i];
+
+               if (p->lid == cp0->lid) {
+                       j = i;
+                       continue;
+               }
+
+               if (p->lid == cp1->lid) {
+                       if (j >= 0)
+                               return 1;
+                       return 0;
+               }
+       }
+
+       return 0;
+}
+
+static int _ses_child_cmp(const void* v0, const void* v1)
+{
+       const ses_path_t* p0 = *(const ses_path_t**)v0;
+       const ses_path_t* p1 = *(const ses_path_t**)v1;
+
+       if (p0->parent_p0 <= p1->parent_p0 && p0->parent_p1 >= p1->parent_p1)
+               return -1;
+
+       if (p0->parent_p0 >= p1->parent_p0 && p0->parent_p1 <= p1->parent_p1)
+               return 1;
+       return 0;
+}
+
+void ses_path_child_index(ses_path_t* path, ses_path_t* child)
+{
+       ScfEpin* cp0;
+       ScfEpin* cp1;
+       ScfEpin* p;
+
+       child->parent_p0 = -1;
+       child->parent_p1 = -1;
+
+       cp0 = child->pins->data[0];
+       cp1 = child->pins->data[child->pins->size - 1];
+
+       int j;
+       for (j = 0; j < path->pins->size; j++) {
+               p  =        path->pins->data[j];
+
+               if (p->lid == cp0->lid)
+                       child->parent_p0 = j;
+
+               else if (p->lid == cp1->lid) {
+                       child->parent_p1 = j;
+                       break;
+               }
+       }
+
+       assert(child->parent_p0 >= 0);
+       assert(child->parent_p1 >= 0);
+}
+
+void ses_path_sort_childs(ses_path_t* path)
+{
+       ses_path_t* child;
+
+       if (path && path->childs) {
+               int i;
+               for (i = 0; i < path->childs->size; i++) {
+                       child     = path->childs->data[i];
+
+                       ses_path_child_index(path, child);
+               }
+
+               scf_vector_qsort(path->childs, _ses_child_cmp);
+       }
+}
+
+ses_path_t* ses_path_find_child(ses_path_t* path, int m, int n)
+{
+       ses_path_t* child;
+       ScfEpin*    cp0;
+       ScfEpin*    cp1;
+
+       if (path->childs) {
+               ScfEpin* p0 = path->pins->data[m];
+               ScfEpin* p1 = path->pins->data[n];
+
+               scf_logd("c%ldp%ld-c%ldp%ld\n", p0->cid, p0->id, p1->cid, p1->id);
+               int i;
+               int j;
+
+               for (i    = 0; i < path->childs->size; i++) {
+                       child =        path->childs->data[i];
+
+                       cp0 = child->pins->data[0];
+                       cp1 = child->pins->data[child->pins->size - 1];
+
+                       if (cp1->lid != p1->lid)
+                               continue;
+
+                       for (j = m; j <= n; j++) {
+                               p0 = path->pins->data[j];
+
+                               if (cp0->lid == p0->lid)
+                                       return child;
+                       }
+               }
+       }
+       return NULL;
+}
+
+ses_path_t* ses_path_find_bridge(ses_path_t* path, int m, int n)
+{
+       ses_path_t* child;
+       ScfEpin*    cp0;
+       ScfEpin*    cp1;
+
+       if (path->bridges) {
+               ScfEpin* p0 = path->pins->data[m];
+               ScfEpin* p1 = path->pins->data[n];
+
+               scf_logd("c%ldp%ld-c%ldp%ld\n", p0->cid, p0->id, p1->cid, p1->id);
+               int i;
+               int j;
+
+               for (i    = 0; i < path->bridges->size; i++) {
+                       child =        path->bridges->data[i];
+
+                       cp0 = child->pins->data[0];
+                       cp1 = child->pins->data[child->pins->size - 1];
+
+                       if (cp1->lid != p1->lid)
+                               continue;
+
+                       for (j = m; j <= n; j++) {
+                               p0 = path->pins->data[j];
+
+                               if (cp0->lid == p0->lid)
+                                       return child;
+                       }
+               }
+       }
+       return NULL;
+}
+
+int ses_path_xchg(ses_path_t* path0, int k0, ses_path_t* path1, int k1)
+{
+       ScfEpin* p;
+
+       int i;
+
+       for (i = 0; i + k0 < path0->pins->size && i + k1 < path1->pins->size; i++)
+               SCF_XCHG(path0->pins->data[i + k0], path1->pins->data[i + k1]);
+
+       scf_logd("path0: %d, k0: %d ... path1: %d, k1: %d, i: %d\n", path0->pins->size, k0, path1->pins->size, k1, i);
+
+       if (i + k0 < path0->pins->size) {
+
+               while (i + k0 < path0->pins->size) {
+                       p         = path0->pins->data[i + k0];
+
+                       assert(0 == scf_vector_del(path0->pins, p));
+
+                       if (scf_vector_add(path1->pins, p) < 0)
+                               return -ENOMEM;
+               }
+
+       } else if (i + k1 < path1->pins->size) {
+
+               while (i + k1 < path1->pins->size) {
+                       p         = path1->pins->data[i + k1];
+
+                       assert(0 == scf_vector_del(path1->pins, p));
+
+                       if (scf_vector_add(path0->pins, p) < 0)
+                               return -ENOMEM;
+               }
+       }
+
+       return 0;
+}
+
+int ses_path_add(ses_path_t* parent, ses_path_t* child, ScfEfunction* f)
+{
+       if (!parent || !child)
+               return -EINVAL;
+
+       if (!parent->childs) {
+               parent->childs = scf_vector_alloc();
+               if (!parent->childs)
+                       return -ENOMEM;
+       }
+
+       ses_path_t* path;
+       ScfEpin*    p0;
+       ScfEpin*    p1;
+       ScfEpin*    cp0 = child->pins->data[0];
+       ScfEpin*    cp1 = child->pins->data[child->pins->size - 1];
+
+       int j;
+
+       for (j = 0; j < parent->childs->size; j++) {
+               path      = parent->childs->data[j];
+
+               p0        = path->pins->data[0];
+               p1        = path->pins->data[path->pins->size - 1];
+
+               if (p0->lid == cp0->lid && p1->lid == cp1->lid) {
+
+                       if (child->pins->size == (child->n_diodes + child->n_NPNs) * 2
+                         && path->pins->size  > (path->n_diodes + path->n_NPNs) * 2) {
+
+                               parent->childs->data[j] = child;
+                               child->parent           = parent;
+                               child->parent_p0        = path->parent_p0;
+                               child->parent_p1        = path->parent_p1;
+                               child->type             = SES_PATH_BRANCH;
+
+                               return ses_path_add(child, path, f);
+                       } else
+                               return ses_path_add(path, child, f);
+               }
+       }
+
+       if (scf_vector_add(parent->childs, child) < 0)
+               return -ENOMEM;
+
+       for (j = 0; j < parent->pins->size; j++) {
+               p0 =        parent->pins->data[j];
+
+               if (p0->lid == cp0->lid) {
+                       child->parent_p0 = (j + 1) & ~0x1;
+                       break;
+               }
+       }
+       assert(j < parent->pins->size);
+
+       int n_transistors = 0;
+       int n_capacitors  = 0;
+       int n_diodes = 0;
+       int n_NPNs   = 0;
+
+       for ( ; j < parent->pins->size; j++) {
+               p0    = parent->pins->data[j];
+
+               if (!(j & 0x1)) {
+                       ScfEcomponent* c = f->components[p0->cid];
+
+                       if (SCF_EDA_Capacitor == c->type)
+                               n_capacitors++;
+
+                       else if (SCF_EDA_Diode == c->type)
+                               n_diodes++;
+
+                       else if (SCF_EDA_NPN == c->type) {
+                               if (SCF_EDA_NPN_B == p0->id)
+                                       n_NPNs++;
+                               else if (SCF_EDA_NPN_C == p0->id)
+                                       n_transistors++;
+                       }
+               }
+
+               if (p0->lid == cp1->lid) {
+                       child->parent_p1 = j;
+                       break;
+               }
+       }
+       assert(j < parent->pins->size);
+
+       p0 = parent->pins->data[0];
+       p1 = parent->pins->data[parent->pins->size - 1];
+
+       scf_logd("parent: %d, c%ldp%ld-c%ldp%ld, child: %d, c%ldp%ld-c%ldp%ld\n",
+                       parent->index, p0->cid, p0->id, p1->cid, p1->id,
+                       child->index, cp0->cid, cp0->id, cp1->cid, cp1->id);
+
+       if (0 == n_transistors
+                       && (n_diodes + n_NPNs < child->n_diodes + child->n_NPNs
+                               || (n_diodes + n_NPNs == child->n_diodes + child->n_NPNs && n_capacitors < child->n_capacitors))) {
+
+               int ret = ses_path_xchg(parent, child->parent_p0, child, 0);
+               if (ret < 0)
+                       return ret;
+
+               int old_parent_p1 = child->parent_p1;
+               j                 = child->parent_p1 - child->parent_p0 + 1;
+               child->parent_p1  = parent->pins->size - 1;
+
+               while (j < child->pins->size) {
+                       p0   = child->pins->data[j];
+
+                       assert(0 == scf_vector_del(child->pins, p0));
+
+                       ret = scf_vector_add(parent->pins, p0);
+                       if (ret < 0)
+                               return ret;
+               }
+
+               parent->n_NPNs   += child->n_NPNs - n_NPNs;
+               child ->n_NPNs    = n_NPNs;
+
+               parent->n_diodes += child->n_diodes - n_diodes;
+               child ->n_diodes  = n_diodes;
+
+               parent->n_capacitors += child->n_capacitors - n_capacitors;
+               child ->n_capacitors  = n_capacitors;
+
+               for (j = 0; j < parent->childs->size; ) {
+                       path      = parent->childs->data[j];
+
+                       if (path == child) {
+                               j++;
+                               continue;
+                       }
+
+                       if (path->parent_p1 <= child->parent_p0) {
+                               j++;
+                               continue;
+                       }
+
+                       if (path->parent_p0 >= child->parent_p1) {
+                               path->parent_p0 += child->parent_p1 - old_parent_p1;
+                               path->parent_p1 += child->parent_p1 - old_parent_p1;
+                               j++;
+                               continue;
+                       }
+
+                       if (path->parent_p0 == child->parent_p0 && path->parent_p1 == old_parent_p1) {
+
+                               assert(0 == scf_vector_del(parent->childs, path));
+
+                               ret = ses_path_add(child, path, f);
+                               if (ret < 0)
+                                       return ret;
+                               continue;
+                       }
+
+                       cp0 = path->pins->data[0];
+                       cp1 = path->pins->data[path->pins->size - 1];
+
+                       path->parent_p0 = -1;
+                       path->parent_p1 = -1;
+
+                       int k;
+                       for (k = 0; k < parent->pins->size; k++) {
+                               p0 =        parent->pins->data[k];
+
+                               if (p0->lid == cp0->lid) {
+                                       path->parent_p0 = k;
+                                       continue;
+                               }
+
+                               if (p0->lid == cp1->lid) {
+                                       path->parent_p1 = k;
+                                       break;
+                               }
+                       }
+
+                       if (-1 == path->parent_p0 || -1 == path->parent_p1) {
+                               assert(0 == scf_vector_del(parent->childs, path));
+
+                               if (!parent->bridges) {
+                                       parent->bridges = scf_vector_alloc();
+                                       if (!parent->bridges)
+                                               return -ENOMEM;
+                               }
+
+                               ret = scf_vector_add(parent->bridges, path);
+                               if (ret < 0)
+                                       return ret;
+                       } else
+                               j++;
+               }
+
+               if (child->childs) {
+                       for (j = 0; j < child->childs->size; ) {
+                               path      = child->childs->data[j];
+
+                               cp0 = path->pins->data[0];
+                               cp1 = path->pins->data[path->pins->size - 1];
+
+                               path->parent_p0 = -1;
+                               path->parent_p1 = -1;
+
+                               int k;
+                               for (k = 0; k < child->pins->size; k++) {
+                                       p0 =        child->pins->data[k];
+
+                                       if (p0->lid == cp0->lid) {
+                                               path->parent_p0 = k;
+                                               continue;
+                                       }
+
+                                       if (p0->lid == cp1->lid) {
+                                               path->parent_p1 = k;
+                                               break;
+                                       }
+                               }
+
+                               if (-1 == path->parent_p0 || -1 == path->parent_p1) {
+                                       assert(0 == scf_vector_del(child->childs, path));
+
+                                       ret = ses_path_add(parent, path, f);
+                                       if (ret < 0)
+                                               return ret;
+                               } else
+                                       j++;
+                       }
+               }
+       }
+
+       child->parent = parent;
+       child->type   = SES_PATH_BRANCH;
+       return 0;
+}
+
+static int __ses_path_save(ScfEfunction* f, ses_path_t* path, scf_vector_t* vec)
+{
+       ses_path_t*    child;
+       ses_data_t*    d;
+
+       ScfEcomponent* c;
+       ScfEpin*       p;
+
+       int i;
+       int j;
+
+       for (i = 0; i < path->pins->size; i += 2) {
+               p  =        path->pins->data[i];
+
+               c  = f->components[p->cid];
+               d  = NULL;
+
+               if (SCF_EDA_NPN == c->type) {
+                       for (j = vec->size - 1; j >= 0; j--) {
+                               d  = vec->data[j];
+
+                               if (d->id == c->id)
+                                       goto save_pins;
+                       }
+               }
+
+               d = malloc(sizeof(ses_data_t) * (1 + c->n_pins));
+               if (!d)
+                       return -ENOMEM;
+
+               int ret = scf_vector_add(vec, d);
+               if (ret < 0) {
+                       free(d);
+                       return ret;
+               }
+
+               d->id = c->id;
+               d->dr = c->dr;
+               d->v  = c->v;
+               d->a  = c->a;
+               d->n_pins = c->n_pins;
+
+save_pins:
+               for (j = 0; j < c->n_pins; j++) {
+                       p  =        c->pins[j];
+
+                       d->pins[j].id = p->id;
+                       d->pins[j].dr = p->dr;
+                       d->pins[j].v  = p->v;
+                       d->pins[j].a  = p->a;
+                       d->pins[j].n_pins = 0;
+               }
+       }
+
+       if (path->childs) {
+               for (i = 0; i < path->childs->size; i++) {
+                       child     = path->childs->data[i];
+
+                       int ret = __ses_path_save(f, child, vec);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
+
+       return 0;
+}
+
+int ses_path_save(ScfEfunction* f, ses_path_t* path, scf_vector_t** data)
+{
+       if (!f || !path || !data)
+               return -EINVAL;
+
+       scf_vector_t* vec = scf_vector_alloc();
+       if (!vec)
+               return -ENOMEM;
+
+       int ret = __ses_path_save(f, path, vec);
+       if (ret < 0) {
+               scf_vector_clear(vec, (void (*)(void*) )free);
+               scf_vector_free(vec);
+               return ret;
+       }
+
+       *data = vec;
+       return 0;
+}
+
+void ses_data_free(scf_vector_t* vec)
+{
+       if (vec) {
+               scf_vector_clear(vec, (void (*)(void*) )free);
+               scf_vector_free(vec);
+       }
+}
+
+void ses_data_print(scf_vector_t* vec)
+{
+       __ses_data_t* p;
+       ses_data_t*   c;
+       int i;
+       int j;
+
+       if (vec) {
+               for (i = 0; i < vec->size; i++) {
+                       c  =        vec->data[i];
+
+                       printf("c%ld->v: %lg, a: %lg, dr: %lg\n", c->id, c->v, c->a, c->dr);
+
+                       for (j = 0; j < c->n_pins; j++) {
+                               p  =       &c->pins[j];
+
+                               printf("c%ldp%ld->v: %lg, a: %lg, dr: %lg\n", c->id, p->id, p->v, p->a, p->dr);
+                       }
+                       printf("\n");
+               }
+       }
+}
+
+int ses_path_load(ScfEfunction* f, ses_path_t* path, scf_vector_t* data)
+{
+       if (!f || !path || !data)
+               return -EINVAL;
+
+       ses_data_t*    d;
+       ScfEcomponent* c;
+       ScfEpin*       p;
+
+       int i;
+       int j;
+
+       for (i = 0; i < data->size; i++) {
+               d  =        data->data[i];
+
+               c     = f->components[d->id];
+               c->v  = d->v;
+               c->a  = d->a;
+               c->dr = d->dr;
+
+               assert(d->n_pins == c->n_pins);
+
+               for (j = 0; j < c->n_pins; j++) {
+                       p  =        c->pins[j];
+
+                       p->v  = d->pins[j].v;
+                       p->a  = d->pins[j].a;
+                       p->dr = d->pins[j].dr;
+               }
+       }
+
+       return 0;
+}
diff --git a/ses_step_a_stat.c b/ses_step_a_stat.c
new file mode 100644 (file)
index 0000000..5064415
--- /dev/null
@@ -0,0 +1,60 @@
+#include"ses_core.h"
+
+static int _a_stat_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx)
+{
+       ses_path_t*    path;
+
+       ScfEcomponent* B = f->components[0];
+       ScfEcomponent* c;
+       ScfEline*      el;
+       ScfEpin*       p;
+       ScfEpin*       p0;
+       ScfEpin*       p1;
+       ScfEpin*       Bp = B->pins[SCF_EDA_Battery_POS];
+       ScfEpin*       Bn = B->pins[SCF_EDA_Battery_NEG];
+
+       int i;
+       for (i = 1; i < f->n_components; i++) {
+               c  =        f->components[i];
+
+               if (SCF_EDA_NPN == c->type) {
+
+                       p  = c->pins[SCF_EDA_NPN_B];
+                       el = f->elines[p->lid];
+                       el->aout += p->a;
+
+                       p  = c->pins[SCF_EDA_NPN_C];
+                       el = f->elines[p->lid];
+                       el->aout += p->a;
+
+                       p    = c->pins[SCF_EDA_NPN_E];
+                       p->a = c->pins[SCF_EDA_NPN_B]->a + c->pins[SCF_EDA_NPN_C]->a;
+                       el   = f->elines[p->lid];
+                       el->ain += p->a;
+                       continue;
+               }
+
+               if (c->a > 0) {
+                       el = f->elines[c->pins[0]->lid];
+                       el->ain += c->a;
+
+                       el = f->elines[c->pins[1]->lid];
+                       el->aout += c->a;
+               } else {
+                       el = f->elines[c->pins[0]->lid];
+                       el->aout -= c->a;
+
+                       el = f->elines[c->pins[1]->lid];
+                       el->ain -= c->a;
+               }
+       }
+
+       return 0;
+}
+
+ses_step_t  ses_step_a_stat =
+{
+       .name    = "a_stat",
+
+       .handler = _a_stat_handler,
+};
index 4ada12b765c23441e7ad0d5d1619c4e643e83fe1..e13c1d0f7556899cc477fcbe6e63ce8501ea9dda 100644 (file)
@@ -45,7 +45,7 @@ static int _dc_transistor_handler(ScfEfunction* f, int64_t ns, int64_t count, se
                        continue;
                }
 
-               scf_logi("c%ld, status: %d, lock: %d, pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\n",
+               scf_logd("c%ld, status: %d, lock: %d, pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\n",
                                c->id, c->status, c->lock, pb->v, pe->v, pb->v - pe->v, SCF_EDA_V_NPN_OFF);
 
                if (lb->v < SCF_EDA_V_MIN) {
index ea709a979e82c230680741ec3229ac0a1da1b6ea..9086dd440765f25849c81d6dae79d2764643a0be 100644 (file)
@@ -25,46 +25,24 @@ void __ses_path_pr(ScfEfunction* f, ses_path_t* path, int i, int j, ses_path_t*
        ScfEpin* p0 = path->pins->data[i];
        ScfEpin* p1 = path->pins->data[j];
 
-       if (!child) {
-               *r = p1->pr - p0->pr;
-
-               scf_logd("c%ldp%ld-c%ldp%ld, r: %lg, p0->pr: %lg, p1->pr: %lg\n",
-                               p0->cid, p0->id, p1->cid, p1->id, *r, p0->pr, p1->pr);
-       } else {
+       if (child) {
                *r = child->parent_pr - p0->pr;
 
                scf_logd("c%ldp%ld-c%ldp%ld, r: %lg, p0->pr: %lg, p1->pr: %lg, child->parent_pr: %lg\n",
                                p0->cid, p0->id, p1->cid, p1->id, *r, p0->pr, p1->pr, child->parent_pr);
+               return;
        }
-}
-
-void __ses_path_jsr(ScfEfunction* f, ses_path_t* path, int i, int j, double* jr)
-{
-       ScfEpin* p0 = path->pins->data[i];
-       ScfEpin* p1 = path->pins->data[j];
-
-       *jr = p1->jsr - p0->jpr;
-
-       scf_logd("c%ldp%ld-c%ldp%ld, jr: %lg, p0->jsr: %lg, p0->jpr: %lg, p1->jsr: %lg, p1->jpr: %lg\n",
-                       p0->cid, p0->id, p1->cid, p1->id, *jr, p0->jsr, p0->jpr, p1->jsr, p1->jpr);
-}
-
-void __ses_path_jpr(ScfEfunction* f, ses_path_t* path, int i, int j, ses_path_t* child, double* jr)
-{
-       ScfEpin* p0 = path->pins->data[i];
-       ScfEpin* p1 = path->pins->data[j];
 
-       if (!child) {
-               *jr = p1->jpr - p0->jpr;
+       child = ses_path_find_child(path, i, j);
+       if (child) {
+               *r = child->parent_pr - p0->pr;
+               return;
+       }
 
-               scf_logd("c%ldp%ld-c%ldp%ld, jr: %lg, p0->jpr: %lg, p1->jpr: %lg\n",
-                               p0->cid, p0->id, p1->cid, p1->id, *jr, p0->jpr, p1->jpr);
-       } else {
-               *jr = child->parent_jpr - p0->jpr;
+       *r = p1->sr - p0->pr;
 
-               scf_logd("c%ldp%ld-c%ldp%ld, jr: %lg, p0->jpr: %lg, p1->jpr: %lg, child->parent_jpr: %lg\n",
-                               p0->cid, p0->id, p1->cid, p1->id, *jr, p0->jpr, p1->jpr, child->parent_jpr);
-       }
+       scf_logd("c%ldp%ld-c%ldp%ld, r: %lg, p0->pr: %lg, p1->sr: %lg\n",
+                       p0->cid, p0->id, p1->cid, p1->id, *r, p0->pr, p1->sr);
 }
 
 int __ses_path_jr(ScfEfunction* f, ses_path_t* path)
@@ -88,9 +66,6 @@ int __ses_path_jr(ScfEfunction* f, ses_path_t* path)
        double r;
        double r2;
 
-       double jr;
-       double jr2;
-
        int    i;
        int    j;
 
@@ -105,36 +80,27 @@ int __ses_path_jr(ScfEfunction* f, ses_path_t* path)
        }
 
        r  = 0;
-       jr = 0;
 
        for (i = 0; i < path->pins->size; i++) {
                p  =        path->pins->data[i];
 
                c  = f->components[p->cid];
                r2 = r;
-               r += p->r + p->dr + p->jdr;
-
-               jr2 = jr;
-               jr += p->r + p->dr;
+               r += p->r + p->dr;
 
                if (i & 0x1) {
-                       r  += c->r + c->dr + c->jdr;
-                       jr += c->r + c->dr;
+                       r += c->r + c->dr;
                }
 
-               if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_E != p->id) {
+               if (SCF_EDA_NPN == c->type && !(i & 0x1)) {
                        p->sr  = r2;
                        p->pr  = r2;
-                       p->jsr = jr2;
-                       p->jpr = jr2;
                } else {
                        p->sr  = r;
                        p->pr  = r;
-                       p->jsr = jr;
-                       p->jpr = jr;
                }
 
-               scf_loge("path: %d, i: %d, c%ldp%ld, sr: %lg, jsr: %lg\n", path->index, i, p->cid, p->id, p->sr, p->jsr);
+               scf_loge("path: %d, i: %d, c%ldp%ld, sr: %lg\n", path->index, i, p->cid, p->id, p->sr);
        }
 
        if (path->childs) {
@@ -176,40 +142,28 @@ int __ses_path_jr(ScfEfunction* f, ses_path_t* path)
                        if (!p1)
                                return -EINVAL;
 
-                       double pr;
-                       double jpr;
-
-                       __ses_path_pr (f, path, k, j, NULL, &pr);
-                       __ses_path_jpr(f, path, k, j, NULL, &jpr);
+                       double pr = p1->pr - p0->pr;
 
-                       ses_merge_r(&r,  NULL, pr,  0, child->pr,  0);
-                       ses_merge_r(&jr, NULL, jpr, 0, child->jpr, 0);
+                       ses_merge_r(&r, NULL, pr, 0, child->pr, 0);
 
-                       double dr  = pr  - r;
-                       double jdr = jpr - jr;
+                       double dr = pr - r;
 
-                       p1->pr  -= dr;
-                       p1->jpr -= jdr;
+                       p1->pr -= dr;
 
-                       child->parent_pr  = p1->pr;
-                       child->parent_jpr = p1->jpr;
+                       child->parent_pr = p1->pr;
 
-                       scf_logi("j: %d, c%ldp%ld,  p->pr: %lg,  p->sr: %lg,  pr: %lg,  dr: %lg\n", j, p1->cid, p1->id, p1->pr, p1->sr, pr, dr);
-                       scf_logi("j: %d, c%ldp%ld, p->jpr: %lg, p->jsr: %lg, jpr: %lg, jdr: %lg\n", j, p1->cid, p1->id, p1->jpr, p1->jsr, jpr, jdr);
+                       scf_logi("j: %d, c%ldp%ld, p->pr: %lg, p->sr: %lg, pr: %lg, dr: %lg\n", j, p1->cid, p1->id, p1->pr, p1->sr, pr, dr);
 
                        for (++j; j < path->pins->size; j++) {
                                p       = path->pins->data[j];
 
-                               p->pr  -= dr;
-                               p->sr  -= dr;
-                               p->jpr -= jdr;
-                               p->jsr -= jdr;
+                               p->pr -= dr;
+                               p->sr -= dr;
 
-                               scf_logd("j: %d, c%ldp%ld,  p->pr: %lg,  p->sr: %lg\n", j, p->cid, p->id, p->pr, p->sr);
-                               scf_logd("j: %d, c%ldp%ld, p->jpr: %lg, p->jsr: %lg\n", j, p->cid, p->id, p->jpr, p->jsr);
+                               scf_logi("j: %d, c%ldp%ld,  p->pr: %lg,  p->sr: %lg\n", j, p->cid, p->id, p->pr, p->sr);
                        }
 
-                       scf_logw("child: %d, pr: %lg, dr: %lg, jpr: %lg, jdr: %lg\n", child->index, child->pr, dr, child->jpr, jdr);
+                       scf_logw("child: %d, pr: %lg, dr: %lg\n", child->index, child->pr, dr);
                }
        }
 
@@ -224,20 +178,17 @@ int __ses_path_jr(ScfEfunction* f, ses_path_t* path)
 
                                if (p->lid == cp1->lid) {
                                        child->parent_pr  = p->pr;
-                                       child->parent_jpr = p->jpr;
                                        break;
                                }
                        }
                }
        }
 
-       p         = path->pins->data[path->pins->size - 1];
-       path->pr  = p->pr;
-       path->sr  = p->sr;
-       path->jpr = p->jpr;
-       path->jsr = p->jsr;
+       p        = path->pins->data[path->pins->size - 1];
+       path->pr = p->pr;
+       path->sr = p->sr;
 
-       scf_loge("path: %d, pr: %lg, sr: %lg, jpr: %lg, jsr: %lg\n\n", path->index, path->pr, path->sr, path->jpr, path->jsr);
+       scf_loge("path: %d, pr: %lg, sr: %lg\n\n", path->index, path->pr, path->sr);
        return 0;
 }
 
index d0e611ebfa062837eb895340dec752cde563e2f3..a0a9ae4acf26ad76de4f3e59a121c98d173c448d 100644 (file)
@@ -167,20 +167,18 @@ static int _open_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t*
                if (el->flags & (SCF_EDA_PIN_IN | SCF_EDA_PIN_POS | SCF_EDA_PIN_NEG))
                        continue;
 
-               if (el->v > SCF_EDA_V_MIN)
-                       continue;
-
                if (__ses_path_pos(f, el)) {
 
-                       if (!__ses_path_neg(f, el))
+                       if (!__ses_path_neg(f, el)) {
                                el->v = Bp->v;
 
-               } else if (__ses_path_neg(f, el))
+                               scf_logw("e%ld->v: %lg\n", el->id, el->v);
+                       }
+               } else if (__ses_path_neg(f, el)) {
                        el->v = Bn->v;
-               else
-                       return -EINVAL;
 
-               scf_logw("e%ld->v: %lg\n", el->id, el->v);
+                       scf_logw("e%ld->v: %lg\n", el->id, el->v);
+               }
        }
 
        printf("\n");
index a9be82dc74ffc486dde7ab5e25bee93edfb72222..0352d1c6614adaf362911a4b49929d24ba1b906c 100644 (file)
@@ -1,6 +1,90 @@
 #include<cairo/cairo.h>
 #include"ses_core.h"
 
+static void ses_text_cda(cairo_t* cr, int x, int y, double a)
+{
+       char text[64];
+
+       cairo_set_source_rgb(cr, 0.0, 0.7, 0.0);
+
+       if (a > 1e-1 || a < -1e-1) {
+               snprintf(text, sizeof(text) - 1, "%lgA", (int)(a * 1000) / 1000.0);
+
+               cairo_move_to  (cr, x, y);
+               cairo_show_text(cr, text);
+
+       } else if (a > 1e-5 || a < -1e-5) {
+               snprintf(text, sizeof(text) - 1, "%lgmA", (int)(a * 1000000) / 1000.0);
+
+               cairo_move_to  (cr, x, y);
+               cairo_show_text(cr, text);
+
+       } else {
+               snprintf(text, sizeof(text) - 1, "%lguA", (int64_t)(a * 1000000000LL) / 1000.0);
+
+               cairo_move_to  (cr, x, y);
+               cairo_show_text(cr, text);
+       }
+}
+
+static void ses_text_a(cairo_t* cr, int x, int y, double a)
+{
+       char text[64];
+
+       if (a > 0)
+               cairo_set_source_rgb(cr, 0.7, 0.0, 0.0);
+       else
+               cairo_set_source_rgb(cr, 0.0, 0.0, 0.7);
+
+       if (a > 1e-1 || a < -1e-1) {
+               snprintf(text, sizeof(text) - 1, "%lgA", (int)(a * 1000) / 1000.0);
+
+               cairo_move_to  (cr, x, y);
+               cairo_show_text(cr, text);
+
+       } else if (a > 1e-5 || a < -1e-5) {
+               snprintf(text, sizeof(text) - 1, "%lgmA", (int)(a * 1000000) / 1000.0);
+
+               cairo_move_to  (cr, x, y);
+               cairo_show_text(cr, text);
+
+       } else if (a > 1e-9 || a < -1e-9) {
+               snprintf(text, sizeof(text) - 1, "%lguA", (int64_t)(a * 1000000000LL) / 1000.0);
+
+               cairo_move_to  (cr, x, y);
+               cairo_show_text(cr, text);
+       }
+}
+
+static void ses_text_v(cairo_t* cr, int x, int y, double v)
+{
+       char text[64];
+
+       if (v > 0)
+               cairo_set_source_rgb(cr, 0.7, 0.0, 0.0);
+       else
+               cairo_set_source_rgb(cr, 0.0, 0.0, 0.7);
+
+       if (v > 1e-1 || v < -1e-1) {
+               snprintf(text, sizeof(text) - 1, "%lgv", (int)(v * 1000) / 1000.0);
+
+               cairo_move_to  (cr, x, y);
+               cairo_show_text(cr, text);
+
+       } else if (v > 1e-5 || v < -1e-5) {
+               snprintf(text, sizeof(text) - 1, "%lgmV", (int)(v * 1000000) / 1000.0);
+
+               cairo_move_to  (cr, x, y);
+               cairo_show_text(cr, text);
+
+       } else if (v > 1e-9 || v < -1e-9) {
+               snprintf(text, sizeof(text) - 1, "%lguV", (int64_t)(v * 1000000000LL) / 1000.0);
+
+               cairo_move_to  (cr, x, y);
+               cairo_show_text(cr, text);
+       }
+}
+
 void __ses_function_draw(ScfEfunction* f, cairo_t* cr)
 {
        ScfEcomponent*   c;
@@ -132,24 +216,10 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr)
                                cairo_line_to(cr, p->x, p->y);
                                cairo_stroke(cr);
 
-                               if (c->v > 0)
-                                       cairo_set_source_rgb(cr, 0.7, 0.0, 0.0);
-                               else
-                                       cairo_set_source_rgb(cr, 0.0, 0.0, 0.7);
                                cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
 
-                               if (c->v > 1e-3 || c->v < -1e-3) {
-                                       snprintf(text, sizeof(text) - 1, "%lgv", (int)(c->v * 1000) / 1000.0);
-
-                                       cairo_move_to  (cr, c->x + 10, c->y + 10);
-                                       cairo_show_text(cr, text);
-
-                               } else if (c->v > 1e-6 || c->v < -1e-6) {
-                                       snprintf(text, sizeof(text) - 1, "%lgmV", (int)(c->v * 1000000) / 1000.0);
-
-                                       cairo_move_to  (cr, c->x + 10, c->y + 10);
-                                       cairo_show_text(cr, text);
-                               }
+                               ses_text_v(cr, c->x + 10, c->y + 10, c->v);
+                               ses_text_a(cr, c->x + 10, c->y + 25, c->a);
 
                                cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
 
@@ -163,14 +233,22 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr)
                        case SCF_EDA_Resistor:
                                p = c->pins[0];
 
-                               vertical(&dx0, &dy0, c->x - p->x, c->y - p->y, 3);
-                               forward (&dx1, &dy1, c->x - p->x, c->y - p->y, 6);
+                               vertical(&dx0, &dy0, c->x - p->x, c->y - p->y, 6);
+                               forward (&dx1, &dy1, c->x - p->x, c->y - p->y, 12);
 
-                               cairo_move_to    (cr,  p->x,       p->y);
-                               cairo_line_to    (cr,  c->x - dx1, c->y - dy1);
+                               cairo_move_to(cr, p->x,       p->y);
+                               cairo_line_to(cr, c->x - dx1, c->y - dy1);
+                               cairo_stroke(cr);
 
-                               cairo_rel_move_to(cr,  dx0,        dy0);
+                               cairo_set_source_rgb(cr, 0.0, 0.0, 0.8);
+
+                               cairo_move_to    (cr,  c->x - dx1 + dx0, c->y - dy1 + dy0);
                                cairo_rel_line_to(cr, -dx0 * 2,   -dy0 * 2);
+                               cairo_stroke(cr);
+
+                               cairo_set_source_rgb(cr, 0.6, 0.6, 0.0);
+
+                               cairo_move_to    (cr,  c->x - dx1 - dx0, c->y - dy1 - dy0);
                                cairo_rel_line_to(cr,  dx1 * 2,    dy1 * 2);
                                cairo_rel_line_to(cr,  dx0 * 2,    dy0 * 2);
                                cairo_rel_line_to(cr, -dx1 * 2,   -dy1 * 2);
@@ -180,14 +258,16 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr)
                                cairo_line_to    (cr,  c->x + dx1, c->y + dy1);
                                cairo_stroke(cr);
 
+                               cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+
+                               ses_text_a(cr, c->x + 10, c->y + 25, c->a);
+
+                               cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
                                if (c->r > 1e6)
                                        snprintf(text, sizeof(text) - 1, "%dM", (int)(c->r / 1000000.0));
                                else
                                        snprintf(text, sizeof(text) - 1, "%dk", (int)(c->r / 1000.0));
 
-                               cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
-                               cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
-
                                cairo_move_to  (cr, c->x + 4, c->y - 5);
                                cairo_show_text(cr, text);
                                cairo_stroke(cr);
@@ -214,6 +294,7 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr)
                                cairo_rel_move_to(cr,  dx0,         dy0);
                                cairo_rel_line_to(cr, -dx0 * 2,    -dy0 * 2);
 
+                               ses_text_a(cr, c->x + 10, c->y + 25, c->a);
                                cairo_stroke(cr);
                                break;
 
@@ -270,6 +351,12 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr)
                                        cairo_line_to(cr, c->x - dx3 + dx4 - dx1,  c->y - dy3 + dy4 - dy1);
                                        cairo_stroke(cr);
                                }
+
+                               cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+                               ses_text_a(cr, c->x, (pb->y + c->y) / 2, pb->a);
+                               ses_text_a(cr, c->x,  c->y,              pc->a);
+                               ses_text_a(cr, c->x, (pe->y + c->y) / 2, pe->a);
+                               cairo_stroke(cr);
                                break;
                        default:
                                break;
@@ -277,7 +364,7 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* cr)
        }
 }
 
-static int _simplify_draw(ScfEfunction* f, uint32_t bx, uint32_t by, uint32_t bw, uint32_t bh, int64_t count)
+int ses_simplify_draw(ScfEfunction* f, const char* file, uint32_t bx, uint32_t by, uint32_t bw, uint32_t bh)
 {
        ScfEcomponent*   B;
        ScfEcomponent*   c;
@@ -330,8 +417,6 @@ static int _simplify_draw(ScfEfunction* f, uint32_t bx, uint32_t by, uint32_t bw
                else
                        cairo_set_source_rgb(cr, 1, 0.5, 0.1);
 
-               cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
-
                uint8_t  text[64];
                ScfLine* prev = NULL;
 
@@ -342,25 +427,49 @@ static int _simplify_draw(ScfEfunction* f, uint32_t bx, uint32_t by, uint32_t bw
                                continue;
 
                        if (!prev) {
+                               if (el->vconst)
+                                       cairo_select_font_face(cr, "Calibri", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+                               else
+                                       cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+
                                cairo_set_font_size(cr, 28);
+
                                int n = snprintf(text, sizeof(text) - 1, "%ld", el->id);
 
                                cairo_move_to  (cr, l->x0 - 10 - n * 12, l->y0 + 10);
                                cairo_show_text(cr, text);
                                cairo_stroke(cr);
 
+                               // V of line
                                if (el->v < SCF_EDA_V_MIN)
-                                       snprintf(text, sizeof(text) - 1, "0v");
+                                       n = snprintf(text, sizeof(text) - 1, "0v");
                                else if (el->v > SCF_EDA_V_MAX)
-                                       snprintf(text, sizeof(text) - 1, "%lgv", B->pins[SCF_EDA_Battery_POS]->v);
+                                       n = snprintf(text, sizeof(text) - 1, "%lgv", B->pins[SCF_EDA_Battery_POS]->v);
+
+                               else if (el->v > 1e-2 || el->v < -1e-2)
+                                       n = snprintf(text, sizeof(text) - 1, "%lgv", (int)(el->v * 1000) / 1000.0);
+
+                               else if (el->v > 1e-5 || el->v < -1e-5)
+                                       n = snprintf(text, sizeof(text) - 1, "%lgmV", (int)(el->v * 1000000) / 1000.0);
+                               else
+                                       n = snprintf(text, sizeof(text) - 1, "%lguV", (int64_t)(el->v * 1000000000LL) / 1000.0);
+
+                               // A of line
+                               if (el->aout > 1e-1 || el->aout < -1e-1)
+                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", %lgA", (int)(el->aout * 1000) / 1000.0);
 
-                               else if (el->v > 1e-3 || el->v < -1e-3)
-                                       snprintf(text, sizeof(text) - 1, "%lgv", (int)(el->v * 1000) / 1000.0);
+                               else if (el->aout > 1e-5 || el->aout < -1e-5)
+                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", %lgmA", (int)(el->aout * 1000000) / 1000.0);
+                               else
+                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", %lguA", (int64_t)(el->aout * 1000000000LL) / 1000.0);
+
+                               if (el->ain > 1e-1 || el->ain < -1e-1)
+                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lgA", (int)(el->ain * 1000) / 1000.0);
 
-                               else if (el->v > 1e-6 || el->v < -1e-6)
-                                       snprintf(text, sizeof(text) - 1, "%lgmV", (int)(el->v * 1000000) / 1000.0);
+                               else if (el->ain > 1e-5 || el->ain < -1e-5)
+                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lgmA", (int)(el->ain * 1000000) / 1000.0);
                                else
-                                       snprintf(text, sizeof(text) - 1, "%lguV", (int)(el->v * 1000000) / 1000000.0);
+                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lguA", (int64_t)(el->ain * 1000000000LL) / 1000.0);
 
                                int cx = INT_MAX;
                                int cy = l->y0;
@@ -374,14 +483,17 @@ static int _simplify_draw(ScfEfunction* f, uint32_t bx, uint32_t by, uint32_t bw
                                        }
                                }
 
+                               if (INT_MAX == cx)
+                                       cx = l->x0;
+
                                cairo_set_font_size(cr, 20);
 
                                if (cy > l->y0) {
-                                       cairo_move_to  (cr, cx - 20, l->y0 - 8);
+                                       cairo_move_to  (cr, cx - 40, l->y0 - 8);
                                        cairo_show_text(cr, text);
                                        cairo_stroke(cr);
                                } else {
-                                       cairo_move_to  (cr, cx - 20, l->y0 + 24);
+                                       cairo_move_to  (cr, cx - 40, l->y0 + 24);
                                        cairo_show_text(cr, text);
                                        cairo_stroke(cr);
                                }
@@ -407,9 +519,6 @@ static int _simplify_draw(ScfEfunction* f, uint32_t bx, uint32_t by, uint32_t bw
 
        __ses_function_draw(f, cr);
 
-       char file[128];
-       snprintf(file, sizeof(file) - 1, "./simplify_%ld.png", count);
-
        cairo_surface_write_to_png(surface, file);
 
        cairo_destroy(cr);
@@ -419,7 +528,27 @@ static int _simplify_draw(ScfEfunction* f, uint32_t bx, uint32_t by, uint32_t bw
 
 static int _simplify_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx)
 {
-       _simplify_draw(f, f->x, f->y, f->w, f->h, count);
+       ScfEline* el;
+
+       int i;
+#if 0
+       for (i = 0; i < f->n_elines; i++) {
+               el =        f->elines[i];
+
+               if (el->flags & SCF_EDA_PIN_OUT) {
+                       if (el->v < 1)
+                               return 0;
+                       else
+                               break;
+               }
+       }
+#endif
+
+       char file[128];
+       snprintf(file, sizeof(file) - 1, "./simplify_%ld.png", count);
+
+       if (count % 100 < 5)
+               ses_simplify_draw(f, file, f->x, f->y, f->w, f->h);
        return 0;
 }
 
diff --git a/ses_step_simplify2.c b/ses_step_simplify2.c
new file mode 100644 (file)
index 0000000..afdc666
--- /dev/null
@@ -0,0 +1,551 @@
+#include<cairo/cairo.h>
+#include"ses_core.h"
+
+static void ses_text_cda(cairo_t* cr, int x, int y, double a)
+{
+       char text[64];
+
+       cairo_set_source_rgb(cr, 0.0, 0.7, 0.0);
+
+       if (a > 1e-1 || a < -1e-1) {
+               snprintf(text, sizeof(text) - 1, "%lgA", (int)(a * 1000) / 1000.0);
+
+               cairo_move_to  (cr, x, y);
+               cairo_show_text(cr, text);
+
+       } else if (a > 1e-5 || a < -1e-5) {
+               snprintf(text, sizeof(text) - 1, "%lgmA", (int)(a * 1000000) / 1000.0);
+
+               cairo_move_to  (cr, x, y);
+               cairo_show_text(cr, text);
+
+       } else {
+               snprintf(text, sizeof(text) - 1, "%lguA", (int64_t)(a * 1000000000LL) / 1000.0);
+
+               cairo_move_to  (cr, x, y);
+               cairo_show_text(cr, text);
+       }
+}
+
+static void ses_text_a(cairo_t* cr, int x, int y, double a)
+{
+       char text[64];
+
+       if (a > 0)
+               cairo_set_source_rgb(cr, 0.7, 0.0, 0.0);
+       else
+               cairo_set_source_rgb(cr, 0.0, 0.0, 0.7);
+
+       if (a > 1e-1 || a < -1e-1) {
+               snprintf(text, sizeof(text) - 1, "%lgA", (int)(a * 1000) / 1000.0);
+
+               cairo_move_to  (cr, x, y);
+               cairo_show_text(cr, text);
+
+       } else if (a > 1e-5 || a < -1e-5) {
+               snprintf(text, sizeof(text) - 1, "%lgmA", (int)(a * 1000000) / 1000.0);
+
+               cairo_move_to  (cr, x, y);
+               cairo_show_text(cr, text);
+
+       } else if (a > 1e-9 || a < -1e-9) {
+               snprintf(text, sizeof(text) - 1, "%lguA", (int64_t)(a * 1000000000LL) / 1000.0);
+
+               cairo_move_to  (cr, x, y);
+               cairo_show_text(cr, text);
+       }
+}
+
+static void ses_text_v(cairo_t* cr, int x, int y, double v)
+{
+       char text[64];
+
+       if (v > 0)
+               cairo_set_source_rgb(cr, 0.7, 0.0, 0.0);
+       else
+               cairo_set_source_rgb(cr, 0.0, 0.0, 0.7);
+
+       if (v > 1e-1 || v < -1e-1) {
+               snprintf(text, sizeof(text) - 1, "%lgv", (int)(v * 1000) / 1000.0);
+
+               cairo_move_to  (cr, x, y);
+               cairo_show_text(cr, text);
+
+       } else if (v > 1e-5 || v < -1e-5) {
+               snprintf(text, sizeof(text) - 1, "%lgmV", (int)(v * 1000000) / 1000.0);
+
+               cairo_move_to  (cr, x, y);
+               cairo_show_text(cr, text);
+       }
+}
+
+static void __ses_function_draw(ScfEfunction* f, cairo_t* cr)
+{
+       ScfEcomponent*   c;
+       ScfEpin*         p;
+       ScfEpin*         pb;
+       ScfEpin*         pc;
+       ScfEpin*         pe;
+
+       size_t j;
+       size_t k;
+
+       for (j = 0; j < f->n_components; j++) {
+               c  =        f->components[j];
+
+               cairo_set_line_width(cr, 2.5);
+
+               uint8_t text[64];
+               int n = snprintf(text, sizeof(text) - 1, "%ld", c->id);
+
+               cairo_set_source_rgb  (cr, 0, 0, 0);
+               cairo_select_font_face(cr, "Calibri", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+               cairo_set_font_size   (cr, 20);
+               cairo_move_to         (cr, c->x - 10 - n * 10, c->y - 5);
+               cairo_show_text       (cr, text);
+               cairo_stroke(cr);
+
+               if ((SCF_EDA_Diode == c->type || SCF_EDA_NPN == c->type) && SCF_EDA_Status_OFF == c->status)
+                       cairo_set_source_rgb(cr, 0.0, 0.6, 0.6);
+               else
+                       cairo_set_source_rgb(cr, 0.6, 0.6, 0.0);
+
+               for (k = 0; k < c->n_pins; k++) {
+                       p  =        c->pins[k];
+
+                       cairo_arc (cr, p->x, p->y, 4, 0, 2 * M_PI);
+                       cairo_fill(cr);
+               }
+               cairo_stroke(cr);
+
+               int dx0;
+               int dy0;
+
+               int dx1;
+               int dy1;
+               int dx2;
+               int dy2;
+
+               int dx3;
+               int dy3;
+               int dx4;
+               int dy4;
+
+               switch (c->type) {
+
+                       case SCF_EDA_Battery:
+                               p = c->pins[SCF_EDA_Battery_POS];
+
+                               if (p->y < c->y) {
+                                       cairo_move_to(cr, c->x - 12, c->y - 5);
+                                       cairo_line_to(cr, c->x + 12, c->y - 5);
+
+                                       cairo_move_to(cr, c->x, c->y - 5);
+                                       cairo_line_to(cr, p->x, p->y);
+
+                                       cairo_move_to(cr, c->x - 8, c->y + 5);
+                                       cairo_line_to(cr, c->x + 8, c->y + 5);
+
+                                       p = c->pins[SCF_EDA_Battery_NEG];
+                                       cairo_move_to(cr, c->x, c->y + 5);
+                                       cairo_line_to(cr, p->x, p->y);
+
+                               } else {
+                                       cairo_move_to(cr, c->x - 12, c->y + 5);
+                                       cairo_line_to(cr, c->x + 12, c->y + 5);
+
+                                       cairo_move_to(cr, c->x, c->y + 5);
+                                       cairo_line_to(cr, p->x, p->y);
+
+                                       cairo_move_to(cr, c->x - 8, c->y - 5);
+                                       cairo_line_to(cr, c->x + 8, c->y - 5);
+
+                                       p = c->pins[SCF_EDA_Battery_NEG];
+                                       cairo_move_to(cr, c->x, c->y - 5);
+                                       cairo_line_to(cr, p->x, p->y);
+                               }
+
+                               cairo_stroke(cr);
+                               break;
+
+                       case SCF_EDA_Capacitor:
+
+                               cairo_set_source_rgb(cr, 0.8, 0.0, 0.0);
+                               p = c->pins[SCF_EDA_Battery_POS];
+                               if (p->y < c->y) {
+                                       cairo_move_to(cr, c->x - 8, c->y - 5);
+                                       cairo_line_to(cr, c->x + 8, c->y - 5);
+                                       cairo_stroke(cr);
+
+                                       cairo_set_source_rgb(cr, 0.6, 0.6, 0.0);
+                                       cairo_move_to(cr, c->x, c->y - 5);
+                               } else {
+                                       cairo_move_to(cr, c->x - 8, c->y + 5);
+                                       cairo_line_to(cr, c->x + 8, c->y + 5);
+                                       cairo_stroke(cr);
+
+                                       cairo_set_source_rgb(cr, 0.6, 0.6, 0.0);
+                                       cairo_move_to(cr, c->x, c->y + 5);
+                               }
+                               cairo_line_to(cr, p->x, p->y);
+                               cairo_stroke(cr);
+
+                               cairo_set_source_rgb(cr, 0.0, 0.0, 0.8);
+                               p = c->pins[SCF_EDA_Battery_NEG];
+                               if (p->y < c->y) {
+                                       cairo_move_to(cr, c->x - 8, c->y - 5);
+                                       cairo_line_to(cr, c->x + 8, c->y - 5);
+                                       cairo_stroke(cr);
+
+                                       cairo_set_source_rgb(cr, 0.6, 0.6, 0.0);
+                                       cairo_move_to(cr, c->x, c->y - 5);
+                               } else {
+                                       cairo_move_to(cr, c->x - 8, c->y + 5);
+                                       cairo_line_to(cr, c->x + 8, c->y + 5);
+                                       cairo_stroke(cr);
+
+                                       cairo_set_source_rgb(cr, 0.6, 0.6, 0.0);
+                                       cairo_move_to(cr, c->x, c->y + 5);
+                               }
+                               cairo_line_to(cr, p->x, p->y);
+                               cairo_stroke(cr);
+
+                               cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+
+                               ses_text_v(cr, c->x + 10, c->y + 10, c->v);
+                               ses_text_a(cr, c->x + 10, c->y + 25, c->a);
+
+                               cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
+
+                               snprintf(text, sizeof(text) - 1, "%lguf", c->uf);
+
+                               cairo_move_to  (cr, c->x + 4, c->y - 5);
+                               cairo_show_text(cr, text);
+                               cairo_stroke(cr);
+                               break;
+
+                       case SCF_EDA_Resistor:
+                               p = c->pins[0];
+
+                               vertical(&dx0, &dy0, c->x - p->x, c->y - p->y, 6);
+                               forward (&dx1, &dy1, c->x - p->x, c->y - p->y, 12);
+
+                               cairo_move_to(cr, p->x,       p->y);
+                               cairo_line_to(cr, c->x - dx1, c->y - dy1);
+                               cairo_stroke(cr);
+
+                               cairo_set_source_rgb(cr, 0.0, 0.0, 0.8);
+
+                               cairo_move_to    (cr,  c->x - dx1 + dx0, c->y - dy1 + dy0);
+                               cairo_rel_line_to(cr, -dx0 * 2,   -dy0 * 2);
+                               cairo_stroke(cr);
+
+                               cairo_set_source_rgb(cr, 0.6, 0.6, 0.0);
+
+                               cairo_move_to    (cr,  c->x - dx1 - dx0, c->y - dy1 - dy0);
+                               cairo_rel_line_to(cr,  dx1 * 2,    dy1 * 2);
+                               cairo_rel_line_to(cr,  dx0 * 2,    dy0 * 2);
+                               cairo_rel_line_to(cr, -dx1 * 2,   -dy1 * 2);
+
+                               p = c->pins[1];
+                               cairo_move_to    (cr,  p->x,       p->y);
+                               cairo_line_to    (cr,  c->x + dx1, c->y + dy1);
+                               cairo_stroke(cr);
+
+                               cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+
+                               ses_text_a(cr, c->x + 10, c->y + 25, c->a);
+
+                               cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
+                               if (c->r > 1e6)
+                                       snprintf(text, sizeof(text) - 1, "%dM", (int)(c->r / 1000000.0));
+                               else
+                                       snprintf(text, sizeof(text) - 1, "%dk", (int)(c->r / 1000.0));
+
+                               cairo_move_to  (cr, c->x + 4, c->y - 5);
+                               cairo_show_text(cr, text);
+                               cairo_stroke(cr);
+                               break;
+
+                       case SCF_EDA_Diode:
+                               p = c->pins[SCF_EDA_Diode_POS];
+
+                               vertical(&dx0, &dy0, c->x - p->x, c->y - p->y,  6);
+                               forward (&dx1, &dy1, c->x - p->x, c->y - p->y,  6);
+
+                               cairo_move_to(cr, p->x,       p->y);
+                               cairo_line_to(cr, c->x - dx1, c->y - dy1);
+
+                               cairo_rel_move_to(cr,  dx0,              dy0);
+                               cairo_rel_line_to(cr, -dx0 * 2,         -dy0 * 2);
+                               cairo_line_to    (cr,  c->x + dx1,       c->y + dy1);
+                               cairo_line_to    (cr,  c->x + dx0 - dx1, c->y + dy0 - dy1);
+
+                               p = c->pins[SCF_EDA_Diode_NEG];
+
+                               cairo_move_to    (cr,  p->x,        p->y);
+                               cairo_line_to    (cr,  c->x + dx1,  c->y + dy1);
+                               cairo_rel_move_to(cr,  dx0,         dy0);
+                               cairo_rel_line_to(cr, -dx0 * 2,    -dy0 * 2);
+
+                               ses_text_a(cr, c->x + 10, c->y + 25, c->a);
+                               cairo_stroke(cr);
+                               break;
+
+                       case SCF_EDA_NPN:
+                               pb = c->pins[SCF_EDA_NPN_B];
+                               pc = c->pins[SCF_EDA_NPN_C];
+                               pe = c->pins[SCF_EDA_NPN_E];
+
+                               vertical(&dx0, &dy0, c->x - pb->x, c->y - pb->y,  8);
+                               forward (&dx3, &dy3, c->x - pb->x, c->y - pb->y,  8);
+
+                               cairo_arc(cr, c->x - dx3 / 2, c->y - dy3 / 2, 12, 0, 2 * M_PI);
+
+                               cairo_move_to    (cr,  pb->x,       pb->y);
+                               cairo_line_to    (cr,  c->x - dx3,  c->y - dy3);
+                               cairo_rel_move_to(cr,  dx0,         dy0);
+                               cairo_rel_line_to(cr, -dx0 * 2,    -dy0 * 2);
+                               cairo_stroke(cr);
+
+                               if ((c->x + dx3 + dx0 > c->x + dx3 - dx0 && pe->x > pc->x)
+                                               || (c->x + dx3 + dx0 < c->x + dx3 - dx0 && pe->x < pc->x)) {
+
+                                       cairo_move_to(cr, c->x - dx3,       c->y - dy3);
+                                       cairo_line_to(cr, c->x + dx3 + dx0, c->y + dy3 + dy0);
+                                       cairo_line_to(cr, pe->x, pe->y);
+
+                                       vertical(&dx1, &dy1, dx3 * 2 + dx0, dy3 * 2 + dy0, 3);
+                                       forward (&dx4, &dy4, dx3 * 2 + dx0, dy3 * 2 + dy0, 8);
+
+                                       cairo_move_to(cr, c->x - dx3 + dx4 + dx1,  c->y - dy3 + dy4 + dy1);
+                                       cairo_line_to(cr, c->x + dx3 + dx0,        c->y + dy3 + dy0);
+                                       cairo_line_to(cr, c->x - dx3 + dx4 - dx1,  c->y - dy3 + dy4 - dy1);
+                                       cairo_stroke(cr);
+
+                                       cairo_move_to(cr, c->x - dx3,        c->y - dy3);
+                                       cairo_line_to(cr, c->x + dx3 - dx0,  c->y + dy3 - dy0);
+                                       cairo_line_to(cr, pc->x, pc->y);
+                                       cairo_stroke(cr);
+                               } else {
+                                       cairo_move_to(cr, c->x - dx3,       c->y - dy3);
+                                       cairo_line_to(cr, c->x + dx3 + dx0, c->y + dy3 + dy0);
+                                       cairo_line_to(cr, pc->x, pc->y);
+                                       cairo_stroke(cr);
+
+                                       cairo_move_to(cr, c->x - dx3,        c->y - dy3);
+                                       cairo_line_to(cr, c->x + dx3 - dx0,  c->y + dy3 - dy0);
+                                       cairo_line_to(cr, pe->x, pe->y);
+
+                                       vertical(&dx1, &dy1, dx3 * 2 - dx0, dy3 * 2 - dy0, 3);
+                                       forward (&dx4, &dy4, dx3 * 2 - dx0, dy3 * 2 - dy0, 8);
+
+                                       cairo_move_to(cr, c->x - dx3 + dx4 + dx1,  c->y - dy3 + dy4 + dy1);
+                                       cairo_line_to(cr, c->x + dx3 - dx0,        c->y + dy3 - dy0);
+                                       cairo_line_to(cr, c->x - dx3 + dx4 - dx1,  c->y - dy3 + dy4 - dy1);
+                                       cairo_stroke(cr);
+                               }
+
+                               cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+                               ses_text_a(cr, c->x, (pb->y + c->y) / 2, pb->a);
+                               ses_text_a(cr, c->x,  c->y,              pc->a);
+                               ses_text_a(cr, c->x, (pe->y + c->y) / 2, pe->a);
+                               cairo_stroke(cr);
+                               break;
+                       default:
+                               break;
+               };
+       }
+}
+
+static int _simplify_draw(ScfEfunction* f, uint32_t bx, uint32_t by, uint32_t bw, uint32_t bh, int64_t count)
+{
+       ScfEcomponent*   B;
+       ScfEcomponent*   c;
+       ScfEline*        el;
+       ScfLine*         l;
+
+       cairo_surface_t* surface;
+       cairo_t*         cr;
+
+       surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, bx + bw, by + bh);
+       cr      = cairo_create (surface);
+
+       cairo_set_line_width(cr, 2);
+       cairo_set_source_rgb(cr, 1, 1, 1);
+       cairo_rectangle     (cr, 0, 0, bx + bw, by + bh);
+       cairo_fill(cr);
+       cairo_stroke(cr);
+
+       long i;
+       long j;
+       long k;
+
+       B = f->components[0];
+
+       for (j = 0; j < f->n_elines; j++) {
+               el =        f->elines[j];
+
+               cairo_set_line_width(cr, 2);
+
+               if (SCF_EDA_PIN_POS & el->flags)
+                       cairo_set_source_rgb(cr, 1, 0, 0);
+
+               else if (SCF_EDA_PIN_NEG & el->flags)
+                       cairo_set_source_rgb(cr, 0, 0, 1);
+
+               else if (SCF_EDA_PIN_OUT & el->flags)
+                       cairo_set_source_rgb(cr, 1, 0, 1);
+
+               else if (el->v == B->pins[SCF_EDA_Battery_POS]->v)
+                       cairo_set_source_rgb(cr, 0.8, 0, 0);
+
+               else if (el->v == B->pins[SCF_EDA_Battery_NEG]->v)
+                       cairo_set_source_rgb(cr, 0, 0, 0.8);
+
+               else if (SCF_EDA_PIN_IN & el->flags)
+                       cairo_set_source_rgb(cr, 0, 1, 0);
+
+               else if (SCF_EDA_PIN_CF & el->flags)
+                       cairo_set_source_rgb(cr, 0.8, 0, 1.0);
+               else
+                       cairo_set_source_rgb(cr, 1, 0.5, 0.1);
+
+               uint8_t  text[64];
+               ScfLine* prev = NULL;
+
+               for (k = 0; k < el->n_lines; k++) {
+                       l  =        el->lines[k];
+
+                       if (l->x0 > l->x1)
+                               continue;
+
+                       if (!prev) {
+                               if (el->vconst)
+                                       cairo_select_font_face(cr, "Calibri", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+                               else
+                                       cairo_select_font_face(cr, "Georgia", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
+
+                               cairo_set_font_size(cr, 28);
+
+                               int n = snprintf(text, sizeof(text) - 1, "%ld", el->id);
+
+                               cairo_move_to  (cr, l->x0 - 10 - n * 12, l->y0 + 10);
+                               cairo_show_text(cr, text);
+                               cairo_stroke(cr);
+
+                               // V of line
+                               if (el->v < SCF_EDA_V_MIN)
+                                       n = snprintf(text, sizeof(text) - 1, "0v");
+                               else if (el->v > SCF_EDA_V_MAX)
+                                       n = snprintf(text, sizeof(text) - 1, "%lgv", B->pins[SCF_EDA_Battery_POS]->v);
+
+                               else if (el->v > 1e-2 || el->v < -1e-2)
+                                       n = snprintf(text, sizeof(text) - 1, "%lgv", (int)(el->v * 1000) / 1000.0);
+
+                               else if (el->v > 1e-5 || el->v < -1e-5)
+                                       n = snprintf(text, sizeof(text) - 1, "%lgmV", (int)(el->v * 1000000) / 1000.0);
+                               else
+                                       n = snprintf(text, sizeof(text) - 1, "%lguV", (int64_t)(el->v * 1000000000LL) / 1000.0);
+
+                               // A of line
+                               if (el->aout > 1e-1 || el->aout < -1e-1)
+                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", %lgA", (int)(el->aout * 1000) / 1000.0);
+
+                               else if (el->aout > 1e-5 || el->aout < -1e-5)
+                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", %lgmA", (int)(el->aout * 1000000) / 1000.0);
+                               else
+                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", %lguA", (int64_t)(el->aout * 1000000000LL) / 1000.0);
+
+                               if (el->ain > 1e-1 || el->ain < -1e-1)
+                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lgA", (int)(el->ain * 1000) / 1000.0);
+
+                               else if (el->ain > 1e-5 || el->ain < -1e-5)
+                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lgmA", (int)(el->ain * 1000000) / 1000.0);
+                               else
+                                       n += snprintf(text + n, sizeof(text) - 1 - n, ", in %lguA", (int64_t)(el->ain * 1000000000LL) / 1000.0);
+
+                               int cx = INT_MAX;
+                               int cy = l->y0;
+
+                               for (i = 0; i < el->n_pins; i += 2) {
+                                       c = f->components[el->pins[i]];
+
+                                       if (c->x > l->x0 && c->x < cx) {
+                                               cx = c->x;
+                                               cy = c->y;
+                                       }
+                               }
+
+                               cairo_set_font_size(cr, 20);
+
+                               if (cy > l->y0) {
+                                       cairo_move_to  (cr, cx - 40, l->y0 - 8);
+                                       cairo_show_text(cr, text);
+                                       cairo_stroke(cr);
+                               } else {
+                                       cairo_move_to  (cr, cx - 40, l->y0 + 24);
+                                       cairo_show_text(cr, text);
+                                       cairo_stroke(cr);
+                               }
+                       }
+
+                       cairo_set_line_width(cr, 4);
+                       cairo_move_to(cr, l->x0, l->y0);
+                       cairo_line_to(cr, l->x1, l->y1);
+                       cairo_stroke(cr);
+
+                       if (prev) {
+                               if (!(el->flags & SCF_EDA_PIN_BORDER))
+                                       cairo_set_line_width(cr, 1);
+
+                               cairo_move_to(cr, prev->x0, prev->y0);
+                               cairo_line_to(cr, l->x0,    l->y0);
+                               cairo_stroke(cr);
+                       }
+
+                       prev = l;
+               }
+       }
+
+       __ses_function_draw(f, cr);
+
+       char file[128];
+       snprintf(file, sizeof(file) - 1, "./simplify2_%ld.png", count);
+
+       cairo_surface_write_to_png(surface, file);
+
+       cairo_destroy(cr);
+       cairo_surface_destroy(surface);
+       return 0;
+}
+
+static int _simplify_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx)
+{
+       ScfEline* el;
+
+       int i;
+#if 0
+       for (i = 0; i < f->n_elines; i++) {
+               el =        f->elines[i];
+
+               if (el->flags & SCF_EDA_PIN_OUT) {
+                       if (el->v < 1)
+                               return 0;
+                       else
+                               break;
+               }
+       }
+#endif
+
+//     if (count % 5000 == 0)
+               _simplify_draw(f, f->x, f->y, f->w, f->h, count);
+       return 0;
+}
+
+ses_step_t   ses_step_simplify2 =
+{
+       .name    = "simplify2",
+
+       .handler = _simplify_handler,
+};
diff --git a/ses_step_status.c b/ses_step_status.c
new file mode 100644 (file)
index 0000000..01ee0f9
--- /dev/null
@@ -0,0 +1,129 @@
+#include"ses_core.h"
+
+int __ses_path_status(ScfEfunction* f, ses_path_t* bridge, int* changed, scf_vector_t* paths, int64_t ns, int64_t count)
+{
+       ScfEcomponent* B;
+       ScfEline*      el;
+       ScfEpin*       Bp;
+       ScfEpin*       Bn;
+       ScfEpin*       p0;
+       ScfEpin*       p1;
+
+       B  = f->components[0];
+       Bp = B->pins[SCF_EDA_Battery_POS];
+       Bn = B->pins[SCF_EDA_Battery_NEG];
+
+       p0 = bridge->pins->data[0];
+       p1 = bridge->pins->data[bridge->pins->size - 1];
+
+       if (p0->lid == Bp->lid && p1->lid == Bn->lid)
+               return 0;
+
+       el     = f->elines[p0->lid];
+       p0->v  = el->v;
+
+       el     = f->elines[p1->lid];
+       p1->v  = el->v;
+
+       if (p0->v < SCF_EDA_V_MIN || p1->v < SCF_EDA_V_MIN)
+               return 0;
+
+       int __changed = 0;
+
+       __ses_path_jr(f, bridge);
+
+       if (bridge->n_diodes + bridge->n_NPNs > 0) {
+               __ses_path_va_diode(f, bridge);
+               __ses_path_jr      (f, bridge);
+       }
+
+       if (bridge->n_transistors > 0) {
+               __ses_path_va_transistor(f, bridge);
+               __ses_path_jr           (f, bridge);
+       }
+
+       int ret = __ses_path_va(f, bridge, &__changed, ns, count);
+       if (ret < 0)
+               return ret;
+
+       *changed += __changed;
+
+       scf_loge("bridge: %d, c%ldp%ld--c%ldp%ld, __changed: %d, p0->v: %lg, p1->v: %lg, n_diodes: %d, n_NPNs: %d, p0->a: %lg, p1->a: %lg\n\n",
+                       bridge->index, p0->cid, p0->id, p1->cid, p1->id, __changed, p0->v, p1->v, bridge->n_diodes, bridge->n_NPNs, p0->a, p1->a);
+
+       bridge->vflag = 0;
+       return 0;
+}
+
+static int ses_path_status(ScfEfunction* f, ses_path_t* path, int* changed, scf_vector_t* paths, int64_t ns, int64_t count)
+{
+       ses_path_t* child;
+
+       int ret;
+       int j;
+
+       if (!path)
+               return -EINVAL;
+
+       if (0 == path->n_capacitors) {
+
+               ret = __ses_path_status(f, path, changed, paths, ns, count);
+               if (ret < 0)
+                       return ret;
+       }
+
+       if (path->bridges) {
+               scf_vector_t* vec = scf_vector_alloc();
+               if (!vec)
+                       return -ENOMEM;
+
+               ret = scf_vector_add(vec, path);
+               if (ret < 0) {
+                       scf_vector_free(vec);
+                       return ret;
+               }
+
+               for (j = 0; j < path->bridges->size; j++) {
+                       child     = path->bridges->data[j];
+
+                       ret = ses_path_status(f, child, changed, vec, ns, count);
+                       if (ret < 0) {
+                               scf_vector_free(vec);
+                               return ret;
+                       }
+               }
+
+               scf_vector_free(vec);
+               vec = NULL;
+       }
+
+       return 0;
+}
+
+static int _status_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx)
+{
+       ses_path_t* path;
+
+       int changed = 0;
+       int i;
+
+       for (i = 0; i < ctx->paths->size; i++) {
+               path      = ctx->paths->data[i];
+
+               scf_logi("i: %d, path->index: %d\n", i, path->index);
+
+               int ret = ses_path_status(f, path, &changed, ctx->paths, ns, count);
+               if (ret < 0)
+                       return ret;
+       }
+
+       ctx->changed += changed;
+       return 0;
+}
+
+ses_step_t  ses_step_status =
+{
+       .name    = "status",
+
+       .handler = _status_handler,
+};
index ca44eabe8cedd3233eb9ed5f504602ffebf0fd80..c4faeccb4c3f5ce4102660cb1a72fcc281e713a6 100644 (file)
@@ -1,11 +1,12 @@
 #include"ses_core.h"
 
-int __dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_vector_t* __paths, ses_path_t** ppath)
+static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_vector_t* __paths, ses_path_t** ppath)
 {
        ScfEcomponent*   c;
        ScfEline*        el;
        ScfEpin*         np;
        ScfEpin*         p;
+       ScfEpin*         p2;
 
        size_t i;
        size_t j;
@@ -68,21 +69,19 @@ int __dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_vector_t* __
                if (SCF_EDA_NPN != rc->type || SCF_EDA_NPN_E != np->id)
                        np->vflag = 1;
 
-               if ((SCF_EDA_PIN_NEG & el->flags) || SCF_EDA_Capacitor == rc->type) {
+               if (SCF_EDA_PIN_NEG & el->flags) {
 
                        if (scf_vector_add(__paths, *ppath) < 0)
                                return -ENOMEM;
 
                        for (j = 0; j < (*ppath)->pins->size; j++) {
-                               p         = (*ppath)->pins->data[j];
-                               p->pflag  = 1;
-                               p->path   = (uintptr_t)*ppath;
+                               p2        = (*ppath)->pins->data[j];
+                               p2->pflag = 1;
+                               p2->path  = (uintptr_t)*ppath;
                        }
 
                        *ppath = NULL;
-
-                       if (SCF_EDA_PIN_NEG & el->flags)
-                               return 0;
+                       return 0;
                }
 
                ret = 0;
@@ -101,9 +100,9 @@ int __dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_vector_t* __
                                                        return -ENOMEM;
 
                                                for (k = 0; k < (*ppath)->pins->size; k++) {
-                                                       p         = (*ppath)->pins->data[k];
-                                                       p->pflag  = 1;
-                                                       p->path   = (uintptr_t)*ppath;
+                                                       p2        = (*ppath)->pins->data[k];
+                                                       p2->pflag = 1;
+                                                       p2->path  = (uintptr_t)*ppath;
                                                }
                                        } else
                                                ses_path_free(*ppath);
@@ -116,10 +115,25 @@ int __dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_vector_t* __
                        if (p->vflag)
                                continue;
 
+                       if (SCF_EDA_Capacitor == rc->type && SCF_EDA_Capacitor != c->type) {
+                               if (*ppath) {
+                                       if (scf_vector_add(__paths, *ppath) < 0)
+                                               return -ENOMEM;
+
+                                       for (j = 0; j < (*ppath)->pins->size; j++) {
+                                               p2        = (*ppath)->pins->data[j];
+                                               p2->pflag = 1;
+                                               p2->path  = (uintptr_t)*ppath;
+                                       }
+
+                                       *ppath = NULL;
+                               }
+                       }
+
                        if (SCF_EDA_NPN != c->type || SCF_EDA_NPN_E != p->id)
                                p->vflag = 1;
 
-                       ret = __dfs_path(f, c, p, __paths, ppath);
+                       ret = __ses_dfs_path(f, c, p, __paths, ppath);
                        if (ret < 0)
                                return ret;
 
@@ -154,6 +168,34 @@ int __dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_vector_t* __
        return ret;
 }
 
+static int ses_pin_to_npn(const ScfEfunction* f, const ScfEpin* vip, int pid)
+{
+       const ScfEcomponent* c;
+       const ScfEline*      el = f->elines[vip->lid];
+       const ScfEpin*       p;
+
+       int i;
+       for (i = 0; i < el->n_pins; i += 2) {
+
+               c  = f->components[el->pins[i]];
+               p  = c->pins      [el->pins[i + 1]];
+
+               if (p != vip && SCF_EDA_NPN == c->type && pid == p->id)
+                       return 1;
+       }
+
+       return 0;
+}
+
+static int ses_path_to_npn(const ScfEfunction* f, const ses_path_t* path, int pid)
+{
+       const ScfEpin* p0 = path->pins->data[0];
+       const ScfEpin* p1 = path->pins->data[path->pins->size - 1];
+
+       return ses_pin_to_npn(f, p0, pid) || ses_pin_to_npn(f, p1, pid);
+}
+
+
 static int _ses_child_cmp(const void* v0, const void* v1)
 {
        const ses_path_t* p0 = *(const ses_path_t**)v0;
@@ -224,6 +266,7 @@ static int __topo_path_bridges(ScfEfunction* f, ses_path_t* path)
                                continue;
                        }
 
+                       // positive pin of path
                        p0 = sp0->pins->data[0];
                        p1 = sp1->pins->data[0];
 
@@ -250,6 +293,47 @@ static int __topo_path_bridges(ScfEfunction* f, ses_path_t* path)
                         || (SCF_EDA_NPN   == c1->type && SCF_EDA_NPN_B     == p1->id))
                                goto bridge_sp0;
 
+                       if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_B))
+                               goto bridge_sp1;
+                       if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_B))
+                               goto bridge_sp0;
+
+                       if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_C))
+                               goto bridge_sp1;
+                       if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_C))
+                               goto bridge_sp0;
+
+                       // negative pin of path
+                       p0 = sp0->pins->data[sp0->pins->size - 1];
+                       p1 = sp1->pins->data[sp1->pins->size - 1];
+
+                       if (SCF_EDA_PIN_IN & p0->flags)
+                               goto bridge_sp1;
+
+                       if (SCF_EDA_PIN_IN & p1->flags)
+                               goto bridge_sp0;
+
+                       if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_B))
+                               goto bridge_sp1;
+                       if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_B))
+                               goto bridge_sp0;
+
+                       if (ses_pin_to_npn(f, p0, SCF_EDA_NPN_C))
+                               goto bridge_sp1;
+                       if (ses_pin_to_npn(f, p1, SCF_EDA_NPN_C))
+                               goto bridge_sp0;
+
+                       c0 = f->components[p0->cid];
+                       c1 = f->components[p1->cid];
+
+                       if ((SCF_EDA_Diode == c0->type && SCF_EDA_Diode_NEG == p0->id)
+                        || (SCF_EDA_NPN   == c0->type && SCF_EDA_NPN_E     == p0->id))
+                               goto bridge_sp1;
+
+                       if ((SCF_EDA_Diode == c1->type && SCF_EDA_Diode_NEG == p1->id)
+                        || (SCF_EDA_NPN   == c1->type && SCF_EDA_NPN_E     == p1->id))
+                               goto bridge_sp0;
+
 bridge_sp1:
                        scf_vector_del(path->childs, sp1);
                        if (scf_vector_add(path->bridges, sp1) < 0)
@@ -298,33 +382,6 @@ static int _topo_path_bridges(ScfEfunction* f, ses_path_t* path)
        return __topo_path_bridges(f, path);
 }
 
-static int ses_pin_to_npn(const ScfEfunction* f, const ScfEpin* vip, int pid)
-{
-       const ScfEcomponent* c;
-       const ScfEline*      el = f->elines[vip->lid];
-       const ScfEpin*       p;
-
-       int i;
-       for (i = 0; i < el->n_pins; i += 2) {
-
-               c  = f->components[el->pins[i]];
-               p  = c->pins      [el->pins[i + 1]];
-
-               if (p != vip && SCF_EDA_NPN == c->type && pid == p->id)
-                       return 1;
-       }
-
-       return 0;
-}
-
-static int ses_path_to_npn(const ScfEfunction* f, const ses_path_t* path, int pid)
-{
-       const ScfEpin* p0 = path->pins->data[0];
-       const ScfEpin* p1 = path->pins->data[path->pins->size - 1];
-
-       return ses_pin_to_npn(f, p0, pid) || ses_pin_to_npn(f, p1, pid);
-}
-
 static int _ses_connect_cmp(const void* v0, const void* v1, void* arg)
 {
        const ScfEfunction* f  = arg;
@@ -332,9 +389,21 @@ static int _ses_connect_cmp(const void* v0, const void* v1, void* arg)
        const ses_path_t*   p0 = *(const ses_path_t**)v0;
        const ses_path_t*   p1 = *(const ses_path_t**)v1;
 
-       if (0 == p0->n_capacitors)
+       if (0 == p0->n_capacitors) {
+               if (0 == p1->n_capacitors) {
+
+                       if (ses_path_to_npn(f, p0, SCF_EDA_NPN_B))
+                               return -1;
+                       if (ses_path_to_npn(f, p1, SCF_EDA_NPN_B))
+                               return 1;
+
+                       if (ses_path_to_npn(f, p0, SCF_EDA_NPN_C))
+                               return -1;
+                       if (ses_path_to_npn(f, p1, SCF_EDA_NPN_C))
+                               return 1;
+               }
                return -1;
-       if (0 == p1->n_capacitors)
+       } else if (0 == p1->n_capacitors)
                return 1;
 
        if (ses_path_to_npn(f, p0, SCF_EDA_NPN_C))
@@ -343,13 +412,13 @@ static int _ses_connect_cmp(const void* v0, const void* v1, void* arg)
                return 1;
 
        if (ses_path_to_npn(f, p0, SCF_EDA_NPN_B))
-               return -1;
-       if (ses_path_to_npn(f, p1, SCF_EDA_NPN_B))
                return 1;
-
-       if (p0->n_capacitors < p1->n_capacitors)
+       if (ses_path_to_npn(f, p1, SCF_EDA_NPN_B))
                return -1;
+
        if (p0->n_capacitors > p1->n_capacitors)
+               return -1;
+       if (p0->n_capacitors < p1->n_capacitors)
                return 1;
        return 0;
 }
@@ -418,7 +487,7 @@ static int _topo_path_connect(ScfEfunction* f, scf_vector_t* paths)
 
                        } else if (p3->lid == p1->lid) {
 
-                               if (path0->n_diodes > 0 || path0->n_transistors > 0)
+                               if (path0->n_diodes + path0->n_NPNs > 0 || path0->n_transistors > 0)
                                        continue;
 
                                for (k = path0->pins->size - 1; k >= 0; k--) {
@@ -442,7 +511,7 @@ static int _topo_path_connect(ScfEfunction* f, scf_vector_t* paths)
 
                        } else if (p2->lid == p0->lid) {
 
-                               if (path0->n_diodes > 0 || path0->n_transistors > 0)
+                               if (path0->n_diodes + path0->n_NPNs > 0 || path0->n_transistors > 0)
                                        continue;
 
                                m = path0->pins->size - 1;
@@ -485,6 +554,51 @@ error:
        return -ENOMEM;
 }
 
+static int _topo_fix_complete(scf_vector_t* paths, ses_path_t* parent)
+{
+       ses_path_t* child;
+
+       int i;
+
+       if (parent->childs) {
+
+               for (i = 0; i < parent->childs->size; ) {
+                       child     = parent->childs->data[i];
+
+                       if (ses_path_is_child(parent, child))
+                               i++;
+                       else {
+                               int ret = scf_vector_add(paths, child);
+                               if (ret < 0)
+                                       return ret;
+
+                               assert(0 == scf_vector_del(parent->childs, child));
+                               child->parent = NULL;
+                       }
+               }
+       }
+
+       if (parent->bridges) {
+
+               for (i = 0; i < parent->bridges->size; ) {
+                       child     = parent->bridges->data[i];
+
+                       if (ses_path_is_child(parent, child))
+                               i++;
+                       else {
+                               int ret = scf_vector_add(paths, child);
+                               if (ret < 0)
+                                       return ret;
+
+                               assert(0 == scf_vector_del(parent->bridges, child));
+                               child->parent = NULL;
+                       }
+               }
+       }
+
+       return 0;
+}
+
 static int _topo_path_completes(ScfEfunction* f, scf_vector_t* paths)
 {
        if (!f || !paths)
@@ -555,6 +669,14 @@ static int _topo_path_completes(ScfEfunction* f, scf_vector_t* paths)
                                if (ret < 0)
                                        return ret;
 
+                               ret = _topo_fix_complete(paths, path1);
+                               if (ret < 0)
+                                       return ret;
+
+                               ret = _topo_fix_complete(paths, path0);
+                               if (ret < 0)
+                                       return ret;
+
                                if (path0->pins->size <= 0) {
                                        if (scf_vector_del(paths, path0) < 0)
                                                return -1;
@@ -581,6 +703,14 @@ static int _topo_path_completes(ScfEfunction* f, scf_vector_t* paths)
                                if (ret < 0)
                                        return ret;
 
+                               ret = _topo_fix_complete(paths, path1);
+                               if (ret < 0)
+                                       return ret;
+
+                               ret = _topo_fix_complete(paths, path0);
+                               if (ret < 0)
+                                       return ret;
+
                                if (path0->pins->size <= 0) {
                                        if (scf_vector_del(paths, path0) < 0)
                                                return -1;
@@ -636,6 +766,7 @@ static int __topo_path_key_infos(ScfEfunction* f, ses_path_t* path)
 
        scf_vector_clear(path->infos, ( void (*)(void*) )free);
        path->n_diodes = 0;
+       path->n_NPNs   = 0;
 
        for (i = 0; i < path->pins->size; i++) {
                p  =        path->pins->data[i];
@@ -676,7 +807,7 @@ static int __topo_path_key_infos(ScfEfunction* f, ses_path_t* path)
                                }
 
                                info->n_NPNs++;
-                               path->n_diodes++;
+                               path->n_NPNs++;
                                continue;
 
                        } else if (SCF_EDA_NPN_E == p->id) {
@@ -850,9 +981,9 @@ static int topo_epin_cmp(const void* v0, const void* v1, void* arg)
                return 1;
 
        if (SCF_EDA_Capacitor == c0->type)
-               return 1;
-       if (SCF_EDA_Capacitor == c1->type)
                return -1;
+       if (SCF_EDA_Capacitor == c1->type)
+               return 1;
 
        return 0;
 }
@@ -864,7 +995,8 @@ static void _topo_key_components(ScfEfunction* f, ses_path_t* path)
 
        int i;
 
-       path->n_diodes     = 0;
+       path->n_NPNs   = 0;
+       path->n_diodes = 0;
        path->n_capacitors = 0;
 
        for (i = 0; i < path->pins->size; i++) {
@@ -880,7 +1012,7 @@ static void _topo_key_components(ScfEfunction* f, ses_path_t* path)
                } else if (SCF_EDA_NPN == c->type) {
 
                        if (SCF_EDA_NPN_B == p->id)
-                               path->n_diodes++;
+                               path->n_NPNs++;
 
                        else if (SCF_EDA_NPN_C == p->id)
                                path->n_transistors++;
@@ -921,6 +1053,8 @@ static void _topo_clear(ScfEfunction* f)
 
        for (i = 0; i < f->n_elines; i++) {
                el        = f->elines[i];
+               el->ain   = 0;
+               el->aout  = 0;
                el->vflag = 0;
 
                qsort_r(el->pins, el->n_pins / 2, sizeof(uint64_t) * 2, topo_epin_cmp, f);
@@ -930,13 +1064,14 @@ static void _topo_clear(ScfEfunction* f)
                c         = f->components[i];
                c->vflag  = 0;
                c->lock   = 0;
+               c->a      = 0;
 
                for (j = 0; j < c->n_pins; j++) {
                        p         = c->pins[j];
                        p->vflag  = 0;
                        p->pflag  = 0;
                        p->dr     = 0;
-                       p->jdr    = 0;
+                       p->a      = 0;
                }
        }
 }
@@ -964,7 +1099,7 @@ static int _topo_paths(ScfEfunction* f, ScfEline* el, scf_vector_t* paths)
                if (c == B)
                        continue;
 
-               int ret = __dfs_path(f, c, p, paths, &path);
+               int ret = __ses_dfs_path(f, c, p, paths, &path);
                if (ret < 0)
                        return ret;
 
index 29d5518c048d3f4b9345bc2895c18ae7fb45b4b8..8f5cbc2beed39a419532ddabd83612027993d05b 100644 (file)
@@ -1,6 +1,7 @@
 #include"ses_core.h"
 
-static int __ses_path_split_a(ScfEfunction* f, ses_path_t* path, int i, int n, double* a, int* changed, int64_t ns, int64_t count)
+static int __ses_path_split_a(ScfEfunction* f, ses_path_t* path, int i, int n,
+               double* a, int* changed, int64_t ns, int64_t count)
 {
        ses_path_t*    child;
 
@@ -36,67 +37,70 @@ static int __ses_path_split_a(ScfEfunction* f, ses_path_t* path, int i, int n, d
                if (k > n)
                        continue;
 
-               double r;
+               double sr = 0;
+               double cv = 0;
+               double dv = 0;
+               double da = 0;
+               double pr;
                double v;
 
-               if (path->n_capacitors > 0) {
-                       __ses_path_jpr(f, path, i, k, child, &r);
+               __ses_path_pr(f, path, i, k, child, &pr);
 
-                       ses_ir_u(&v, NULL, *a, 0, r, 0);
+               ses_ir_u(&v, NULL, *a, 0, pr, 0);
 
-                       ses_ur_i(&child->a0, NULL, v, 0, child->jpr, 0);
-               } else {
-                       __ses_path_pr(f, path, i, k, child, &r);
+               ses_ur_i(&child->a0, NULL, v, 0, child->pr, 0);
 
-                       ses_ir_u(&v, NULL, *a, 0, r, 0);
+               if (__ses_path_capacitors(f, path, i, k, &cv) > 0)
+                       v += cv;
 
-                       ses_ur_i(&child->a0, NULL, v, 0, child->pr, 0);
-               }
+               ses_ur_i(&child->a, NULL, v, 0, child->pr, 0);
 
-               scf_logw("child: %d, c%ldp%ld-c%ldp%ld (c%ldp%ld-c%ldp%ld, n_diodes: %d), v: %lg, a: %lg, r: %lg\n",
-                               child->index, p0->cid, p0->id, p1->cid, p1->id, cp0->cid, cp0->id, cp1->cid, cp1->id, child->n_diodes, v, *a, r);
+               scf_logw("child: %d, c%ldp%ld-c%ldp%ld (c%ldp%ld-c%ldp%ld, n_diodes: %d, n_NPNs: %d), v: %lg, cv: %lg, dv: %lg, a: %lg, pr: %lg, sr: %lg\n",
+                               child->index, p0->cid, p0->id, p1->cid, p1->id, cp0->cid, cp0->id, cp1->cid, cp1->id,
+                               child->n_diodes, child->n_NPNs, v, cv, dv, *a, pr, sr);
 
-               *a    -= child->a0;
+               *a  -= child->a0;
 
                el     = f->elines[p1->lid];
                el->v  = p0->v - v;
 
-               double _pr   = p1->pr;
-               double _sr   = p1->sr;
-               double _jpr  = p1->jpr;
-               double _jsr  = p1->jsr;
+               double _pr0  = p0->pr;
+               double _sr0  = p0->sr;
+               double _pr1  = p1->pr;
+               double _sr1  = p1->sr;
 
-               double _cpr  = cp1->pr;
-               double _csr  = cp1->sr;
-               double _cjpr = cp1->jpr;
-               double _cjsr = cp1->jsr;
+               double _cpr0 = cp0->pr;
+               double _csr0 = cp0->sr;
+               double _cpr1 = cp1->pr;
+               double _csr1 = cp1->sr;
 
+               cp0->pr  = 0;
+               cp0->sr  = 0;
                cp1->pr  = child->pr;
                cp1->sr  = child->sr;
-               cp1->jpr = child->jpr;
-               cp1->jsr = child->jsr;
 
-               if (child->n_diodes > 0) {
+               if (child->n_diodes + child->n_NPNs > 0) {
                        __ses_path_va_diode(f, child);
                        __ses_path_jr      (f, child);
                }
 
-               int ret = __ses_path_va(f, child, 0, child->pins->size - 1, changed, ns, count);
+               int ret = __ses_path_va(f, child, changed, ns, count);
                if (ret < 0)
                        return ret;
 
-               cp1->pr  = _cpr;
-               cp1->sr  = _csr;
-               cp1->jpr = _cjpr;
-               cp1->jsr = _cjsr;
+               cp0->pr = _cpr0;
+               cp0->sr = _csr0;
+               cp1->pr = _cpr1;
+               cp1->sr = _csr1;
 
-               p1->pr   = _pr;
-               p1->sr   = _sr;
-               p1->jpr  = _jpr;
-               p1->jsr  = _jsr;
+               p0->pr  = _pr0;
+               p0->sr  = _sr0;
+               p1->pr  = _pr1;
+               p1->sr  = _sr1;
 
-               scf_loge("child: %d, c%ldp%ld-c%ldp%ld (c%ldp%ld-c%ldp%ld, n_diodes: %d), p->v: %lg, v: %lg, child->a0: %lg, child->a: %lg\n\n",
-                               child->index, p0->cid, p0->id, p1->cid, p1->id, cp0->cid, cp0->id, cp1->cid, cp1->id, child->n_diodes, p0->v, v, child->a0, child->a);
+               scf_loge("child: %d, c%ldp%ld-c%ldp%ld (c%ldp%ld-c%ldp%ld, n_diodes: %d), p->v: %lg, v: %lg, child->a0: %lg, child->a: %lg, cv: %lg, cda: %lg\n\n",
+                               child->index, p0->cid, p0->id, p1->cid, p1->id, cp0->cid, cp0->id, cp1->cid, cp1->id,
+                               child->n_diodes + child->n_NPNs, p0->v, v, child->a0, child->a, cv, child->cda);
 
                n_childs++;
        }
@@ -114,10 +118,7 @@ static void __ses_path_split_v(ScfEfunction* f, ses_path_t* path, int i0, int i,
        double v;
        double r;
 
-       if (path->n_capacitors > 0)
-               __ses_path_jsr(f, path, i0, i, &r);
-       else
-               __ses_path_sr(f, path, i0, i, &r);
+       __ses_path_sr(f, path, i0, i, &r);
 
        ses_ir_u(&v, NULL, a, 0, r, 0);
 
@@ -141,13 +142,13 @@ int __ses_path_capacitors(ScfEfunction* f, ses_path_t* path, int m, int n, doubl
        int    k = 0;
        int    i;
 
-       for (i = m; i <= n; i += 2) {
+       for (i = m; i <= n; i++) {
                p  = path->pins->data[i];
 
                c  = f->components[p->cid];
 
-               if (SCF_EDA_Capacitor == c->type) {
-                       int sign = p->id - !p->id;
+               if (SCF_EDA_Capacitor == c->type && (i & 0x1)) {
+                       int sign = !p->id - p->id;
 
                        v += c->v * sign;
                        k++;
@@ -158,16 +159,19 @@ int __ses_path_capacitors(ScfEfunction* f, ses_path_t* path, int m, int n, doubl
        return k;
 }
 
-int __ses_path_va(ScfEfunction* f, ses_path_t* path, int m, int n, int* changed, int64_t ns, int64_t count)
+int __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count)
 {
        if (!path)
                return -EINVAL;
 
-       if (path->pins->size < 2 || n - m < 1) {
+       if (path->pins->size < 2) {
                scf_loge("\n");
                return -EINVAL;
        }
 
+       if (n - m < 1)
+               return 0;
+
        ses_path_t*    child;
        ScfEcomponent* c;
        ScfEcomponent* B  = f->components[0];
@@ -186,34 +190,20 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int m, int n, int* changed,
        p0 = path->pins->data[m];
        p1 = path->pins->data[n];
 
-       el     = f->elines[p0->lid];
-       p0->v  = el->v;
-
-       el     = f->elines[p1->lid];
-       p1->v  = el->v;
-
-       double pr = 0;
        double cv = 0;
        double a  = 0;
        double v  = p0->v - p1->v;
 
-       child = ses_path_find_child(path, m, n);
-
-       if (path->n_capacitors > 0) {
-               __ses_path_capacitors(f, path, m, n, &cv);
-               v -= cv;
-               __ses_path_jpr(f, path, m, n, child, &pr);
-       } else {
-               __ses_path_pr(f, path, m, n, child, &pr);
-       }
+       __ses_path_capacitors(f, path, m, n, &cv);
+       v -= cv;
 
        ses_ur_i(&a, NULL, v, 0, pr, 0);
 
        if (0 == m && path->pins->size - 1 == n)
                path->a = a;
 
-       scf_logw("path: %d, c%ldp%ld-c%ldp%ld, p0->v: %lg, p1->v: %lg, v: %lg, cv: %lg, pr: %lg, path->pr: %lg, path->jpr: %lg, a: %lg\n\n",
-                       path->index, p0->cid, p0->id, p1->cid, p1->id, p0->v, p1->v, v, cv, pr, path->pr, path->jpr, a);
+       scf_logw("path: %d, c%ldp%ld-c%ldp%ld, p0->v: %lg, p1->v: %lg, v: %lg, cv: %lg, pr: %lg, path->pr: %lg, a: %lg\n\n",
+                       path->index, p0->cid, p0->id, p1->cid, p1->id, p0->v, p1->v, v, cv, pr, path->pr, a);
 
        double r   = 0;
        double dv  = 0;
@@ -226,15 +216,20 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int m, int n, int* changed,
        for (i = m; i <= n; i++) {
                p  = path->pins->data[i];
 
+               c  = f->components[p->cid];
+
                scf_logd("c%ldp%ld, p->r: %lg, dr: %lg, sr: %lg, pr: %lg\n", p->cid, p->id, p->r, p->dr, p->sr, p->pr);
 
                __ses_path_split_v(f, path, i0, i, a);
 
-               p->v -= dv0 + dvc + dv1;
+               p->v -= dv0 + dvc;
                dv1   = 0;
 
                double tmp = p->v;
 
+               el    = f->elines[p->lid];
+               el->v = p->v;
+
                if (!(i & 0x1) && path->childs) {
                        int ret = __ses_path_split_a(f, path, i, n, &a, changed, ns, count);
                        if (ret < 0)
@@ -243,74 +238,44 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int m, int n, int* changed,
                        if (ret > 0) {
                                p0 = p;
                                i0 = i;
-                               dv0 = p->v - tmp;
-                               scf_logd("i: %d, p0: c%ldp%ld\n", i, p0->cid, p0->id);
+                               dv0 = p->v - tmp - dvc;
+
+                               scf_logi("-------i: %d, p0: c%ldp%ld, dvc: %lg\n", i, p0->cid, p0->id, dvc);
                        }
                }
 
-               el    = f->elines[p->lid];
                el->v = p->v;
 
-               r += p->r + p->dr + p->jdr;
+               r += p->r + p->dr;
 
                if (i & 0x1) {
                        p2  = path->pins->data[i - 1];
-                       c   = f->components[p->cid];
                        dv -= p->v;
-                       r  += c->r + c->dr + c->jdr;
+                       r  += c->r + c->dr;
 
                        ses_ur_i(&p->a, NULL, dv, 0, r, 0);
 
-                       if (SCF_EDA_Capacitor == c->type) {
-                               int sign = !p->id - p->id;
+                       int sign = !p->id - p->id;
 
+                       if (SCF_EDA_Capacitor == c->type) {
                                cv  = c->v * sign;
                                dv -= cv;
-                               r  -= c->jdr;
                                ses_ur_i(&p->a, NULL, dv, 0, r, 0);
 
-                               c->v   += p->a * ns / 1e3 / c->uf * sign;
-                               c->jdr  = c->v / p->a * sign - c->r;
+//                             c->v += p->a * sign * ns / 1e3 / c->uf;
+                               c->a  = p->a * sign;
 
-                               if (p->a > 0 || p->lid == Bn->lid) {
-                                       tmp   = p2->v;
-                                       p2->v = p->v + c->v * sign;
-
-                                       if (p0 == p2)
-                                               dv0 = p2->v - tmp;
-                               } else {
-                                       tmp  = p->v;
-                                       p->v = p2->v - c->v * sign;
-                                       dv1  = tmp - p->v;
-                               }
                                dvc += cv;
 
-                               scf_logi("c%ld->v: %lg, p->v: %lg, p2->v: %lg, dv: %lg, ja: %lg, ja0: %lg, ns: %ld, uf: %lg, c->jdr: %lg\n",
-                                               c->id, c->v, p->v, p2->v, dv, p->a, c->a, ns, c->uf, c->jdr);
-
-                               c->a     = p->a * sign;
-                               c->count = count;
-
-                               el    = f->elines[p->lid];
-                               el->v = p->v;
-                               __ses_status_check_line(f, el, changed);
-
-                               el    = f->elines[p2->lid];
-                               el->v = p2->v;
-                               __ses_status_check_line(f, el, changed);
-
+                               scf_logi("c%ld->v: %lg, p->v: %lg, p2->v: %lg, dv: %lg, ja: %lg, ja0: %lg, ns: %ld, uf: %lg\n",
+                                               c->id, c->v, p->v, p2->v, dv, p->a, c->a, ns, c->uf);
                        } else if (p->a > a) {
                                p->a = a;
+                               c->a = p->a * sign;
+                       } else
+                               c->a = p->a * sign;
+                       c->count = count;
 
-                               if (SCF_EDA_NPN == c->type) {
-                                       ses_ui_r(&p2->dr, NULL, dv, 0, a, 0);
-                                       p2->dr -= p2->r;
-
-                               } else if (SCF_EDA_Diode == c->type) {
-                                       ses_ui_r(&p->dr, NULL, dv, 0, a, 0);
-                                       p->dr -= p->r;
-                               }
-                       }
                        scf_logd("c%ld->v: %lg, p->v: %lg, dv: %lg, ja: %lg, r: %lg\n", c->id, c->v, p->v, dv, p->a, r);
 
                        p2->a = p->a;
@@ -334,11 +299,18 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int m, int n, int* changed,
                                                        break;
                                                }
                                        }
+
+                                       if (k > n) {
+                                               p0 = p;
+                                               i0 = i;
+                                               dv0 = 0;
+                                               scf_logi("----------------------i: %d, p0: c%ldp%ld\n", i, p0->cid, p0->id);
+                                       }
                                }
                        }
 
-                       scf_loge("path: %d, i: %d, c%ldp%ld, p->v: %lg, dv: %lg, r: %lg, p->a: %lg, a: %lg, p->pr: %lg\n\n",
-                                       path->index, i, p->cid, p->id, p->v, dv, r, p->a, a, p->pr);
+                       scf_loge("path: %d, i: %d, c%ldp%ld, p->v: %lg, dv: %lg, r: %lg, p->a: %lg, a: %lg, p->pr: %lg, e%ld->v: %lg\n\n",
+                                       path->index, i, p->cid, p->id, p->v, dv, r, p->a, a, p->pr, el->id, el->v);
 
                        if (SCF_EDA_Diode == c->type) {
 
@@ -346,8 +318,6 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int m, int n, int* changed,
                                        p2 = path->pins->data[i - 1];
 
                                        *changed += __ses_status_check(f, c, p2, p, 1);
-
-                                       __ses_pn_dr(c, p2, p);
                                }
 
                        } else if (SCF_EDA_NPN == c->type) {
@@ -358,8 +328,6 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int m, int n, int* changed,
                                        if (SCF_EDA_NPN_B == p2->id) {
                                                *changed += __ses_status_check(f, c, p2, p, 1);
 
-                                               __ses_npn_dr(c, p2, p);
-
                                                c->pins[SCF_EDA_NPN_C]->aconst = 1;
                                        }
                                }
@@ -368,8 +336,8 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int m, int n, int* changed,
                        r  = 0;
                } else {
                        dv = p->v;
-                       scf_loge("path: %d, i: %d, c%ldp%ld, p->v: %lg, dv: %lg, a: %lg, p->pr: %lg, dv0: %lg, dvc: %lg\n",
-                                       path->index, i, p->cid, p->id, p->v, dv, a, p->pr, dv0, dvc);
+                       scf_loge("path: %d, i: %d, c%ldp%ld, p->v: %lg, dv: %lg, a: %lg, p->pr: %lg, dv0: %lg, e%ld->v: %lg\n",
+                                       path->index, i, p->cid, p->id, p->v, dv, a, p->pr, dv0, el->id, el->v);
                }
        }
        printf("\n");
@@ -378,10 +346,76 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int m, int n, int* changed,
        return 0;
 }
 
+int __ses_path_va2(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count)
+{
+       if (!path)
+               return -EINVAL;
+
+       if (path->pins->size < 2) {
+               scf_loge("\n");
+               return -EINVAL;
+       }
+
+       if (n - m < 1)
+               return 0;
+
+       ScfEline* el;
+       ScfEpin*  p0 = path->pins->data[m];
+       ScfEpin*  p1 = path->pins->data[n];
+
+       el     = f->elines[p0->lid];
+       p0->v  = el->v;
+
+       el     = f->elines[p1->lid];
+       p1->v  = el->v;
+
+       return __ses_path_va3(f, path, m, n, pr, changed, ns, count);
+}
+
+int __ses_path_va(ScfEfunction* f, ses_path_t* path, int* changed, int64_t ns, int64_t count)
+{
+       if (!path)
+               return -EINVAL;
+
+       if (path->pins->size < 2) {
+               scf_loge("\n");
+               return -EINVAL;
+       }
+
+       ScfEpin* p0 = path->pins->data[0];
+       ScfEpin* p1 = path->pins->data[path->pins->size - 1];
+
+       double _sr0 = p0->sr;
+       double _pr0 = p0->pr;
+       double _sr1 = p1->sr;
+       double _pr1 = p1->pr;
+
+       p0->sr = 0;
+       p0->pr = 0;
+       p1->sr = path->sr;
+       p1->pr = path->pr;
+
+//     scf_logi("---------------\n");
+       //int ret = __ses_meshs_path_solve(f, path, 0, path->pins->size - 1, changed, ns, count);
+       int ret = __ses_path_va2(f, path, 0, path->pins->size - 1, path->pr, changed, ns, count);
+       if (ret < 0) {
+               scf_loge("\n");
+               return ret;
+       }
+//     scf_logi("---------------\n\n");
+
+       p0->sr = _sr0;
+       p0->pr = _pr0;
+       p1->sr = _sr1;
+       p1->pr = _pr1;
+       return ret;
+}
+
 static int _va_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx)
 {
        ses_path_t*    path;
        ScfEcomponent* B;
+       ScfEline*      el;
        ScfEpin*       p0;
        ScfEpin*       p1;
        ScfEpin*       Bp;
@@ -396,6 +430,12 @@ static int _va_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ct
        int changed = 0;
        int i;
 
+       for (i = 0; i < f->n_elines; i++) {
+               el        = f->elines[i];
+               el->ain   = 0;
+               el->aout  = 0;
+       }
+
        for (i = 0; i < ctx->paths->size; i++) {
                path      = ctx->paths->data[i];
 
@@ -414,7 +454,7 @@ static int _va_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ct
 
                __ses_path_jr(f, path);
 
-               int ret = __ses_path_va(f, path, 0, path->pins->size - 1, &changed, ns, count);
+               int ret = __ses_path_va(f, path, &changed, ns, count);
                if (ret < 0)
                        return ret;
        }
diff --git a/ses_step_va_bridge.c b/ses_step_va_bridge.c
deleted file mode 100644 (file)
index 908ffb3..0000000
+++ /dev/null
@@ -1,428 +0,0 @@
-#include"ses_core.h"
-
-int __ses_flow_a_pos(ScfEfunction* f, ses_flow_t* flow, double da_vip, int* changed)
-{
-       if (!flow || !flow->paths || flow->paths->size <= 0 || !flow->vip)
-               return -EINVAL;
-
-       ScfEcomponent* c;
-       ScfEcomponent* B    = f->components[0];
-       ScfEpin*       Bp   = B->pins[SCF_EDA_Battery_POS];
-       ScfEpin*       Bn   = B->pins[SCF_EDA_Battery_NEG];
-
-       ses_path_t*    path = flow->paths->data[flow->paths->size - 1];
-       ScfEpin*       vip  = flow->vip;
-       ScfEpin*       p;
-       ScfEline*      el;
-
-       double v;
-
-       ses_ir_u(&v, NULL, da_vip, 0, flow->pos_r, 0);
-
-       int i;
-       int j;
-
-       for (i   = 0; i < flow->paths->size; i++) {
-               path =        flow->paths->data[i];
-
-               double r = 0;
-
-               int j0 = -1;
-               for (j = path->pins->size - 1; j >= 0; j--) {
-                       p  = path->pins->data[j];
-
-                       if (j0 < 0) {
-                               if ((j & 0x1) && p->lid == vip->lid)
-                                       j0 = j;
-                               else
-                                       continue;
-                       }
-
-                       r += p->r + p->dr;
-
-                       if (!(j & 0x1)) {
-                               c  = f->components[p->cid];
-                               r += c->r;
-
-                               ses_ir_u(&v, NULL, da_vip, 0, r, 0);
-                       }
-
-                       el = f->elines[p->lid];
-
-                       if (p->lid != Bp->lid && p->v - v < Bp->lid) {
-                               p->v   -= v;
-                               el->v   = p->v;
-                       }
-
-                       p->a += da_vip;
-                       scf_logw("c%ldp%ld->v: %lg, p->a: %lg, r: %lg, l%ld->v: %lg\n", p->cid, p->id, p->v, p->a, r, el->id, el->v);
-
-                       if (!(j & 0x1)) {
-                               r  = 0;
-                       }
-               }
-
-               vip = path->pins->data[0];
-       }
-
-       return 0;
-}
-
-int __ses_flow_v_neg(ScfEfunction* f, ses_flow_t* flow, double dv_vip, int* changed)
-{
-       if (!flow || !flow->paths || flow->paths->size <= 0 || !flow->vip)
-               return -EINVAL;
-
-       ScfEcomponent* c;
-       ScfEcomponent* B    = f->components[0];
-       ScfEpin*       Bp   = B->pins[SCF_EDA_Battery_POS];
-       ScfEpin*       Bn   = B->pins[SCF_EDA_Battery_NEG];
-
-       ses_path_t*    path = flow->paths->data[flow->paths->size - 1];
-       ScfEpin*       vip  = flow->vip;
-       ScfEpin*       p;
-       ScfEpin*       p2;
-       ScfEline*      el;
-
-       double v = dv_vip;
-       double da;
-
-       int i;
-       int j;
-
-       for (i   = 0; i < flow->paths->size; i++) {
-               path =        flow->paths->data[i];
-
-               double r = 0;
-
-               int j0 = -1;
-               for (j = 0; j < path->pins->size; j++) {
-                       p  =        path->pins->data[j];
-
-                       if (j0 < 0) {
-                               if (!(j & 0x1) && p->lid == vip->lid) {
-                                       j0 = j;
-
-                                       ses_ur_i(&da, NULL, vip->v, 0, flow->neg_r, 0);
-
-                                       da -= p->a;
-                               } else
-                                       continue;
-                       }
-
-                       r += p->r + p->dr;
-
-                       if (j & 0x1) {
-                               c  = f->components[p->cid];
-                               r += c->r;
-
-                               ses_ir_u(&v, NULL, da, 0, r, 0);
-                       }
-
-                       el = f->elines[p->lid];
-
-                       if (p->lid != Bn->lid && p->v + v > Bn->lid) {
-                               p->v   += v;
-                               el->v   = p->v;
-                       }
-
-                       p->a += da;
-
-                       scf_logw("c%ldp%ld->v: %lg, p->a: %lg, r: %lg, v: %lg, da: %lg\n", p->cid, p->id, p->v, p->a, r, v, da);
-
-                       if (j & 0x1) {
-                               if (SCF_EDA_Diode == c->type) {
-
-                                       if (SCF_EDA_Diode_NEG == p->id) {
-                                               p2 = path->pins->data[j - 1];
-
-                                               *changed += __ses_status_check(f, c, p2, p, 1);
-
-                                               __ses_pn_dr(c, p2, p);
-                                       }
-
-                               } else if (SCF_EDA_NPN == c->type) {
-
-                                       if (SCF_EDA_NPN_E == p->id) {
-                                               p2 = path->pins->data[j - 1];
-
-                                               if (SCF_EDA_NPN_B == p2->id) {
-                                                       *changed += __ses_status_check(f, c, p2, p, 1);
-
-                                                       __ses_npn_dr(c, p2, p);
-                                               }
-                                       }
-                               }
-
-                               r = 0;
-                       }
-               }
-
-               vip = path->pins->data[j - 1];
-       }
-
-       return 0;
-}
-
-static int __ses_bridge_v(ScfEfunction* f, ses_path_t* bridge, double vmin, ses_flow_t* flow, int64_t ns, int64_t count)
-{
-       ScfEline* el;
-       ScfEpin*  p0 = bridge->pins->data[0];
-       ScfEpin*  p1 = bridge->pins->data[bridge->pins->size - 1];
-
-       double da;
-       double v;
-       double dv;
-
-       double a   = 0;
-       double Eta = 0.001;
-
-       int __changed = 0;
-       int k = 0;
-
-       while (p0->v - p1->v > vmin) {
-
-               scf_logw("k: %d, ****************\n", k);
-
-               el     = f->elines[p0->lid];
-               p0->v  = el->v;
-
-               el     = f->elines[p1->lid];
-               p1->v  = el->v;
-
-               if (bridge->n_diodes > 0) {
-                       __ses_path_va_diode(f, bridge);
-                       __ses_path_jr      (f, bridge);
-               }
-
-               __changed = 0;
-
-               int ret = __ses_path_va(f, bridge, 0, bridge->pins->size - 1, &__changed, ns, count);
-               if (ret < 0)
-                       return ret;
-
-               da  = bridge->a - a;
-               a  += Eta * da;
-
-               scf_loge("da: %lg, a: %lg, bridge->a: %lg, bridge->pr: %lg, p0->v: %lg, p1->v: %lg, diff: %lg, vmin: %lg\n",
-                               da, a, bridge->a, bridge->pr, p0->v, p1->v, p0->v - p1->v, vmin);
-
-               v = flow->vip->v;
-
-               ret = __ses_flow_a_pos(f, flow, Eta * da, &__changed);
-               if (ret < 0)
-                       return ret;
-
-               dv = flow->vip->v - v;
-
-               scf_logi("dv: %lg, v: %lg - %lg ----------------\n", dv, flow->vip->v, v);
-
-               ret = __ses_flow_v_neg(f, flow, dv, &__changed);
-               if (ret < 0)
-                       return ret;
-
-               scf_logw("flow vip: c%ldp%ld->a: %lg, vip_n: c%ldp%ld->a: %lg, bridge->a: %lg, diff: %lg\n\n",
-                               flow->vip->cid, flow->vip->id, flow->vip->a,
-                               flow->vip_n->cid, flow->vip_n->id, flow->vip_n->a,
-                               bridge->a,
-                               flow->vip->a - flow->vip_n->a - bridge->a);
-
-               ses_flow_jr(flow, f);
-
-               if (__changed > 0
-                               || fabs(dv) < 0.001
-                               || fabs(flow->vip->a - flow->vip_n->a - bridge->a) < 1e-4)
-                       break;
-               k++;
-       }
-
-       return __changed;
-}
-
-static int __ses_bridge_r(ScfEfunction* f, ses_path_t* bridge, int vmin, ses_flow_t* flow)
-{
-       return 0;
-}
-
-int __ses_path_va_bridge(ScfEfunction* f, ses_path_t* bridge, int* changed, scf_vector_t* paths, int64_t ns, int64_t count)
-{
-       ses_flow_t*    flow0;
-       ses_flow_t*    flow1;
-       ses_path_t*    fpath;
-       ses_info_t*    info;
-
-       ScfEcomponent* B;
-       ScfEline*      el;
-       ScfEpin*       Bp;
-       ScfEpin*       Bn;
-       ScfEpin*       p0;
-       ScfEpin*       p1;
-
-       B  = f->components[0];
-       Bp = B->pins[SCF_EDA_Battery_POS];
-       Bn = B->pins[SCF_EDA_Battery_NEG];
-
-       p0 = bridge->pins->data[0];
-       p1 = bridge->pins->data[bridge->pins->size - 1];
-
-       if (p0->lid == Bp->lid && p1->lid == Bn->lid)
-               return 0;
-
-       __ses_path_jr(f, bridge);
-
-       flow0 = ses_flow_alloc();
-       if (!flow0)
-               return -ENOMEM;
-
-       int ret = ses_paths_find_flow(flow0, paths, p0, bridge);
-       if (ret < 0) {
-               ses_flow_free(flow0);
-               return ret;
-       }
-
-       flow1 = ses_flow_alloc();
-       if (!flow1) {
-               ses_flow_free(flow0);
-               return -ENOMEM;
-       }
-
-       ret = ses_paths_find_flow(flow1, paths, p1, bridge);
-       if (ret < 0) {
-               ses_flow_free(flow0);
-               ses_flow_free(flow1);
-               return ret;
-       }
-
-       ses_flow_print(flow0);
-       ses_flow_jr(flow0, f);
-       printf("\n");
-
-       ses_flow_print(flow1);
-       ses_flow_jr(flow1, f);
-       printf("\n");
-
-       double v;
-       double jv;
-       double vmin = 0;
-       int    i;
-
-       for (i = 0; i < bridge->infos->size; i++) {
-               info      = bridge->infos->data[i];
-
-               vmin += info->n_diodes * SCF_EDA_V_Diode_ON + info->n_NPNs * SCF_EDA_V_NPN_ON;
-       }
-
-       el     = f->elines[p0->lid];
-       p0->v  = el->v;
-
-       el     = f->elines[p1->lid];
-       p1->v  = el->v;
-
-       if (bridge->n_diodes > 0) {
-               __ses_path_va_diode(f, bridge);
-               __ses_path_jr      (f, bridge);
-       }
-
-       __ses_path_va_transistor(f, bridge);
-       __ses_path_jr           (f, bridge);
-
-       int __changed = 0;
-
-       ret = __ses_path_va(f, bridge, 0, bridge->pins->size - 1, &__changed, ns, count);
-       if (ret < 0)
-               return ret;
-#if 0
-       if (0 == __changed) {
-
-               ret = __ses_bridge_v(f, bridge, vmin, flow);
-               if (ret < 0)
-                       return ret;
-
-               if (0 == ret) {
-                       ret = __ses_bridge_r(f, bridge, vmin, flow);
-                       if (ret < 0)
-                               return ret;
-               } else
-                       __changed = ret;
-       }
-#endif
-       v  = p0->v  - p1->v;
-
-       changed += __changed;
-
-       scf_loge("bridge: %d, c%ldp%ld--c%ldp%ld, __changed: %d, v: %lg, p0->v: %lg, p1->v: %lg, n_diodes: %d, p0->a: %lg, p1->a: %lg\n\n",
-                       bridge->index, p0->cid, p0->id, p1->cid, p1->id, __changed, v, p0->v, p1->v, bridge->n_diodes, p0->a, p1->a);
-
-       return 0;
-}
-
-static int ses_path_va_bridge(ScfEfunction* f, ses_path_t* path, int* changed, scf_vector_t* paths, int64_t ns, int64_t count)
-{
-       ses_path_t* child;
-
-       int ret;
-       int j;
-
-       if (!path)
-               return -EINVAL;
-
-       if (0 == path->n_capacitors) {
-
-               ret = __ses_path_va_bridge(f, path, changed, paths, ns, count);
-               if (ret < 0)
-                       return ret;
-       }
-
-       if (path->bridges) {
-               scf_vector_t* vec = scf_vector_clone(path->childs);
-               if (!vec)
-                       return -ENOMEM;
-
-               ret = scf_vector_add(vec, path);
-               if (ret < 0) {
-                       scf_vector_free(vec);
-                       return ret;
-               }
-
-               for (j = 0; j < path->bridges->size; j++) {
-                       child     = path->bridges->data[j];
-
-                       ret = ses_path_va_bridge(f, child, changed, vec, ns, count);
-                       if (ret < 0) {
-                               scf_vector_free(vec);
-                               return ret;
-                       }
-               }
-
-               scf_vector_free(vec);
-               vec = NULL;
-       }
-
-       return 0;
-}
-
-static int _va_bridge_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx)
-{
-       ses_path_t* path;
-
-       int changed = 0;
-       int i;
-
-       for (i = 0; i < ctx->paths->size; i++) {
-               path      = ctx->paths->data[i];
-
-               int ret = ses_path_va_bridge(f, path, &changed, ctx->paths, ns, count);
-               if (ret < 0)
-                       return ret;
-       }
-
-       ctx->changed += changed;
-       return 0;
-}
-
-ses_step_t  ses_step_va_bridge =
-{
-       .name    = "va_bridge",
-
-       .handler = _va_bridge_handler,
-};
index 6c76221a8ae30c9d3c0c041083bd1fbc97841401..9740da1d0a77779a876bb19c3c10bde50c084ea2 100644 (file)
@@ -10,74 +10,138 @@ void __ses_status_check_line(ScfEfunction* f, ScfEline* el, int* changed)
 
        for (i = 0; i < el->n_pins; i += 2) {
 
-               c     = f->components[el->pins[i]];
-               p0    = c->pins      [el->pins[i + 1]];
-               p0->v = el->v;
+               c  = f->components[el->pins[i]];
+               p0 = c->pins      [el->pins[i + 1]];
 
                if (SCF_EDA_Diode == c->type) {
 
                        p0 = c->pins[SCF_EDA_Diode_POS];
                        p1 = c->pins[SCF_EDA_Diode_NEG];
 
+                       double v0 = p0->v;
+                       double v1 = p1->v;
+
                        *changed += __ses_status_check(f, c, p0, p1, 0);
 
-               } else if (SCF_EDA_NPN == c->type) {
+                       p0->v = v0;
+                       p1->v = v1;
+
+               } else if (SCF_EDA_NPN == c->type
+                               && (SCF_EDA_NPN_B == p0->id || SCF_EDA_NPN_E == p0->id)) {
 
                        p0 = c->pins[SCF_EDA_NPN_B];
                        p1 = c->pins[SCF_EDA_NPN_E];
 
+                       double v0 = p0->v;
+                       double v1 = p1->v;
+
                        *changed += __ses_status_check(f, c, p0, p1, 0);
+
+                       p0->v = v0;
+                       p1->v = v1;
                }
        }
 }
 
-static void ses_va_bridge(
-               double  U0,  double  U1,  double  U2,  double  U3,  double  Vbc,
-               double  R0,  double  R1,  double  R2,  double  R3,  double  Rb,
-               double* pi0, double* pi1, double* pi2, double* pi3, double* pib,
-               double* pVb0, double* pVb1)
+int __ses_flow_va(ScfEfunction* f, ses_flow_t* flow, double* rp, double* rn, int* changed, int64_t ns, int64_t count)
+{
+#if 1
+       ses_path_t* fpath = flow->paths->data[0];
+       ScfEline*   el    = NULL;
+       ScfEpin*    p0    = fpath->pins->data[flow->vip_m];
+       ScfEpin*    p1    = fpath->pins->data[flow->vip_n];
+
+       double tmp;
+
+       __ses_path_jr(f, fpath);
+
+       if (rp) {
+               el  = f->elines[p0->lid];
+               tmp = el->v;
+
+               int ret = __ses_path_va2(f, fpath, flow->vip_m, flow->vip_i, *rp, changed, ns, count);
+               if (ret < 0)
+                       return ret;
+
+               if (el->vconst)
+                       el->v = tmp;
+       }
+
+       if (rn) {
+               el  = f->elines[p1->lid];
+               tmp = el->v;
+
+               int ret = __ses_path_va2(f, fpath, flow->vip_i + 1, flow->vip_n, *rn, changed, ns, count);
+               if (ret < 0)
+                       return ret;
+
+               if (el->vconst)
+                       el->v = tmp;
+       }
+#endif
+       return 0;
+}
+
+void __ses_flow_solve_cross(ses_flow_t* flow0, ses_flow_t* flow1, ses_path_t* bridge)
 {
-       scf_logw("R0: %lg, R1: %lg, R2: %lg, R3: %lg, Vbc: %lg, U0: %lg, U1: %lg, U2: %lg, U3: %lg\n", R0, R1, R2, R3, Vbc, U0, U1, U2, U3);
+       ses_path_t* path0;
+       ses_path_t* path1;
+       ses_path_t* path;
 
-       double i1 = (R0 * R3 * (U2 - U1 + Vbc) - R0 * R2 * (U1 - U3 - Vbc) + (R2 * R3 + R3 * Rb + R2 * Rb) * (U0 - U1))
-                     / ((R2 + R3) * (R0 * R1 + Rb * (R0 + R1)) + R2 * R3 * (R0 + R1));
+       int i;
+       int j;
 
-       double ib = (U0 - U1 - i1 * (R0 + R1)) / R0;
-       double i0 = i1 + ib;
-       double i3 = (R0 * (U1 - U3 - Vbc) - Rb * (U0 - U1) + i1 * (R0 * R1 + Rb * (R0 + R1))) / R0 / R3;
-       double i2 = i3 - ib;
+       for (i = 0; i < flow0->paths->size; i++) {
+               path0     = flow0->paths->data[i];
 
-       double V0 = i0 * R0;
-       double V1 = i1 * R1;
-       double V2 = i2 * R2;
-       double V3 = i3 * R3;
-       double Vb = ib * Rb;
+               for (j = 0; j < flow1->paths->size; j++) {
+                       path1     = flow1->paths->data[j];
 
-       scf_logi("i0: %lg, i1: %lg, i2: %lg, i3: %lg, ib: %lg\n", i0, i1, i2, i3, ib);
+                       if (path0 == path1) {
+                               flow1->paths->size = j + 1;
+                               flow0->paths->size = i + 1;
+                               goto cross;
+                       }
+               }
+       }
+
+       return;
 
-       double Vb0 = U1 + V1;
-       double Vb1 = U3 + V3;
+cross:
+       scf_logi("-----------\n");
 
-       if (pi0)
-               *pi0 = i0;
+       if (i > 0) {
+               if (j > 0) {
+                       scf_logi("-----------\n");
+                       return;
+               }
 
-       if (pi1)
-               *pi1 = i1;
+               path = flow0->paths->data[i - 1];
 
-       if (pi2)
-               *pi2 = i2;
+               if (flow1->vip_i > path->parent_p0 && flow1->vip_i < path->parent_p1) {
+                       flow1->vip_m = path->parent_p0;
+                       flow1->vip_n = path->parent_p1;
+               }
 
-       if (pi3)
-               *pi3 = i3;
+       } else if (j > 0) {
+               path = flow1->paths->data[j - 1];
 
-       if (pib)
-               *pib = ib;
+               if (flow0->vip_i > path->parent_p0 && flow0->vip_i < path->parent_p1) {
+                       flow0->vip_m = path->parent_p0;
+                       flow0->vip_n = path->parent_p1;
+               }
 
-       if (pVb0)
-               *pVb0 = Vb0;
+       } else {
+               path = flow0->paths->data[0];
 
-       if (pVb1)
-               *pVb1 = Vb1;
+               if (flow0->vip_i < flow1->vip_i) {
+                       flow0->vip_m = flow0->vip_i;
+                       flow0->vip_n = flow1->vip_i;
+               } else {
+                       flow1->vip_m = flow1->vip_i;
+                       flow1->vip_n = flow0->vip_i;
+               }
+       }
 }
 
 static int __ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_path_t* bridge, int* changed, int64_t ns, int64_t count)
@@ -92,6 +156,8 @@ static int __ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_pat
        ScfEpin*       p1;
        ScfEpin*       fp0;
        ScfEpin*       fp1;
+       ScfEpin*       fp2;
+       ScfEpin*       fp3;
        ScfEpin*       Bp;
        ScfEpin*       Bn;
 
@@ -131,7 +197,7 @@ static int __ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_pat
                goto error;
 
        if (flow0->paths->size > 0) {
-               fpath = flow0->paths->data[flow0->paths->size - 1];
+               fpath = flow0->paths->data[0];
 
                if (!fpath->vflag) {
                        ret = __ses_path_va_capacitor(f, paths, fpath, changed, ns, count);
@@ -141,26 +207,49 @@ static int __ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_pat
        }
 
        if (flow1->paths->size > 0) {
-               fpath = flow1->paths->data[flow1->paths->size - 1];
+               fpath = flow1->paths->data[0];
 
                if (!fpath->vflag) {
                        ret = __ses_path_va_capacitor(f, paths, fpath, changed, ns, count);
                        if (ret < 0)
                                goto error;
                }
-       }
+
+               if (flow0->paths->size > 0) {
+
+                       __ses_flow_solve_cross(flow0, flow1, bridge);
+
+                       flow0->paths->size = 1;
+               }
+
+               flow1->paths->size = 1;
+       } else if (flow0->paths->size > 0)
+               flow0->paths->size = 1;
 
        double R;
        double cv;
+       double Dv = bridge->n_NPNs * SCF_EDA_V_NPN_ON + bridge->n_diodes * SCF_EDA_V_Diode_ON;
        double ja;
+       double tmp0;
+       double tmp1;
 
        __ses_path_jr(f, bridge);
 
        el    = f->elines[p0->lid];
        p0->v = el->v;
+       tmp0  = el->v;
 
        el    = f->elines[p1->lid];
        p1->v = el->v;
+       tmp1  = el->v;
+
+       ses_flow_print(flow0);
+       ses_flow_jr(flow0, f);
+       printf("\n");
+
+       ses_flow_print(flow1);
+       ses_flow_jr(flow1, f);
+       printf("\n");
 
        __ses_path_capacitors(f, bridge, 0, bridge->pins->size - 1, &cv);
 
@@ -170,150 +259,205 @@ static int __ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_pat
 
                if (p0->lid == Bp->lid) {
 
-                       ret = ses_flow_find_pos(flow1, paths, f);
-                       if (ret < 0)
-                               goto error;
-
-                       ret = ses_flow_find_neg(flow1, paths, f);
-                       if (ret < 0)
-                               goto error;
+                       fpath = flow1->paths->data[flow1->paths->size - 1];
+                       fp0   = fpath->pins->data[0];
+                       fp1   = fpath->pins->data[fpath->pins->size - 1];
 
-                       ses_flow_print(flow0);
-                       ses_flow_jr(flow0, f);
                        printf("\n");
+                       scf_logi("-----------\n");
+                       ret = __ses_meshs_PPN_solve(f, flow1, bridge, changed, ns, count);
+                       if (ret < 0) {
+                               scf_loge("\n");
+                               return ret;
+                       }
+                       scf_logi("-----------\n\n");
 
-                       ses_flow_print(flow1);
-                       ses_flow_jr(flow1, f);
-                       printf("\n");
+               } else if (p1->lid == Bn->lid) {
 
-                       R     = bridge->jpr * flow1->pos_r / (bridge->jpr + flow1->pos_r);
+                       fpath = flow0->paths->data[flow0->paths->size - 1];
+                       fp0   = fpath->pins->data[0];
+                       fp1   = fpath->pins->data[fpath->pins->size - 1];
 
-                       ja    = Bp->v / (R + flow1->neg_r);
-                       p0->v = Bp->v;
-                       p1->v = Bp->v - ja * R;
+                       double U0 = fp0->v - flow0->pos_cv;
+                       double U1 = Bn->v  + cv + Dv;
+                       double U2 = fp1->v + flow0->neg_cv;
 
-               } else if (p1->lid == Bn->lid) {
+                       ses_va_PNN(U0, U1, U2, flow0->pos_r, bridge->pr, flow0->neg_r,
+                                       NULL, &ja, NULL, &p0->v);
 
-                       ret = ses_flow_find_pos(flow0, paths, f);
-                       if (ret < 0)
+                       p1->v = Bn->v;
+
+                       scf_logi("c%ldp%ld-c%ldp%ld, cv: %lg, p0->v: %lg, p1->v: %lg, ja: %lg\n\n",
+                                       p0->cid, p0->id, p1->cid, p1->id, cv, p0->v, p1->v, ja);
+
+                       el    = f->elines[p0->lid];
+                       el->v = p0->v;
+
+                       el    = f->elines[p1->lid];
+                       el->v = p1->v;
+
+                       ret = __ses_path_va(f, bridge, changed, ns, count);
+                       if (ret < 0) {
+                               scf_loge("\n");
                                goto error;
+                       }
+
+                       el = f->elines[p0->lid];
+                       if (el->vconst)
+                               el->v = tmp0;
 
-                       ret = ses_flow_find_neg(flow0, paths, f);
+                       el = f->elines[p1->lid];
+                       if (el->vconst)
+                               el->v = tmp1;
+
+                       ret = __ses_flow_va(f, flow0, &flow0->pos_r, &flow0->neg_r, changed, ns, count);
                        if (ret < 0)
                                goto error;
 
-                       ses_flow_print(flow0);
-                       ses_flow_jr(flow0, f);
-                       printf("\n");
+               } else {
+                       fpath = flow0->paths->data[0];
+                       fp0   = fpath->pins->data[flow0->vip_m];
+                       fp1   = fpath->pins->data[flow0->vip_n];
 
-                       ses_flow_print(flow1);
-                       ses_flow_jr(flow1, f);
-                       printf("\n");
+                       double U0 = fp0->v - flow0->pos_cv;
+                       double U1 = fp1->v + flow0->neg_cv;
 
-                       R     = bridge->jpr * flow0->neg_r / (bridge->jpr + flow0->neg_r);
+                       fpath = flow1->paths->data[0];
+                       fp2   = fpath->pins->data[flow1->vip_m];
+                       fp3   = fpath->pins->data[flow1->vip_n];
 
-                       ja    = Bp->v / (R + flow0->pos_r);
-                       p0->v = Bp->v - ja * flow0->pos_r;
-                       p1->v = Bn->v;
+                       double U2 = fp2->v - flow1->pos_cv;
+                       double U3 = fp3->v + flow1->neg_cv;
 
-                       scf_logi("R: %lg, flow0->pos_r: %lg, flow0->neg_r: %lg\n", R, flow0->pos_r, flow0->neg_r);
-               } else {
-                       ses_flow_print(flow0);
-                       ses_flow_jr(flow0, f);
-                       printf("\n");
+                       double i0 = 0;
+                       double i1 = 0;
+                       double i2 = 0;
+                       double i3 = 0;
 
-                       ses_flow_print(flow1);
-                       ses_flow_jr(flow1, f);
-                       printf("\n");
+                       ses_va_bridge(U0, U1, U2, U3, cv,
+                                       flow0->pos_r, flow0->neg_r, flow1->pos_r, flow1->neg_r, bridge->pr,
+                                       &i0, &i1, &i2, &i3, &ja, &p0->v, &p1->v);
 
-                       fpath = flow0->paths->data[flow0->paths->size - 1];
-                       fp0   = fpath->pins->data[0];
-                       fp1   = fpath->pins->data[fpath->pins->size - 1];
+                       scf_logi("c%ldp%ld-c%ldp%ld, cv: %lg, p0->v: %lg, p1->v: %lg, ja: %lg\n\n",
+                                       p0->cid, p0->id, p1->cid, p1->id, cv, p0->v, p1->v, ja);
 
-                       double U0 = fp0->v;
-                       double U1 = fp1->v;
+                       el    = f->elines[p0->lid];
+                       el->v = p0->v;
 
-                       fpath = flow1->paths->data[flow1->paths->size - 1];
-                       fp0   = fpath->pins->data[0];
-                       fp1   = fpath->pins->data[fpath->pins->size - 1];
+                       el    = f->elines[p1->lid];
+                       el->v = p1->v;
 
-                       double U2 = fp0->v;
-                       double U3 = fp1->v;
+                       ret = __ses_path_va(f, bridge, changed, ns, count);
+                       if (ret < 0) {
+                               scf_loge("\n");
+                               goto error;
+                       }
 
-                       ses_va_bridge(U0, U1, U2, U3, cv,
-                                       flow0->pos_r, flow0->neg_r, flow1->pos_r, flow1->neg_r, bridge->jpr,
-                                       NULL, NULL, NULL, NULL, &ja, &p0->v, &p1->v);
-               }
+                       el = f->elines[p0->lid];
+                       if (el->vconst)
+                               el->v = tmp0;
 
-               scf_logi("c%ldp%ld-c%ldp%ld, cv: %lg, p0->v: %lg, p1->v: %lg, ja: %lg\n\n",
-                               p0->cid, p0->id, p1->cid, p1->id, cv, p0->v, p1->v, ja);
-       } else {
-               assert(p0->lid != Bp->lid);
-
-               if (p1->lid == Bn->lid) {
+                       el = f->elines[p1->lid];
+                       if (el->vconst)
+                               el->v = tmp1;
 
-                       ret = ses_flow_find_neg(flow1, paths, f);
+                       ret = __ses_flow_va(f, flow1, &flow1->pos_r, &flow1->neg_r, changed, ns, count);
                        if (ret < 0)
                                goto error;
 
-                       ses_flow_print(flow0);
-                       ses_flow_jr(flow0, f);
-                       printf("\n");
+                       ret = __ses_flow_va(f, flow0, &flow0->pos_r, &flow0->neg_r, changed, ns, count);
+                       if (ret < 0)
+                               goto error;
+               }
+       } else {
+               assert(p0->lid != Bp->lid);
 
-                       ses_flow_print(flow1);
-                       ses_flow_jr(flow1, f);
-                       printf("\n");
+               if (p1->lid == Bn->lid) {
 
-                       R     = bridge->jpr + flow0->neg_r;
+                       R     = bridge->pr + flow0->neg_r;
                        ja    = (cv - p0->v) / R;
                        p1->v = Bn->v;
 
-               } else {
-                       ses_flow_print(flow0);
-                       ses_flow_jr(flow0, f);
-                       printf("\n");
+                       scf_logi("c%ldp%ld-c%ldp%ld, cv: %lg, p0->v: %lg, p1->v: %lg, ja: %lg\n\n",
+                                       p0->cid, p0->id, p1->cid, p1->id, cv, p0->v, p1->v, ja);
 
-                       ses_flow_print(flow1);
-                       ses_flow_jr(flow1, f);
-                       printf("\n");
+                       el    = f->elines[p0->lid];
+                       el->v = p0->v;
 
-                       fpath = flow1->paths->data[flow1->paths->size - 1];
-                       fp0   = fpath->pins->data[0];
-                       fp1   = fpath->pins->data[fpath->pins->size - 1];
+                       el    = f->elines[p1->lid];
+                       el->v = p1->v;
 
-                       double U0 = fp0->v;
-                       double U1 = fp1->v;
+                       ret = __ses_path_va(f, bridge, changed, ns, count);
+                       if (ret < 0) {
+                               scf_loge("\n");
+                               goto error;
+                       }
 
-                       fpath = flow0->paths->data[flow0->paths->size - 1];
-                       fp0   = fpath->pins->data[0];
-                       fp1   = fpath->pins->data[fpath->pins->size - 1];
+                       el = f->elines[p0->lid];
+                       if (el->vconst)
+                               el->v = tmp0;
+
+                       el = f->elines[p1->lid];
+                       if (el->vconst)
+                               el->v = tmp1;
+
+               } else {
+                       fpath = flow1->paths->data[0];
+                       fp0   = fpath->pins->data[flow1->vip_m];
+                       fp1   = fpath->pins->data[flow1->vip_n];
+
+                       double U0 = fp0->v - flow1->pos_cv;
+                       double U1 = fp1->v + flow1->neg_cv;
 
-                       double U2 = fp0->v;
-                       double U3 = fp1->v;
+                       fpath = flow0->paths->data[0];
+                       fp2   = fpath->pins->data[flow0->vip_m];
+                       fp3   = fpath->pins->data[flow0->vip_n];
+
+                       double U2 = fp2->v - flow0->pos_cv;
+                       double U3 = fp3->v + flow0->neg_cv;
+
+                       double i0 = 0;
+                       double i1 = 0;
+                       double i2 = 0;
+                       double i3 = 0;
 
                        ses_va_bridge(U0, U1, U2, U3, -cv,
-                                       flow1->pos_r, flow1->neg_r, flow0->pos_r, flow0->neg_r, bridge->jpr,
-                                       NULL, NULL, NULL, NULL, &ja, &p1->v, &p0->v);
-               }
+                                       flow1->pos_r, flow1->neg_r, flow0->pos_r, flow0->neg_r, bridge->pr,
+                                       &i0, &i1, &i2, &i3, &ja, &p1->v, &p0->v);
 
-               scf_logi("c%ldp%ld-c%ldp%ld, cv: %lg, p0->v: %lg, p1->v: %lg, ja: %lg\n\n",
-                               p0->cid, p0->id, p1->cid, p1->id, cv, p0->v, p1->v, ja);
-       }
+                       scf_logi("c%ldp%ld-c%ldp%ld, cv: %lg, p0->v: %lg, p1->v: %lg, ja: %lg\n\n",
+                                       p0->cid, p0->id, p1->cid, p1->id, cv, p0->v, p1->v, ja);
 
-       el    = f->elines[p0->lid];
-       el->v = p0->v;
+                       el    = f->elines[p0->lid];
+                       el->v = p0->v;
 
-       el    = f->elines[p1->lid];
-       el->v = p1->v;
+                       el    = f->elines[p1->lid];
+                       el->v = p1->v;
 
-       ret = __ses_path_va(f, bridge, 0, bridge->pins->size - 1, changed, ns, count);
-       if (ret < 0) {
-               scf_loge("\n");
-               goto error;
+                       ret = __ses_path_va(f, bridge, changed, ns, count);
+                       if (ret < 0) {
+                               scf_loge("\n");
+                               goto error;
+                       }
+
+                       el = f->elines[p0->lid];
+                       if (el->vconst)
+                               el->v = tmp0;
+
+                       el = f->elines[p1->lid];
+                       if (el->vconst)
+                               el->v = tmp1;
+
+                       ret = __ses_flow_va(f, flow1, &flow1->pos_r, &flow1->neg_r, changed, ns, count);
+                       if (ret < 0)
+                               goto error;
+
+                       ret = __ses_flow_va(f, flow0, &flow0->pos_r, &flow0->neg_r, changed, ns, count);
+                       if (ret < 0)
+                               goto error;
+               }
        }
 
-       __ses_status_check_line(f, f->elines[p0->lid], changed);
-       __ses_status_check_line(f, f->elines[p1->lid], changed);
        ret = 0;
 error:
        ses_flow_free(flow0);
@@ -331,12 +475,9 @@ static int ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_path_
        if (!bridge || bridge->pins->size < 2)
                return -EINVAL;
 
-       if (bridge->n_capacitors > 0) {
-
-               ret = __ses_path_va_capacitor(f, paths, bridge, changed, ns, count);
-               if (ret < 0)
-                       return ret;
-       }
+       ret = __ses_path_va_capacitor(f, paths, bridge, changed, ns, count);
+       if (ret < 0)
+               return ret;
 
        if (bridge->bridges) {
                for (j = 0; j < bridge->bridges->size; j++) {
index 400747f41898774286e2b8384f2bfcf69fa6f892..be5f8f934ce7219e17ec16c73a3fb459d3ca7e3f 100644 (file)
@@ -76,10 +76,18 @@ void __ses_path_split_i(ScfEfunction* f, ses_path_t* path, int i, int j, double
                if (cp0->lid != p0->lid || cp1->lid != p1->lid)
                        continue;
 
-               ses_ur_i(&child->a, NULL, v, 0, child->pr, 0);
+               double cv = 0;
 
-               if (child->a >= la)
-                       ses_split_i(&child->a, NULL, la, 0, child->pr, 0, r, 0);
+               if (child->n_capacitors > 0) {
+                       __ses_path_capacitors(f, child, 0, child->pins->size - 1, &cv);
+                       v -= cv;
+                       ses_ur_i(&child->a, NULL, v, 0, child->pr, 0);
+               } else {
+                       ses_ur_i(&child->a, NULL, v, 0, child->pr, 0);
+
+                       if (child->a >= la)
+                               ses_split_i(&child->a, NULL, la, 0, child->pr, 0, r, 0);
+               }
 
                *a -= child->a;
 
@@ -89,7 +97,7 @@ void __ses_path_split_i(ScfEfunction* f, ses_path_t* path, int i, int j, double
                cp1->sr = child->sr;
                cp1->pr = child->pr;
 
-               if (child->n_diodes > 0) {
+               if (child->n_diodes + child->n_NPNs > 0) {
 
                        int ret = __ses_path_va_diode(f, child);
                        if (ret < 0)
@@ -98,8 +106,8 @@ void __ses_path_split_i(ScfEfunction* f, ses_path_t* path, int i, int j, double
                                goto ok;
                }
 
-               scf_logi("k: %d, c%ldp%ld--c%ldp%ld, v: %lg, child->pr: %lg, r: %lg, child->a: %lg, el->a: %lg\n",
-                               k, cp0->cid, cp0->id, cp1->cid, cp1->id, v, child->pr, r, child->a, la);
+               scf_logi("k: %d, c%ldp%ld--c%ldp%ld, v: %lg, cv: %lg, child->pr: %lg, r: %lg, child->a: %lg, el->a: %lg\n",
+                               k, cp0->cid, cp0->id, cp1->cid, cp1->id, v, cv, child->pr, r, child->a, la);
 
                cp1->v = p1->v;
                cp0->v = p0->v;
@@ -111,7 +119,7 @@ void __ses_path_split_i(ScfEfunction* f, ses_path_t* path, int i, int j, double
 
                cp0->a = ca;
 
-               if (child->n_diodes > 0)
+               if (child->n_diodes + child->n_NPNs > 0)
                        __ses_path_dr_forward(f, child, 0, child->pins->size - 1, ca);
 
 ok:
@@ -171,55 +179,21 @@ void __ses_path_dr_reverse(ScfEfunction* f, ses_path_t* path, int i, int j, doub
        }
 }
 
-ses_path_t* ses_path_find_child(ses_path_t* path, int m, int n)
-{
-       ses_path_t* child;
-       ScfEpin*    cp0;
-       ScfEpin*    cp1;
-
-       if (path->childs) {
-               ScfEpin* p0;
-               ScfEpin* p1 = path->pins->data[n];
-
-               int i;
-               int j;
-
-               for (i    = 0; i < path->childs->size; i++) {
-                       child =        path->childs->data[i];
-
-                       cp0 = child->pins->data[0];
-                       cp1 = child->pins->data[child->pins->size - 1];
-
-                       if (cp1->lid != p1->lid)
-                               continue;
-
-                       for (j = m; j <= n; j++) {
-                               p0 = path->pins->data[j];
-
-                               if (cp0->lid == p0->lid)
-                                       return child;
-                       }
-               }
-       }
-       return NULL;
-}
-
-static void __ses_path_a_diode(ScfEfunction* f, ses_path_t* path, int k, double* a)
+static void __ses_path_a_diode(ScfEfunction* f, ses_path_t* path, int i, int k, double cv, double* a)
 {
        ses_info_t* info;
        ses_path_t* child;
 
-       ScfEpin*    p0 = path->pins->data[0];
+       ScfEpin*    p0 = path->pins->data[i];
        ScfEpin*    p1 = path->pins->data[path->pins->size - 1];
        ScfEpin*    pi;
        ScfEpin*    pj;
 
-       double v = p0->v - p1->v;
+       double v = p0->v - p1->v - cv;
        double r = 0;
 
        double _r;
 
-       int i = 0;
        int j;
 
        for (j = k; j < path->infos->size; j++) {
@@ -227,12 +201,9 @@ static void __ses_path_a_diode(ScfEfunction* f, ses_path_t* path, int k, double*
                pi        = path->pins->data[i];
                pj        = path->pins->data[info->i];
 
-               v -= info->n_diodes * SCF_EDA_V_Diode_ON;
-               v -= info->n_NPNs   * SCF_EDA_V_NPN_ON;
+               v -= info->n_diodes * SCF_EDA_V_Diode_ON + info->n_NPNs * SCF_EDA_V_NPN_ON;
 
-               child = ses_path_find_child(path, i, info->i);
-
-               __ses_path_pr(f, path, i, info->i, child, &_r);
+               __ses_path_pr(f, path, i, info->i, NULL, &_r);
 
                r += _r;
 
@@ -247,9 +218,7 @@ static void __ses_path_a_diode(ScfEfunction* f, ses_path_t* path, int k, double*
                pi = path->pins->data[i];
                pj = path->pins->data[j];
 
-               child = ses_path_find_child(path, i, j);
-
-               __ses_path_pr(f, path, i, j, child, &_r);
+               __ses_path_pr(f, path, i, j, NULL, &_r);
 
                r += _r;
                scf_logd("c%ldp%ld--c%ldp%ld, r: %lg, v: %lg, _r: %lg\n", pi->cid, pi->id, pj->cid, pj->id, r, v, _r);
@@ -272,14 +241,12 @@ int __ses_path_va_diode(ScfEfunction* f, ses_path_t* path)
        ScfEpin*       pi;
        ScfEpin*       pj;
 
-       int j;
-
-       if (path->n_diodes * 2 >= path->pins->size) {
+       if ((path->n_diodes + path->n_NPNs) * 2 >= path->pins->size) {
                scf_loge("all components are diodes\n\n");
                return -1;
        }
 
-       if (path->n_diodes <= 0)
+       if (path->n_diodes + path->n_NPNs <= 0)
                return 0;
 
        p0 = path->pins->data[0];
@@ -294,54 +261,67 @@ int __ses_path_va_diode(ScfEfunction* f, ses_path_t* path)
        double v;
        double r;
        double a;
+       double cv = 0;
+
+       int i = 0;
+       int j;
 
        for (j = 0; j < path->infos->size; j++) {
                info      = path->infos->data[j];
                pi        = path->pins->data[info->i];
                pj        = path->pins->data[info->j];
 
-               c = f->components[pi->cid];
+               c  = f->components[pi->cid];
+               el = f->elines[pi->lid];
+               pi->v = el->v;
 
                assert((SCF_EDA_Diode == c->type && SCF_EDA_Diode_POS == pi->id)
                        || (SCF_EDA_NPN   == c->type && SCF_EDA_NPN_B     == pi->id));
 
-               __ses_path_a_diode(f, path, j, &a);
+               __ses_path_capacitors(f, path, i, path->pins->size - 1, &cv);
+
+               __ses_path_a_diode(f, path, i, j, cv, &a);
 
                if (a < 0)
                        break;
 
                if (0 == j)
-                       path->a  = a;
+                       path->a = a;
 
                pi->a = a;
 
-               __ses_path_pr(f, path, 0, info->i, NULL, &r);
+               __ses_path_pr(f, path, i, info->i, NULL, &r);
 
                ses_ir_u(&v, NULL, a, 0, r, 0);
 
-               pi->v = p0->v - v;
+               double cv2 = 0;
+               __ses_path_capacitors(f, path, i, info->i, &cv2);
+
+               pi->v = p0->v - v - cv2;
                pj->v = pi->v - info->n_diodes * SCF_EDA_V_Diode_ON - info->n_NPNs * SCF_EDA_V_NPN_ON;
 
-               scf_logi("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, r: %lg, v: %lg, a: %lg\n",
-                               p0->cid, p0->id, p0->v, pi->cid, pi->id, pi->v, pj->cid, pj->id, pj->v, r, v, a);
+               scf_logi("c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, c%ldp%ld->v: %lg, cv2: %lg, r: %lg, v: %lg, a: %lg\n",
+                               p0->cid, p0->id, p0->v, pi->cid, pi->id, pi->v, pj->cid, pj->id, pj->v, cv2, r, v, a);
 
                el         = f->elines[pi->lid];
-               el->a      = a;
                el->v      = pi->v;
-               el->aconst = 1;
+//             el->vconst = 1;
 
                el         = f->elines[pj->lid];
-               el->a      = a;
                el->v      = pj->v;
-               el->aconst = 1;
+//             el->vconst = 1;
 
-               if (path->childs)
-                       __ses_path_split_i(f, path, info->i, info->j, a, &pi->a);
+               if (path->childs) {
+                       __ses_path_split_i(f, path, info->i, path->pins->size - 1, a, &pi->a);
 
+                       if (info->j < path->pins->size - 1)
+                               __ses_path_split_i(f, path, info->i, info->j, a, &pi->a);
+               }
                scf_loge("info->i: %d, info->j: %d, c%ldp%ld--c%ldp%ld, pi->v: %lg, pj->v: %lg, pi->a: %lg\n\n",
                                info->i, info->j, pi->cid, pi->id, pj->cid, pj->id, pi->v, pj->v, pi->a);
 
                __ses_path_dr_forward(f, path, info->i, info->j, pi->a);
+               i = info->j + 1;
        }
 
        return 0;
index 3c0a08c7a2bbe65e0da6eca00be5e694c259ede6..482e3df39e64980b2d8f4fbbb08ae77de2ba4902 100644 (file)
@@ -104,9 +104,6 @@ _changed:
 
 int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path)
 {
-       ses_path_t*    parent = path->parent;
-       ses_path_t*    child;
-
        ScfEcomponent* c;
        ScfEline*      el;
        ScfEpin*       p0;
@@ -157,7 +154,7 @@ int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path)
                                                __ses_path_split_i(f, path, i, j, pj->a, &pc->a);
 
                                } else
-                                       pc->v  = pj->v;
+                                       pc->v = pj->v;
 
                                j = i;
                        }
@@ -176,8 +173,8 @@ int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path)
 
                pc->v = p0->v - v;
 
-               scf_logi("i: %d, c%ldp%ld--c%ldp%ld, v: %lg, pc->v: %lg, pc->a: %lg, pr: %lg, pc->pr: %lg, pb c%ldp%ld->a: %lg\n",
-                               i, p0->cid, p0->id, pc->cid, pc->id, v, pc->v, pc->a, pr, pc->pr, pb->cid, pb->id, pb->a);
+               scf_logi("i: %d, c%ldp%ld--c%ldp%ld, v: %lg, pc->v: %lg, pc->a: %lg, pr: %lg, pc->pr: %lg, pb c%ldp%ld->a: %lg, pj: c%ldp%ld->v: %lg\n",
+                               i, p0->cid, p0->id, pc->cid, pc->id, v, pc->v, pc->a, pr, pc->pr, pb->cid, pb->id, pb->a, pj->cid, pj->id, pj->v);
 
                if (pc->v < pj->v) {
                        v     = p0->v - pj->v;
@@ -198,26 +195,26 @@ int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path)
                                        i, p0->cid, p0->id, pc->cid, pc->id, v, pc->v, pc->a, pr, _pr, pc->pr);
                }
 
-               el     = f->elines[pc->lid];
-               el->v  = pc->v;
-               el->a  = pc->a;
-               el->vconst = 1;
+               el    = f->elines[pc->lid];
+               el->v = pc->v;
 
                scf_logw("i: %d, c%ldp%ld--c%ldp%ld, v: %lg, pc->v: %lg, pc->a: %lg, pr: %lg, pc->dr: %lg\n",
                                i, p0->cid, p0->id, pc->cid, pc->id, v, pc->v, pc->a, pr, pc->dr);
 
+               a = pc->a;
+
                if (path->childs) {
-                       __ses_path_split_i(f, path, i, j, el->a, &pc->a);
+                       __ses_path_split_i(f, path, i, j, a, &pc->a);
 
                        if (i > 0) {
                                p     = path->pins->data[i - 1];
-                               p->a  = el->a;
+                               p->a  = a;
                                p->v  = el->v;
 
-                               __ses_path_split_i(f, path, 0, i - 1, el->a, &p->a);
+                               __ses_path_split_i(f, path, 0, i - 1, a, &p->a);
                        }
                } else
-                       p0->a = el->a;
+                       p0->a = a;
 
                __ses_path_dr_transistor(f, path, i, j);
 
index 86e8f58805ab09ff0ce5249f0e84db439ab54cc7..6d9f5e01535526ee0c8d1fa43f245c851d752a6a 100644 (file)
@@ -17,14 +17,17 @@ extern ses_step_t   ses_step_jr;
 extern ses_step_t   ses_step_va_diode;
 extern ses_step_t   ses_step_va_transistor;
 extern ses_step_t   ses_step_va;
-extern ses_step_t   ses_step_va_bridge;
-extern ses_step_t   ses_step_va_line;
+extern ses_step_t   ses_step_status;
 
 extern ses_step_t   ses_step_open;
 extern ses_step_t   ses_step_va_capacitor;
 
+extern ses_step_t   ses_step_a_stat;
+extern ses_step_t   ses_step_a_balance;
+
 extern ses_step_t   ses_step_output;
 extern ses_step_t   ses_step_simplify;
+extern ses_step_t   ses_step_simplify2;
 
 
 static ses_step_t*  ses_steps_0[] =
@@ -48,20 +51,21 @@ static ses_step_t*  ses_steps_1[] =
 
 //     &ses_step_jr,
        &ses_step_va,
-       &ses_step_va_bridge,
-       &ses_step_va_line,
+       &ses_step_status,
 };
 
 static ses_step_t*  ses_steps_2[] =
 {
        &ses_step_open,
+//     &ses_step_simplify2,
        &ses_step_va_capacitor,
 
+//     &ses_step_a_stat,
+
        &ses_step_output,
        &ses_step_simplify,
 };
 
-
 static int __ses_analyse_input(ScfEfunction* f, int64_t ns, int64_t i, ses_ctx_t* ctx)
 {
        ses_step_t* s;
@@ -127,6 +131,7 @@ static int __ses_analyse_current(ScfEfunction* f, int64_t ns, int64_t i, ses_ctx
                }
        }
 
+       scf_loge("--------------- ctx->changed: %d\n", ctx->changed);
        return ctx->changed > 0 ? -EAGAIN : 0;
 }
 
index 85b828d46597efd2c9c497ce09bc09c1128c837d..a121ca06cf7101b17488fc2e38e4db9b79bba7fe 100644 (file)
 #include"ses_core.h"
 
-ses_flow_t* ses_flow_alloc()
+ses_ctx_t* ses_ctx_alloc()
 {
-       ses_flow_t* flow = calloc(1, sizeof(ses_flow_t));
-       if (!flow)
+       ses_ctx_t* ctx = calloc(1, sizeof(ses_ctx_t));
+       if (!ctx)
                return NULL;
 
-       flow->paths = scf_vector_alloc();
-       if (!flow->paths) {
-               ses_flow_free(flow);
+       ctx->paths = scf_vector_alloc();
+       if (!ctx->paths) {
+               free(ctx);
                return NULL;
        }
 
-       return flow;
-}
-
-void ses_flow_free(ses_flow_t* flow)
-{
-       if (flow) {
-               if (flow->paths)
-                       scf_vector_free(flow->paths);
-
-               free(flow);
-       }
+       return ctx;
 }
 
-int ses_paths_find_flow(ses_flow_t* flow, scf_vector_t* paths, ScfEpin* vip, ses_path_t* bridge)
+void ses_ctx_free(ses_ctx_t* ctx)
 {
-       ses_path_t* path;
-       ScfEpin*    p;
-
-       int i;
-       int j;
-
-       for (i = 0; i < paths->size; i++) {
-               path      = paths->data[i];
-
-               if (path == bridge)
-                       continue;
-
-               for (j = 0; j < path->pins->size; j++) {
-                       p  =        path->pins->data[j];
-
-                       if (vip ->lid == p->lid) {
-
-                               if (j + 1 >= path->pins->size)
-                                       break;
-
-                               flow->vip   = p;
-                               flow->vip_n = path->pins->data[j + 1];;
-
-                               if (scf_vector_add(flow->paths, path) < 0)
-                                       return -1;
-                               return 1;
-                       }
-               }
-
-               if (path->childs) {
-                       int ret = ses_paths_find_flow(flow, path->childs, vip, bridge);
-                       if (ret < 0)
-                               return ret;
-
-                       if (1 == ret) {
-                               if (scf_vector_add(flow->paths, path) < 0)
-                                       return -ENOMEM;
-                               return 1;
-                       }
-               }
-
-               if (path->bridges) {
-                       int ret = ses_paths_find_flow(flow, path->bridges, vip, bridge);
-                       if (ret < 0)
-                               return ret;
-
-                       if (1 == ret) {
-                               if (scf_vector_add(flow->paths, path) < 0)
-                                       return -ENOMEM;
-                               return 1;
-                       }
+       if (ctx) {
+               if (ctx->paths) {
+                       scf_vector_clear(ctx->paths, ( void (*)(void*) )ses_path_free);
+                       scf_vector_free (ctx->paths);
                }
-       }
-
-       return 0;
-}
-
-int ses_flow_find_neg(ses_flow_t* flow, scf_vector_t* paths, ScfEfunction* f)
-{
-       if (flow->paths->size <= 0)
-               return 0;
-
-       ses_path_t*    path = flow->paths->data[flow->paths->size - 1];
-       ScfEpin*       vp   = flow->vip;
-       ScfEpin*       vn   = flow->vip_n;
-       ScfEpin*       p    = path->pins->data[path->pins->size - 1];
-
-       ScfEcomponent* B    = f->components[0];
-       ScfEpin*       Bn   = B->pins[SCF_EDA_Battery_NEG];
-
-       while (p->lid != Bn->lid) {
-               int ret = ses_paths_find_flow(flow, paths, p, path);
-               if (ret < 0)
-                       return ret;
-
-               path = flow->paths->data[flow->paths->size - 1];
-               p    = path->pins ->data[path->pins->size - 1];
-       }
-
-       flow->vip   = vp;
-       flow->vip_n = vn;
-       return 0;
-}
-
-int ses_flow_find_pos(ses_flow_t* flow, scf_vector_t* paths, ScfEfunction* f)
-{
-       if (flow->paths->size <= 0)
-               return 0;
 
-       ses_path_t*    path = flow->paths->data[flow->paths->size - 1];
-       ScfEpin*       vp   = flow->vip;
-       ScfEpin*       vn   = flow->vip_n;
-       ScfEpin*       p    = path->pins->data[0];
-
-       ScfEcomponent* B    = f->components[0];
-       ScfEpin*       Bp   = B->pins[SCF_EDA_Battery_POS];
-
-       while (p->lid != Bp->lid) {
-               int ret = ses_paths_find_flow(flow, paths, p, path);
-               if (ret < 0)
-                       return ret;
-
-               path = flow->paths->data[flow->paths->size - 1];
-               p    = path->pins ->data[0];
+               free(ctx);
        }
-
-       flow->vip   = vp;
-       flow->vip_n = vn;
-       return 0;
 }
 
-int ses_flows_make_path(ses_path_t** ppath, ses_flow_t* pos, ses_flow_t* neg, ses_path_t* bridge, int reverse)
+ses_edge_t* ses_edge_alloc(ses_path_t* path, int first, int last)
 {
-       if (!pos || !neg || !bridge)
-               return -EINVAL;
-
-       if (!pos->paths || !pos->vip || !neg->paths || !neg->vip_n)
-               return -EINVAL;
-
-       *ppath = ses_path_alloc();
-       if (!*ppath)
-               return -ENOMEM;
-
-       ses_path_t*    path;
-       ScfEcomponent* c;
-       ScfEpin*       p;
-       ScfEpin*       p0;
-       ScfEpin*       vip = pos->vip;
-
-       int i;
-       int j;
-
-       for (i   = 0; i < pos->paths->size; i++) {
-               path =        pos->paths->data[i];
-
-               for (j = 0; j < path->pins->size; j++) {
-                       p  =        path->pins->data[j];
-
-                       if (p->lid == vip->lid) {
-                               vip = path->pins->data[0];
-                               break;
-                       }
-               }
-
-               assert(j < path->pins->size);
-
-               for ( ; j >= 0; j--) {
-                       p = path->pins->data[j];
-
-                       if (scf_vector_add((*ppath)->pins, p) < 0) {
-                               ses_path_free(*ppath);
-                               *ppath = NULL;
-                               return -ENOMEM;
-                       }
-               }
-       }
-
-       // positive branch is reversed, make it normal
-       i = 0;
-       j = (*ppath)->pins->size - 1;
-
-       while (i < j) {
-               SCF_XCHG((*ppath)->pins->data[i], (*ppath)->pins->data[j]);
-               i++;
-               j--;
-       }
-
-       // add the bridge by the reverse flag
-       if (!reverse) {
-               for (j = 0; j < bridge->pins->size; j++) {
-                       p  =        bridge->pins->data[j];
-
-                       if (scf_vector_add((*ppath)->pins, p) < 0) {
-                               ses_path_free(*ppath);
-                               *ppath = NULL;
-                               return -ENOMEM;
-                       }
-               }
-       } else {
-               for (j = bridge->pins->size - 1; j >= 0; j--) {
-                       p  = bridge->pins->data[j];
-
-                       if (scf_vector_add((*ppath)->pins, p) < 0) {
-                               ses_path_free(*ppath);
-                               *ppath = NULL;
-                               return -ENOMEM;
-                       }
-               }
-       }
-
-       // negative branch is normal
-       vip = neg->vip;
-
-       for (i   = 0; i < neg->paths->size; i++) {
-               path =        neg->paths->data[i];
-
-               for (j = 0; j < path->pins->size; j++) {
-                       p  =        path->pins->data[j];
-
-                       if (p->lid == vip->lid)
-                               break;
-               }
-
-               for (++j; j < path->pins->size; j++) {
-                       p       = path->pins->data[j];
+       ses_edge_t* edge = calloc(1, sizeof(ses_edge_t));
+       if (!edge)
+               return NULL;
 
-                       if (scf_vector_add((*ppath)->pins, p) < 0) {
-                               ses_path_free(*ppath);
-                               *ppath = NULL;
-                               return -ENOMEM;
-                       }
-               }
+       edge->path  = path;
+       edge->vip_m = first;
+       edge->vip_n = last;
 
-               vip = path->pins->data[j - 1];
-       }
-
-       return 0;
+       edge->refs = 1;
+       return edge;
 }
 
-void ses_flow_jr(ses_flow_t* flow, ScfEfunction* f)
+void ses_edge_free(ses_edge_t* edge)
 {
-       if (!flow)
-               return;
+       if (edge) {
+               if (--edge->refs > 0)
+                       return;
 
-       flow->pos_pins = 0;
-       flow->neg_pins = 0;
+               assert(0 == edge->refs);
 
-       flow->pos_r = 0;
-       flow->neg_r = 0;
-
-       if (!flow->paths || !flow->vip)
-               return;
-
-       ses_path_t*    path;
-       ses_path_t*    child;
-       ScfEcomponent* c;
-       ScfEpin*       p;
-       ScfEpin*       p0;
-       ScfEpin*       vip = flow->vip;
-
-       int i;
-       int j;
-
-       for (i   = 0; i < flow->paths->size; i++) {
-               path =        flow->paths->data[i];
-
-               for (j = 0; j < path->pins->size; j++) {
-                       p  =        path->pins->data[j];
-
-                       ++flow->pos_pins;
-
-                       c = f->components[p->cid];
-
-                       if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_B == p->id)
-                               flow->pos_NPNs++;
-                       else if (SCF_EDA_Diode == c->type && SCF_EDA_Diode_POS == p->id)
-                               flow->pos_diodes++;
-
-                       if (p->lid == vip->lid) {
-                               vip = path->pins->data[0];
-
-                               double pr = p->pr;
-
-                               if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_E == p->id)
-                                       __ses_npn_epr(f, p, &pr);
-
-                               flow->pos_r += pr;
-
-                               scf_logd("flow->pos_r: %lg, c%ldp%ld->pr: %lg, pr: %lg, vip c%ldp%ld->pr: %lg\n",
-                                               flow->pos_r, p->cid, p->id, p->pr, pr, vip->cid, vip->id, vip->pr);
-                               break;
-                       }
-               }
+               free(edge);
        }
-
-       vip = flow->vip;
-
-       for (i   = 0; i < flow->paths->size; i++) {
-               path =        flow->paths->data[i];
-
-               int j0;
-
-               p0 = NULL;
-               for (j = 0; j < path->pins->size; j++) {
-                       p  =        path->pins->data[j];
-
-                       if (!p0) {
-                               if (p->lid == vip->lid) {
-                                       p0 = p;
-                                       j0 = j;
-                               }
-                               continue;
-                       }
-
-                       ++flow->neg_pins;
-
-                       c = f->components[p->cid];
-
-                       if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_B == p->id)
-                               flow->neg_NPNs++;
-                       else if (SCF_EDA_Diode == c->type && SCF_EDA_Diode_POS == p->id)
-                               flow->neg_diodes++;
-
-                       if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_E == p->id) {
-                               p = path->pins->data[j - 1];
-
-                               if (p->lid == p0->lid)
-                                       flow->neg_r += p->r + p->dr;
-                               else
-                                       flow->neg_r += p->pr - p0->pr;
-
-                               scf_logd("flow->neg_r: %lg, c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n",
-                                               flow->neg_r, p->cid, p->id, p->sr, p0->cid, p0->id, p0->pr);
-
-                               if (j + 1 < path->pins->size) {
-                                       p0    = path->pins->data[j + 1];
-                                       j0    = j + 1;
-                               } else {
-                                       p0    = path->pins->data[j];
-                                       j0    = j;
-                               }
-
-                       } else if (p->sr != p->pr) {
-
-                               child = ses_path_find_child(path, j0, j);
-                               if (child)
-                                       flow->neg_r += child->parent_pr - p0->pr;
-                               else
-                                       flow->neg_r += p->sr - p0->pr;
-
-                               scf_logd("flow->neg_r: %lg, c%ldp%ld->sr: %lg, p->pr: %lg, p0 c%ldp%ld->pr: %lg\n",
-                                               flow->neg_r, p->cid, p->id, p->sr, p->pr, p0->cid, p0->id, p0->pr);
-                               p0 = p;
-                               j0 = j;
-                       }
-               }
-
-               if (p0) {
-                       vip = path->pins->data[j - 1];
-                       c   = f->components[vip->cid];
-
-                       if (vip != p0) {
-                               child = ses_path_find_child(path, j0, j - 1);
-                               if (child)
-                                       flow->neg_r += child->parent_pr - p0->pr;
-                               else
-                                       flow->neg_r += vip->sr - p0->pr;
-                       }
-
-                       scf_logd("flow->neg_r: %lg, vip c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n",
-                                       flow->neg_r, vip->cid, vip->id, vip->sr, p0->cid, p0->id, p0->pr);
-
-                       if (SCF_EDA_NPN == c->type && SCF_EDA_NPN_E == vip->id) {
-                               vip->pr  = path->parent_pr;
-                               vip->jpr = path->parent_jpr;
-                       }
-               }
-
-               scf_logd("flow->neg_r: %lg, vip c%ldp%ld->sr: %lg\n", flow->neg_r, vip->cid, vip->id, vip->sr);
-       }
-
-       scf_loge("flow pos_r: %lg, neg_r: %lg, vip: c%ldp%ld, pos_diodes: %d, pos_NPNs: %d, neg_diodes: %d, neg_NPNs: %d\n",
-                       flow->pos_r, flow->neg_r, flow->vip->cid, flow->vip->id, flow->pos_diodes, flow->pos_NPNs, flow->neg_diodes, flow->neg_NPNs);
 }
 
-void ses_flow_print(ses_flow_t* flow)
+void ses_edge_print(ses_edge_t* edge)
 {
-       if (!flow || !flow->paths || !flow->vip)
+       if (!edge)
                return;
 
-       ses_path_t* path;
-       ScfEpin*    p;
-       ScfEpin*    vip = flow->vip;
-
-       int i;
-       int j;
-
-       for (i = flow->paths->size - 1; i >= 0; i--) {
-
-               if (i > 0) {
-                       path = flow->paths->data[i - 1];
-                       vip  = path->pins->data[0];
-               } else
-                       vip  = flow->vip;
-
-               path = flow->paths->data[i];
+       ScfEpin* p;
+       int      j;
 
-               for (j = 0; j < path->pins->size; j++) {
-                       p  =        path->pins->data[j];
+       if (edge->vip_m < edge->vip_n) {
 
-                       printf("c%ldp%ld ", p->cid, p->id);
+               for (j = edge->vip_m; j <= edge->vip_n; j++) {
+                       p  = edge->path->pins->data[j];
 
-                       if (p->lid == vip->lid)
-                               break;
+                       if (j < edge->vip_n)
+                               printf("c%ldp%ld, ", p->cid, p->id);
+                       else
+                               printf("c%ldp%ld; ", p->cid, p->id);
                }
 
-               if (i > 0)
-                       printf(", ");
-       }
-
-       printf(";\n");
-
-       vip = flow->vip;
-
-       for (i   = 0; i < flow->paths->size; i++) {
-               path =        flow->paths->data[i];
-
-               int flag = 0;
-
-               for (j = 0; j < path->pins->size; j++) {
-                       p  =        path->pins->data[j];
-
-                       if (!flag) {
-                               if (p->lid == vip->lid)
-                                       flag = 1;
-                               continue;
-                       }
+       } else {
+               for (j = edge->vip_m; j >= edge->vip_n; j--) {
+                       p  = edge->path->pins->data[j];
 
-                       printf("c%ldp%ld ", p->cid, p->id);
+                       if (j > edge->vip_n)
+                               printf("c%ldp%ld, ", p->cid, p->id);
+                       else
+                               printf("c%ldp%ld; ", p->cid, p->id);
                }
-
-               if (flag)
-                       printf(", ");
-
-               vip = path->pins->data[j - 1];
        }
-
-       printf(".\n");
 }
 
-ses_path_t* ses_path_alloc()
+ses_mesh_t* ses_mesh_alloc()
 {
-       ses_path_t* path = calloc(1, sizeof(ses_path_t));
-       if (!path)
+       ses_mesh_t* mesh = calloc(1, sizeof(ses_mesh_t));
+       if (!mesh)
                return NULL;
 
-       path->pins = scf_vector_alloc();
-       if (!path->pins) {
-               free(path);
+       mesh->edges = scf_vector_alloc();
+       if (!mesh->edges) {
+               free(mesh);
                return NULL;
        }
 
-       path->infos = scf_vector_alloc();
-       if (!path->infos) {
-               scf_vector_free(path->pins);
-               free(path);
-               return NULL;
-       }
-
-       return path;
+       return mesh;
 }
 
-void ses_path_free(ses_path_t* path)
+void ses_mesh_free(ses_mesh_t* mesh)
 {
-       if (path) {
-               if (path->pins)
-                       scf_vector_free(path->pins);
-
-               if (path->infos) {
-                       scf_vector_clear(path->infos, ( void (*)(void*) )free);
-                       scf_vector_free (path->infos);
-               }
-
-               if (path->childs) {
-                       scf_vector_clear(path->childs, ( void (*)(void*) )ses_path_free);
-                       scf_vector_free (path->childs);
-               }
-
-               if (path->bridges) {
-                       scf_vector_clear(path->bridges, ( void (*)(void*) )ses_path_free);
-                       scf_vector_free (path->bridges);
-               }
-
-               scf_logd("path: %d\n", path->index);
+       if (mesh) {
+               scf_vector_clear(mesh->edges, (void (*)(void*) )ses_edge_free);
+               scf_vector_free(mesh->edges);
 
-               free(path);
+               free(mesh);
        }
 }
 
-void ses_path_print(ses_path_t* path)
+void ses_meshs_free(scf_vector_t* meshs)
 {
-       if (!path)
-               return;
-
-       ses_path_t* path2;
-       ScfEpin*    p;
-
-       int i;
-
-       if (!path->parent)
-               printf("\033[31mpath  : %d, n_diodes: %d, infos->size: %d, \033[0m", path->index, path->n_diodes, path->infos->size);
-
-       for (i = 0; i < path->pins->size; i++) {
-               p  =        path->pins->data[i];
-
-               printf("c%ldp%ldd%d ", p->cid, p->id, p->n_diodes);
-       }
-       printf("\n");
-
-       if (path->childs) {
-               for (i = 0; i < path->childs->size; i++) {
-                       path2     = path->childs->data[i];
-
-                       printf("\033[32mchild : %d, n_diodes: %d, infos->size: %d, parent: %d, \033[0m", path2->index, path2->n_diodes, path2->infos->size, path->index);
-
-                       ses_path_print(path2);
-               }
-       }
-
-       if (path->bridges) {
-               for (i = 0; i < path->bridges->size; i++) {
-                       path2     = path->bridges->data[i];
-
-                       printf("\033[33mbridge: %d, n_diodes: %d, infos->size: %d, parent: %d, \033[0m", path2->index, path2->n_diodes, path2->infos->size, path->index);
-
-                       ses_path_print(path2);
-               }
-       }
-}
-
-int ses_path_xchg(ses_path_t* path0, int k0, ses_path_t* path1, int k1)
-{
-       ScfEpin* p;
-
-       int i;
-
-       for (i = 0; i + k0 < path0->pins->size && i + k1 < path1->pins->size; i++)
-               SCF_XCHG(path0->pins->data[i + k0], path1->pins->data[i + k1]);
-
-       scf_logd("path0: %d, k0: %d ... path1: %d, k1: %d, i: %d\n", path0->pins->size, k0, path1->pins->size, k1, i);
-
-       if (i + k0 < path0->pins->size) {
-
-               while (i + k0 < path0->pins->size) {
-                       p         = path0->pins->data[i + k0];
-
-                       assert(0 == scf_vector_del(path0->pins, p));
-
-                       if (scf_vector_add(path1->pins, p) < 0)
-                               return -ENOMEM;
-               }
-
-       } else if (i + k1 < path1->pins->size) {
-
-               while (i + k1 < path1->pins->size) {
-                       p         = path1->pins->data[i + k1];
-
-                       assert(0 == scf_vector_del(path1->pins, p));
-
-                       if (scf_vector_add(path0->pins, p) < 0)
-                               return -ENOMEM;
-               }
+       if (meshs) {
+               scf_vector_clear(meshs, (void (*)(void*) )ses_mesh_free);
+               scf_vector_free(meshs);
        }
-
-       return 0;
 }
 
-int ses_path_add(ses_path_t* parent, ses_path_t* child, ScfEfunction* f)
+void ses_mesh_print(ses_mesh_t* mesh)
 {
-       if (!parent || !child)
-               return -EINVAL;
-
-       if (!parent->childs) {
-               parent->childs = scf_vector_alloc();
-               if (!parent->childs)
-                       return -ENOMEM;
-       }
-
-       ses_path_t* path;
-       ScfEpin*    p0;
-       ScfEpin*    p1;
-       ScfEpin*    cp0 = child->pins->data[0];
-       ScfEpin*    cp1 = child->pins->data[child->pins->size - 1];
-
-       int j;
-
-       for (j = 0; j < parent->childs->size; j++) {
-               path      = parent->childs->data[j];
-
-               p0        = path->pins->data[0];
-               p1        = path->pins->data[path->pins->size - 1];
-
-               if (p0->lid == cp0->lid && p1->lid == cp1->lid) {
-
-                       if (child->pins->size == child->n_diodes * 2
-                         && path->pins->size  >  path->n_diodes * 2) {
-
-                               parent->childs->data[j] = child;
-                               child->parent           = parent;
-                               child->parent_p0        = path->parent_p0;
-                               child->parent_p1        = path->parent_p1;
-                               child->type             = SES_PATH_BRANCH;
-
-                               return ses_path_add(child, path, f);
-                       } else
-                               return ses_path_add(path, child, f);
-               }
-       }
-
-       if (scf_vector_add(parent->childs, child) < 0)
-               return -ENOMEM;
-
-       for (j = 0; j < parent->pins->size; j++) {
-               p0 =        parent->pins->data[j];
-
-               if (p0->lid == cp0->lid) {
-                       child->parent_p0 = (j + 1) & ~0x1;
-                       break;
-               }
-       }
-       assert(j < parent->pins->size);
-
-       int n_capacitors = 0;
-
-       for ( ; j < parent->pins->size; j++) {
-               p0    = parent->pins->data[j];
-
-               if (!(j & 0x1)) {
-                       ScfEcomponent* c = f->components[p0->cid];
-
-                       if (SCF_EDA_Capacitor == c->type)
-                               n_capacitors++;
-               }
-
-               if (p0->lid == cp1->lid) {
-                       child->parent_p1 = j;
-                       break;
-               }
-       }
-       assert(j < parent->pins->size);
-
-       if (n_capacitors > 0 && 0 == child->n_capacitors) {
-
-               int ret = ses_path_xchg(parent, child->parent_p0, child, 0);
-               if (ret < 0)
-                       return ret;
-
-               j                = child->parent_p1 - child->parent_p0 + 1;
-               child->parent_p1 = parent->pins->size - 1;
-
-               while (j < child->pins->size) {
-                       p0   = child->pins->data[j];
-
-                       assert(0 == scf_vector_del(child->pins, p0));
-
-                       ret = scf_vector_add(parent->pins, p0);
-                       if (ret < 0)
-                               return ret;
-               }
-
-               child ->n_capacitors  = n_capacitors;
-               parent->n_capacitors -= n_capacitors;
-       }
-
-       child->parent = parent;
-       child->type   = SES_PATH_BRANCH;
-       return 0;
-}
+       if (!mesh)
+               return;
 
-ses_path_t* ses_path_save(ses_path_t* src)
-{
-       ses_path_t* dst = ses_path_alloc();
-       if (!dst)
-               return NULL;
-
-       ScfEpin* p;
-       ScfEpin* p2;
+       ses_edge_t* edge;
 
        int i;
-       for (i = 0; i < src->pins->size; i++) {
-               p  =        src->pins->data[i];
-
-               p2 = malloc(sizeof(ScfEpin));
-               if (!p2) {
-                       scf_vector_clear(dst->pins, (void (*)(void*) )free);
-                       ses_path_free(dst);
-                       return NULL;
-               }
 
-               if (scf_vector_add(dst->pins, p2) < 0) {
-                       scf_vector_clear(dst->pins, (void (*)(void*) )free);
-                       ses_path_free(dst);
-                       free(p2);
-                       return NULL;
-               }
+       for (i = 0; i < mesh->edges->size; i++) {
+               edge      = mesh->edges->data[i];
 
-               memcpy(p2, p, sizeof(ScfEpin));
+               ses_edge_print(edge);
        }
-
-       return dst;
+       printf("\n");
 }
 
-int ses_path_load(ses_path_t* dst, ses_path_t* src)
+void ses_meshs_print(scf_vector_t* meshs)
 {
-       if (!dst || !src || dst->pins->size != src->pins->size)
-               return -EINVAL;
-
-       ScfEpin* p;
-       ScfEpin* p2;
+       if (!meshs)
+               return;
 
        int i;
-       for (i = 0; i < src->pins->size; i++) {
-               p  =        src->pins->data[i];
-               p2 =        dst->pins->data[i];
-
-               if (p2->cid != p->cid || p2->id != p->id)
-                       return -EINVAL;
+       for (i = 0; i < meshs->size; i++) {
 
-               memcpy(p, p2, sizeof(ScfEpin));
-       }
-
-       return 0;
-}
-
-ses_ctx_t* ses_ctx_alloc()
-{
-       ses_ctx_t* ctx = calloc(1, sizeof(ses_ctx_t));
-       if (!ctx)
-               return NULL;
-
-       ctx->paths = scf_vector_alloc();
-       if (!ctx->paths) {
-               free(ctx);
-               return NULL;
-       }
-
-       return ctx;
-}
-
-void ses_ctx_free(ses_ctx_t* ctx)
-{
-       if (ctx) {
-               if (ctx->paths) {
-                       scf_vector_clear(ctx->paths, ( void (*)(void*) )ses_path_free);
-                       scf_vector_free (ctx->paths);
-               }
-
-               free(ctx);
+               ses_mesh_print(meshs->data[i]);
        }
 }
 
@@ -795,3 +173,35 @@ void __ses_npn_dr(ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe)
        } else if (v > SCF_EDA_V_NPN_OFF)
                pb->dr = pb->r * (SCF_EDA_V_NPN_ON - SCF_EDA_V_NPN_OFF) / (v - SCF_EDA_V_NPN_OFF + 0.001);
 }
+
+void ses_elines_print(ScfEfunction* f)
+{
+       ScfEline* el;
+
+       int i;
+
+       for (i = 0; i < f->n_elines; i++) {
+               el =        f->elines[i];
+
+               printf("### e%ld->v: %lg\n", el->id, el->v);
+       }
+}
+
+void ses_components_print(ScfEfunction* f)
+{
+       ScfEcomponent* c;
+       ScfEpin*       p;
+
+       int i;
+       int j;
+
+       for (i = 0; i < f->n_components; i++) {
+               c  =        f->components[i];
+
+               for (j = 0; j < c->n_pins; j++) {
+                       p  =        c->pins[j];
+
+                       printf("c%ldp%ld->v: %lg\n", p->cid, p->id, p->v);
+               }
+       }
+}
index c8532e48c3bec4aeb199f8f2c58f79350f9a93be..823eab276268b04d504945977b650663f18d1339 100644 (file)
@@ -82,11 +82,97 @@ void bridge2()
        printf("Vbc + Vb + V0: %lg, V2: %lg\n", Vbc + Vb + V0, V2);
 }
 
+void PNN()
+{
+       U0 = 6;
+       U1 = 0.7;
+       U2 = 0.7;
+       R0 = 10000;
+       R1 = 1000;
+       R2 = 750;
+
+       double i1 = (R0 * (U2 - U1) + R2 * (U0 - U1)) / (R0 * R1 + R1 * R2 + R0 * R2);
+       double i0 = (U0 - U1 - i1 * R1) / R0;
+       double i2 = i0 - i1;
+
+       double V0 = i0 * R0;
+       double V1 = i1 * R1;
+       double V2 = i2 * R2;
+
+       printf("R0: %lg, i0: %lg, V0: %lg\n", R0, i0, V0);
+       printf("R1: %lg, i1: %lg, V1: %lg\n", R1, i1, V1);
+       printf("R2: %lg, i2: %lg, V2: %lg\n", R2, i2, V2);
+
+       printf("V0 + V1: %lg, U0 - U1: %lg\n", V0 + V1, U0 - U1);
+       printf("V0 + V2: %lg, U0 - U2: %lg\n", V0 + V2, U0 - U2);
+}
+
+void PPN()
+{
+       U0 = 6;
+       U1 = 0.7;
+       U2 = 5.3;
+       R0 = 2000;
+       R1 = 10000;
+       R2 = 750;
+
+       double i1 = (R0 * (U2 - U1) + R2 * (U0 - U1)) / (R0 * R1 + R1 * R2 + R0 * R2);
+       double i0 = (U0 - U1 - i1 * R1) / R0;
+       double i2 = i1 - i0;
+
+       double V0 = i0 * R0;
+       double V1 = i1 * R1;
+       double V2 = i2 * R2;
+
+       printf("R0: %lg, i0: %lg, V0: %lg\n", R0, i0, V0);
+       printf("R1: %lg, i1: %lg, V1: %lg\n", R1, i1, V1);
+       printf("R2: %lg, i2: %lg, V2: %lg\n", R2, i2, V2);
+
+       printf("U0 - V0: %lg, U2 - V2: %lg, U1 + V1: %lg\n", U0 - V0, U2 - V2, U1 + V1);
+}
+
+void add()
+{
+       double R0 = 1000;
+       double R1 = 10000;
+       double R  = R0 + R1 / 4;
+       double U  = 6;
+
+       double i0 = U / R;
+       double i1 = (U - i0 * R0) / R1;
+
+       double r  = R1 + (R0 * R1 / 3) / (R0 + R1 / 3);
+       double i3 = U / r;
+       double i2 = (U - i3 * R1) / R0;
+       double i4 = (U - i3 * R1) / R1;
+
+       double I0 = i0 - i2;
+       double I3 = i3 - i1;
+       double I4 = i1 + i4;
+
+       double V0 = I0 * R0;
+       double V3 = I3 * R1;
+       double V4 = I4 * R1;
+
+       printf("R0: %lg, i0: %lg, i2: %lg, I0: %lg, V0: %lg\n", R0, i0, i2, I0, V0);
+       printf("R3: %lg, i3: %lg, i1: %lg, I3: %lg, V3: %lg\n", R1, i3, i1, I3, V3);
+       printf("R4: %lg, i4: %lg, i1: %lg, I4: %lg, V4: %lg\n", R1, i4, i1, I4, V4);
+}
+
 int main()
 {
        bridge();
        printf("---------------\n\n");
 
        bridge2();
+       printf("---------------\n\n");
+
+       PNN();
+       printf("---------------\n\n");
+
+       PPN();
+       printf("---------------\n\n");
+
+       add();
        return 0;
 }
index 1afc2b5b14e80c57abfad581dd86bc5f57a7ffa5..4e0a28498ca2658389e6841d70d2cda6cdb2269a 100644 (file)
@@ -70,7 +70,7 @@ int main(int argc, char* argv[])
        EDA_PIN_ADD_PIN(R2, 0,                    B,  SCF_EDA_Battery_NEG);
 
        T0->pins[SCF_EDA_NPN_C]->flags |= SCF_EDA_PIN_OUT;
-       T0->pins[SCF_EDA_NPN_C]->hfe    = 50;
+       T0->pins[SCF_EDA_NPN_C]->hfe    = 80;
 
        R1->r  = 1000 * 10;
        R2->r  = 1000 * 10;
@@ -92,7 +92,7 @@ int main(int argc, char* argv[])
        ScfEboard_free(b);
        b = NULL;
 
-       FILE* fp = fopen("./sin_oscillator.pack", "wb");
+       FILE* fp = fopen("./sin_oscillator.cpk", "wb");
        if (!fp)
                return -EINVAL;