node analysis for DC
authoryu.dongliang <18588496441@163.com>
Fri, 7 Jun 2024 11:06:19 +0000 (19:06 +0800)
committeryu.dongliang <18588496441@163.com>
Fri, 7 Jun 2024 11:06:19 +0000 (19:06 +0800)
Makefile
examples/add.cpk
main.c
scf_eda_pack.c
ses_mesh_analysis.c [deleted file]
ses_node_analysis.c
ses_path.c
ses_step_simplify.c
ses_step_simplify2.c [deleted file]
ses_step_topo.c
ses_step_va_capacitor.c [deleted file]

index 4535c6cf84d97a4c39dee79a6183dd28fa8222a3..c2528e8045f6d0b51ce70f0d548d1cc09481b6b8 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -35,7 +35,6 @@ 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./
index ed6037bdab3a8326037f1da43e53375b3fef996a..81750b927a09a87201365ecb5486c0f6ce55611c 100644 (file)
Binary files a/examples/add.cpk and b/examples/add.cpk differ
diff --git a/main.c b/main.c
index 9757d9a2e6cce6bc2e54db26c6f859bdb4fe1f2e..f04f341d25340746ee3abc7d56551ca09de239ac 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, 100, 76000);
+               ses_steps_analyse(f, 100, 3);
        }
 #endif
 
index ab2f548bf4aab062789e26d220988d6ba2a7df9a..cd251bf89978bb3e5331f6ba7e62167fd4846df4 100644 (file)
@@ -31,10 +31,10 @@ static scf_edata_t  pin_datas[] =
        {SCF_EDA_Diode,      0,   SCF_EDA_Diode_NEG, 0, 0,  750,   0,   0, 0},
 
        {SCF_EDA_NPN,        0,       SCF_EDA_NPN_B, 0, 0,  750,   0,   0, 0},
-       {SCF_EDA_NPN,        0,       SCF_EDA_NPN_C, 0, 0,   10,   0,   0, 150},
+       {SCF_EDA_NPN,        0,       SCF_EDA_NPN_C, 0, 0,    3,   0,   0, 250},
 
        {SCF_EDA_PNP,        0,       SCF_EDA_PNP_B, 0, 0,  750,   0,   0, 0},
-       {SCF_EDA_PNP,        0,       SCF_EDA_PNP_C, 0, 0,   10,   0,   0, 150},
+       {SCF_EDA_PNP,        0,       SCF_EDA_PNP_C, 0, 0,    3,   0,   0, 250},
 };
 
 static scf_edata_t* _pin_find_data(const uint64_t type, const uint64_t model, const uint64_t pid)
diff --git a/ses_mesh_analysis.c b/ses_mesh_analysis.c
deleted file mode 100644 (file)
index 0a9f62e..0000000
+++ /dev/null
@@ -1,451 +0,0 @@
-#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;
-}
-
-static 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
-*/
-
-static 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 r;
-
-       __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;
-
-               if (0 == edge->vip_m && edge->vip_n == edge->path->pins->size - 1)
-                       r  = edge->path->pr;
-               else
-                       __ses_path_sr(f, edge->path, edge->vip_m, edge->vip_n, &r);
-
-               edge->r = r;
-
-               p0 = edge->path->pins->data[edge->vip_m];
-               p1 = edge->path->pins->data[edge->vip_n];
-               scf_logi("c%ldp%ld-c%ldp%ld, r: %lg, cv: %lg\n", p0->cid, p0->id, p1->cid, p1->id, r, cv);
-
-               A[i * N     + i] = 1;
-               A[i * N + n + i] = -r;
-
-               if (i < n - 1)
-                       A[i * N + n + i + 1] =  r;
-       }
-
-       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)
-                               r  = edge->path->pr;
-                       else
-                               __ses_path_sr(f, edge->path, edge->vip_n, edge->vip_m, &r);
-
-                       __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)
-                               r  = edge->path->pr;
-                       else
-                               __ses_path_sr(f, edge->path, edge->vip_m, edge->vip_n, &r);
-               }
-
-               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] = -r;
-               } else
-                       b[n + i] += pm->v;
-
-               A[(n + i) * N + 2 * n] = -r;
-
-               p0 = edge->path->pins->data[edge->vip_m];
-               p1 = edge->path->pins->data[edge->vip_n];
-       
-               edge->r = r;
-
-               scf_logi("c%ldp%ld-c%ldp%ld, r: %lg, cv: %lg, vip_m: %d, vip_n: %d\n", p0->cid, p0->id, p1->cid, p1->id, r, 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_va_branch(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_va_branch(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;
-}
index 4167499d5822668a4f7ed656723997c7c774971b..02fa9a37ff6df0593e2a2d6669c7ba2a88b6b7ee 100644 (file)
@@ -43,10 +43,10 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s
        ses_path_t*    bridge;
        ses_path_t*    conn;
 
-       ses_edge_t*    edge   = NULL;
-       ses_edge_t*    edge_c = NULL;
-       ses_node_t*    prev   = NULL;
-       ses_node_t*    node   = NULL;
+       ses_edge_t*    edge  = NULL;
+       ses_edge_t*    edge2 = NULL;
+       ses_node_t*    prev  = NULL;
+       ses_node_t*    node  = NULL;
 
        ScfEcomponent* c;
        ScfEpin*       p;
@@ -114,15 +114,11 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s
                        case SCF_EDA_NPN:
 
                                if (SCF_EDA_NPN_B == p->id) {
-                                       edge_c = ses_edges_find_edge_by_pin(edges, c->pins[SCF_EDA_NPN_C]);
-                                       if (!edge_c) {
-                                               scf_loge("\n");
-                                               return -EINVAL;
-                                       }
-
                                        bflag = 1;
-                                       edge_c->hfe = c->pins[SCF_EDA_NPN_C]->hfe;
-                               }
+                                       edge2 = ses_edges_find_edge_by_pin(edges, c->pins[SCF_EDA_NPN_C]);
+
+                               } else if (SCF_EDA_NPN_C == p->id)
+                                       edge2 = ses_edges_find_edge_by_pin(edges, c->pins[SCF_EDA_NPN_B]);
 
                        case SCF_EDA_Inductor:
                                if (!node) {
@@ -253,9 +249,16 @@ int __ses_nodes_path2(ScfEfunction* f, ses_path_t* path, int vip_m, int vip_n, s
                        edge->node0 = prev;
                }
 
-               if (edge_c) {
-                       edge_c->edge_b = edge;
-                       edge_c = NULL;
+               if (edge2) {
+                       if (edge ->bflag) {
+                               edge2->edge_b = edge;
+                               edge2->hfe    = c->pins[SCF_EDA_NPN_C]->hfe;
+                       } else {
+                               assert(edge2->bflag);
+                               edge->edge_b = edge2;
+                               edge->hfe    = c->pins[SCF_EDA_NPN_C]->hfe;
+                       }
+                       edge2 = NULL;
                }
 
                prev = node;
@@ -454,17 +457,13 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m,
    v0 - v1 - ir = cv + idt/C + Li/dt - Li0/dt
 
    v0 - v1 - i * (r + dt/C + L/dt) = cv - Li0/dt
-*/
-               if (edge->bflag)
-                       b[n + edge->index] = cv + SCF_EDA_V_NPN_ON;
-               else {
-                       b[n + edge->index] = cv - uh * 1000.0 * la / ns;
-
-                       if (uf > 0.0)
-                               A[(n + edge->index) * N + n + edge->index] = -r - uh * 1000.0 / ns - ns / 1000.0 / uf;
-                       else
-                               A[(n + edge->index) * N + n + edge->index] = -r - uh * 1000.0 / ns;
-               }
+ */
+               b[n + edge->index] = cv - uh * 1000.0 * la / ns;
+
+               if (uf > 0.0)
+                       A[(n + edge->index) * N + n + edge->index] = -r - uh * 1000.0 / ns - ns / 1000.0 / uf;
+               else
+                       A[(n + edge->index) * N + n + edge->index] = -r - uh * 1000.0 / ns;
 
                if (edge->node0 && edge->node0->lid != Bn->lid)
                        A[(n + edge->index) * N + edge->node0->index] = -1;
@@ -477,15 +476,28 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m,
                        b[n + edge->index] -= Bp->v;
        }
 
-       int n_amplifiers;
+       scf_logi("-----check transistor ON / OFF\n");
+
+       gsl_matrix_view _A = gsl_matrix_view_array(U, N, N);
+       gsl_vector_view _b = gsl_vector_view_array(b, N);
+       gsl_vector_view _X = gsl_vector_view_array(X, N);
+
+       gsl_vector_view _W = gsl_vector_view_array(W, N);
+       gsl_vector_view _S = gsl_vector_view_array(S, N);
+       gsl_matrix_view _V = gsl_matrix_view_array(V, N, N);
+
+       int __changed = 0;
+       int __need    = 0;
 
        do {
-               n_amplifiers = 0;
+               __changed = 0;
+               __need    = 0;
+
                memcpy(U, A, sizeof(double) * N * N);
-#if 0
+#if 1
                for (i = 0; i < N; i++) {
                        for (j = 0; j < N; j++)
-                               printf("%8lg ", A[i * N + j]);
+                               printf("%lg ", A[i * N + j]);
                        printf("\n");
                }
                printf("\n");
@@ -494,46 +506,76 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m,
                        printf("%lg\n", b[j]);
 #endif
 
-               gsl_matrix_view _A = gsl_matrix_view_array(U, N, N);
-               gsl_vector_view _b = gsl_vector_view_array(b, N);
-               gsl_vector_view _X = gsl_vector_view_array(X, N);
-
-               gsl_vector_view _W = gsl_vector_view_array(W, N);
-               gsl_vector_view _S = gsl_vector_view_array(S, N);
-               gsl_matrix_view _V = gsl_matrix_view_array(V, N, N);
-
                gsl_linalg_SV_decomp(&_A.matrix, &_V.matrix, &_S.vector, &_W.vector);
                gsl_linalg_SV_solve (&_A.matrix, &_V.matrix, &_S.vector, &_b.vector, &_X.vector);
 
-//             scf_logi("X:\n");
-//             gsl_vector_fprintf(stdout, &_X.vector, "%lg");
+               scf_logi("X:\n");
+               for (i = 0; i < N; i++)
+                       scf_logi("%lg\n", X[i]);
 
                for (j = 0; j < edges->size; j++) {
                        edge      = edges->data[j];
 
-                       if (edge->edge_b) {
-                               double Ic = X[n + edge->index];
-                               double Ib = X[n + edge->edge_b->index];
+                       p0 = edge->path->pins->data[edge->vip_m];
+                       p1 = edge->path->pins->data[edge->vip_n];
+                       c  = f->components[p0->cid];
 
-                               double dI = Ib * edge->hfe - Ic;
+                       if (edge->bflag) {
+                               double Vb;
+                               double Ve;
 
-                               if (dI < -1e-10) {
-                                       scf_logi("Ic: %lg, Ib: %lg, dI: %lg\n", Ic, Ib, dI);
+                               if (edge->node1 && edge->node1->lid != Bp->lid)
+                                       Vb = X[edge->node1->index];
+                               else
+                                       Vb = Bp->v;
 
-                                       int k;
-                                       for (k = 0; k < N; k++)
-                                               A[(n + edge->index) * N + k] = 0;
+                               if (edge->node0 && edge->node0->lid != Bn->lid)
+                                       Ve = X[edge->node0->index];
+                               else
+                                       Ve = Bn->v;
 
-                                       A[(n + edge->index) * N + n + edge->index]         = -1;
-                                       A[(n + edge->index) * N + n + edge->edge_b->index] = edge->hfe;
-                                       b[ n + edge->index] = 0;
+                               double dV = Vb - Ve;
 
-                                       n_amplifiers++;
+                               if (dV > 0.07) {
+                                       if (dV < SCF_EDA_V_NPN_ON * 0.99) {
+
+                                               scf_logi("edge: [%d] c%ldp%ld-c%ldp%ld, Vb: %lg, Ve: %lg, dV: %lg\n",
+                                                               edge->index, p0->cid, p0->id, p1->cid, p1->id, Vb, Ve, dV);
+
+                                               double Ib = X[n + edge->index];
+
+                                               A[(n + edge->index) * N + n + edge->index] = -SCF_EDA_V_NPN_ON / Ib;
+                                               __need++;
+                                       }
+                               } else {
+                                       c->status = SCF_EDA_Status_OFF;
+                                       c->lock   = 1;
+                                       __changed++;
+
+                                       scf_loge("\033[34mc%ld, status: %d, dV: %lg, edge->index: %d\033[0m\n", c->id, c->status, dV, edge->index);
                                }
                        }
                }
-       } while (n_amplifiers > 0);
+       } while (__need > 0);
+
+       scf_logi("-----check transistor on amplified / saturate\n");
+
+       memcpy(U, A, sizeof(double) * N * N);
+#if 1
+       for (i = 0; i < N; i++) {
+               for (j = 0; j < N; j++)
+                       printf("%lg ", A[i * N + j]);
+               printf("\n");
+       }
+       printf("\n");
+
+       for (j = 0; j < N; j++)
+               printf("%lg\n", b[j]);
+#endif
+       gsl_linalg_SV_decomp(&_A.matrix, &_V.matrix, &_S.vector, &_W.vector);
+       gsl_linalg_SV_solve (&_A.matrix, &_V.matrix, &_S.vector, &_b.vector, &_X.vector);
 
+       scf_logi("X:\n");
        for (i = 0; i < N; i++)
                scf_logi("%lg\n", X[i]);
 
@@ -544,7 +586,67 @@ static int __ses_nodes_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m,
                el->v = X[i];
        }
 
-       int __changed = 0;
+       if (__changed > 0) {
+               *changed += __changed;
+               return 0;
+       }
+
+       for (j = 0; j < edges->size; j++) {
+               edge      = edges->data[j];
+
+               if (edge->edge_b) {
+                       double Ic = X[n + edge->index];
+                       double Ib = X[n + edge->edge_b->index];
+
+                       double dI = Ib * edge->hfe - Ic;
+
+                       if (Ib > 0 && dI < -1e-10) {
+                               p0 = edge->path->pins->data[edge->vip_m];
+                               p1 = edge->path->pins->data[edge->vip_n];
+
+                               scf_logi("edge: [%d] c%ldp%ld-c%ldp%ld [b%d], Ic: %lg, Ib: %lg, dI: %lg\n",
+                                               edge->index, p0->cid, p0->id, p1->cid, p1->id, edge->edge_b->index, Ic, Ib, dI);
+
+                               int k;
+                               for (k = 0; k < N; k++)
+                                       A[(n + edge->index) * N + k] = 0;
+
+                               A[(n + edge->index) * N + n + edge->index]         = -1;
+                               A[(n + edge->index) * N + n + edge->edge_b->index] = edge->hfe;
+                               b[ n + edge->index] = 0;
+                       }
+               }
+       }
+
+       scf_logi("-----final result\n");
+
+       memcpy(U, A, sizeof(double) * N * N);
+#if 1
+       for (i = 0; i < N; i++) {
+               for (j = 0; j < N; j++)
+                       printf("%lg ", A[i * N + j]);
+               printf("\n");
+       }
+       printf("\n");
+
+       for (j = 0; j < N; j++)
+               printf("%lg\n", b[j]);
+#endif
+       gsl_linalg_SV_decomp(&_A.matrix, &_V.matrix, &_S.vector, &_W.vector);
+       gsl_linalg_SV_solve (&_A.matrix, &_V.matrix, &_S.vector, &_b.vector, &_X.vector);
+
+       scf_logi("result X:\n");
+       for (i = 0; i < N; i++)
+               scf_logi("%lg\n", X[i]);
+
+       for (i = 0; i < n; i++) {
+               node  = nodes->data[i];
+
+               el    = f->elines[node->lid];
+               el->v = X[i];
+       }
+
+       __changed = 0;
 
        for (j = 0; j < edges->size; j++) {
                edge      = edges->data[j];
index d17ce5d514dcda739581b2a29bd77bd00ed6e3ea..c3a5039170f0fae1aa31145212945f0f27f940ef 100644 (file)
@@ -478,15 +478,8 @@ int ses_path_add(ses_path_t* parent, ses_path_t* child, ScfEfunction* f)
                                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;
+                       if (path->parent_p0 == child->parent_p0 && path->parent_p1 == old_parent_p1)
                                continue;
-                       }
 
                        cp0 = path->pins->data[0];
                        cp1 = path->pins->data[path->pins->size - 1];
index 848de5e23672328d2bfd609e56612b2d9d8da5b6..c9456392a139b73f694a3bf86e8d4e2ca30325e1 100644 (file)
@@ -388,9 +388,17 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* 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);
+                               if (pb->y > c->y)
+                                       ses_text_a(cr, c->x, c->y + 20, pb->a);
+                               else
+                                       ses_text_a(cr, c->x, c->y - 20, pb->a);
+
+                               ses_text_a(cr, c->x,  c->y, pc->a);
+
+                               if (pe->y > c->y)
+                                       ses_text_a(cr, c->x, c->y + 20, pe->a);
+                               else
+                                       ses_text_a(cr, c->x, c->y - 20, pe->a);
                                cairo_stroke(cr);
                                break;
 
@@ -449,9 +457,18 @@ void __ses_function_draw(ScfEfunction* f, cairo_t* 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);
+
+                               if (pb->y > c->y)
+                                       ses_text_a(cr, c->x, c->y + 20, pb->a);
+                               else
+                                       ses_text_a(cr, c->x, c->y - 20, pb->a);
+
+                               ses_text_a(cr, c->x,  c->y, pc->a);
+
+                               if (pe->y > c->y)
+                                       ses_text_a(cr, c->x, c->y + 20, pe->a);
+                               else
+                                       ses_text_a(cr, c->x, c->y - 20, pe->a);
                                cairo_stroke(cr);
                                break;
                        default:
@@ -646,12 +663,12 @@ static int _simplify_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx
 
        char file[128];
        snprintf(file, sizeof(file) - 1, "./simplify_%ld.png", i);
-#if 1
-       if (count < 70000)
+#if 0
+       if (count < 64000)
                return 0;
 #endif
 
-       if (count % 10 == 0) {
+       if (1 || count % 10 == 0) {
 #if 1
                static FILE* fp = NULL;
                if (!fp)
diff --git a/ses_step_simplify2.c b/ses_step_simplify2.c
deleted file mode 100644 (file)
index afdc666..0000000
+++ /dev/null
@@ -1,551 +0,0 @@
-#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,
-};
index ffffc88879f682bdeac29167457ae9c7475e2b70..c2861b7f3b362e08e4713285c8fabe2d91d541df 100644 (file)
@@ -108,6 +108,8 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v
                if (SCF_EDA_PIN_NEG & el->flags) {
                        scf_logd("neg l%ld\n\n", el->id);
 
+                       if (SCF_EDA_Status_OFF == rc->status)
+                               return 0;
                        return __ses_dfs_add_ppath(__paths, ppath);
                }
 
@@ -117,6 +119,13 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v
                        return __ses_dfs_add_ppath(__paths, ppath);
                }
 
+               ses_path_t* off = NULL;
+
+               if (SCF_EDA_Status_OFF == rc->status) {
+                       off    = *ppath;
+                       *ppath = NULL;
+               }
+
                ret = 0;
 
                for (j = 0; j + 1 < el->n_pins; j += 2) {
@@ -182,6 +191,9 @@ static int __ses_dfs_path(ScfEfunction* f, ScfEcomponent* rc, ScfEpin* rp, scf_v
                        }
                }
 
+               if (off)
+                       *ppath = off;
+
                if (*ppath) {
                        scf_vector_del((*ppath)->pins, np);
 
@@ -1093,16 +1105,16 @@ static int topo_epin_cmp(const void* v0, const void* v1, void* arg)
        ScfEcomponent*  c0 = f->components[p0[0]];
        ScfEcomponent*  c1 = f->components[p1[0]];
 
-       if (SCF_EDA_NPN == c0->type && SCF_EDA_NPN_C == p0[1])
+       if (SCF_EDA_Diode == c0->type || (SCF_EDA_NPN == c0->type && SCF_EDA_NPN_B == p0[1]))
                return -1;
 
-       if (SCF_EDA_NPN == c1->type && SCF_EDA_NPN_C == p1[1])
+       if (SCF_EDA_Diode == c1->type || (SCF_EDA_NPN == c1->type && SCF_EDA_NPN_B == p1[1]))
                return 1;
 
-       if (SCF_EDA_Diode == c0->type || (SCF_EDA_NPN == c0->type && SCF_EDA_NPN_B == p0[1]))
+       if (SCF_EDA_NPN == c0->type && SCF_EDA_NPN_C == p0[1])
                return -1;
 
-       if (SCF_EDA_Diode == c1->type || (SCF_EDA_NPN == c1->type && SCF_EDA_NPN_B == p1[1]))
+       if (SCF_EDA_NPN == c1->type && SCF_EDA_NPN_C == p1[1])
                return 1;
 
        if (SCF_EDA_Capacitor == c0->type)
@@ -1443,35 +1455,64 @@ static int _topo_bridge_connections(ScfEfunction* f, scf_vector_t* paths)
        return 0;
 }
 
-static int _topo_path_parallel(ScfEfunction* f, scf_vector_t* paths)
+static int _topo_paths_mov_top(scf_vector_t* paths, ses_path_t* parent, ses_path_t* child)
 {
-       ses_path_t*    child;
-       ses_path_t*    parent;
-       ScfEpin*       p0;
-       ScfEpin*       p1;
-       ScfEpin*       p2;
-       ScfEpin*       p3;
+       ses_path_t*    path;
+       ScfEpin*       p0 = parent->pins->data[0];
        ScfEpin*       p;
 
-       int i;
-       int j;
+       int k;
 
-       for (i    = paths->size - 1; i >= 0; i--) {
-               child = paths->data[i];
+       for (k   = paths->size - 1; k >= 0; k--) {
+               path = paths->data[k];
+               p    = path->pins->data[0];
 
-               assert(child->pins->size >= 2);
+               if (p->lid != p0->lid)
+                       continue;
 
-               p0 = child->pins->data[0];
-               p1 = child->pins->data[child->pins->size - 1];
+               path->parent_p0 = 0;
+               path->parent    = parent;
+               path->conn0     = parent;
+               path->conn1     = child;
 
-               for (j     = paths->size - 1; j >= 0; j--) {
-                       parent = paths->data[j];
+               int ret = _topo_add_connection(path, path->conn0);
+               if (ret < 0)
+                       return ret;
 
-                       if (parent == child)
-                               continue;
+               ret = _topo_add_connection(path, path->conn1);
+               if (ret < 0)
+                       return ret;
 
-                       p2 = parent->pins->data[0];
-                       p3 = parent->pins->data[parent->pins->size - 1];
+               assert(0 == scf_vector_del(paths, path));
+       }
+
+       return 0;
+}
+
+static int _topo_path_parallel(ScfEfunction* f, scf_vector_t* paths)
+{
+       ses_path_t*  parent;
+       ses_path_t*  child;
+       ScfEpin*     p0;
+       ScfEpin*     p1;
+       ScfEpin*     p2;
+       ScfEpin*     p3;
+
+       int i;
+       int j;
+       int k;
+
+       for (i = 0; i < paths->size - 1; i++) {
+               parent    = paths->data[i];
+
+               p0 = parent->pins->data[0];
+               p1 = parent->pins->data[parent->pins->size - 1];
+
+               for (j    = paths->size - 1; j > i; j--) {
+                       child = paths->data[j];
+
+                       p2 = child->pins->data[0];
+                       p3 = child->pins->data[child->pins->size - 1];
 
                        if (p0->lid == p2->lid && p1->lid == p3->lid) {
 
@@ -1480,6 +1521,18 @@ static int _topo_path_parallel(ScfEfunction* f, scf_vector_t* paths)
                                        return ret;
 
                                assert(0 == scf_vector_del(paths, child));
+
+                               if (child->childs) {
+                                       ret = _topo_paths_mov_top(child->childs, parent, child);
+                                       if (ret < 0)
+                                               return ret;
+                               }
+
+                               if (child->bridges) {
+                                       ret = _topo_paths_mov_top(child->bridges, parent, child);
+                                       if (ret < 0)
+                                               return ret;
+                               }
                        }
                }
        }
@@ -1539,6 +1592,9 @@ static int _topo_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t*
        if (ret < 0)
                return ret;
 
+//     _topo_print(ctx->paths);
+//     scf_logi("----\n");
+
        ret = __ses_topo_layers(f, ctx->paths);
        if (ret < 0)
                return ret;
diff --git a/ses_step_va_capacitor.c b/ses_step_va_capacitor.c
deleted file mode 100644 (file)
index e15a7ba..0000000
+++ /dev/null
@@ -1,476 +0,0 @@
-#include"ses_core.h"
-
-void __ses_status_check_line(ScfEfunction* f, ScfEline* el, int* changed)
-{
-       ScfEcomponent* c;
-       ScfEpin*       p0;
-       ScfEpin*       p1;
-
-       int i;
-
-       for (i = 0; i < el->n_pins; i += 2) {
-
-               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);
-
-                       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;
-               }
-       }
-}
-
-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) {
-               int ret = __ses_path_va2(f, fpath, flow->vip_m, flow->vip_i, *rp, changed, ns, count);
-               if (ret < 0)
-                       return ret;
-       }
-
-       if (rn) {
-               int ret = __ses_path_va2(f, fpath, flow->vip_i + 1, flow->vip_n, *rn, changed, ns, count);
-               if (ret < 0)
-                       return ret;
-       }
-#endif
-       return 0;
-}
-
-void __ses_flow_solve_cross(ses_flow_t* flow0, ses_flow_t* flow1, ses_path_t* bridge)
-{
-       ses_path_t* path0;
-       ses_path_t* path1;
-       ses_path_t* path;
-
-       int i;
-       int j;
-
-       for (i = 0; i < flow0->paths->size; i++) {
-               path0     = flow0->paths->data[i];
-
-               for (j = 0; j < flow1->paths->size; j++) {
-                       path1     = flow1->paths->data[j];
-
-                       if (path0 == path1) {
-                               flow1->paths->size = j + 1;
-                               flow0->paths->size = i + 1;
-                               goto cross;
-                       }
-               }
-       }
-
-       return;
-
-cross:
-       scf_logi("-----------\n");
-
-       if (i > 0) {
-               if (j > 0) {
-                       scf_logi("-----------\n");
-                       return;
-               }
-
-               path = flow0->paths->data[i - 1];
-
-               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;
-               }
-
-       } else if (j > 0) {
-               path = flow1->paths->data[j - 1];
-
-               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;
-               }
-
-       } else {
-               path = flow0->paths->data[0];
-
-               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)
-{
-       ses_flow_t*    flow0;
-       ses_flow_t*    flow1;
-       ses_path_t*    fpath;
-
-       ScfEcomponent* B;
-       ScfEline*      el;
-       ScfEpin*       p0;
-       ScfEpin*       p1;
-       ScfEpin*       fp0;
-       ScfEpin*       fp1;
-       ScfEpin*       fp2;
-       ScfEpin*       fp3;
-       ScfEpin*       Bp;
-       ScfEpin*       Bn;
-
-       if (bridge->vflag)
-               return 0;
-
-       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;
-
-       scf_loge("c%ldp%ld-c%ldp%ld-------------------------\n", p0->cid, p0->id, p1->cid, p1->id);
-
-       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)
-               goto error;
-
-       if (flow0->paths->size > 0) {
-               fpath = flow0->paths->data[0];
-
-               if (!fpath->vflag) {
-                       ret = __ses_path_va_capacitor(f, paths, fpath, changed, ns, count);
-                       if (ret < 0)
-                               goto error;
-               }
-       }
-
-       if (flow1->paths->size > 0) {
-               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;
-
-       __ses_path_jr(f, bridge);
-
-       el    = f->elines[p0->lid];
-       p0->v = el->v;
-
-       el    = f->elines[p1->lid];
-       p1->v = 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);
-
-       scf_logw("c%ldp%ld-c%ldp%ld, cv: %lg, p0->v: %lg, p1->v: %lg\n", p0->cid, p0->id, p1->cid, p1->id, cv, p0->v, p1->v);
-
-       if (p0->v - p1->v > cv) {
-
-               if (p0->lid == Bp->lid) {
-
-                       fpath = flow1->paths->data[flow1->paths->size - 1];
-                       fp0   = fpath->pins->data[0];
-                       fp1   = fpath->pins->data[fpath->pins->size - 1];
-
-                       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");
-
-                       bridge->vflag = 1;
-
-               } else if (p1->lid == Bn->lid) {
-
-                       fpath = flow0->paths->data[flow0->paths->size - 1];
-                       fp0   = fpath->pins->data[0];
-                       fp1   = fpath->pins->data[fpath->pins->size - 1];
-
-                       double U0 = fp0->v - flow0->pos_cv;
-                       double U1 = Bn->v  + cv + Dv;
-                       double U2 = fp1->v + flow0->neg_cv;
-
-                       ses_va_PNN(U0, U1, U2, flow0->pos_r, bridge->pr, flow0->neg_r,
-                                       NULL, &ja, NULL, &p0->v);
-
-                       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;
-                       }
-                       bridge->vflag = 1;
-
-                       ret = __ses_flow_va(f, flow0, &flow0->pos_r, &flow0->neg_r, changed, ns, count);
-                       if (ret < 0)
-                               goto error;
-
-               } else {
-                       fpath = flow0->paths->data[0];
-                       fp0   = fpath->pins->data[flow0->vip_m];
-                       fp1   = fpath->pins->data[flow0->vip_n];
-
-                       double U0 = fp0->v - flow0->pos_cv;
-                       double U1 = fp1->v + flow0->neg_cv;
-
-                       fpath = flow1->paths->data[0];
-                       fp2   = fpath->pins->data[flow1->vip_m];
-                       fp3   = fpath->pins->data[flow1->vip_n];
-
-                       double U2 = fp2->v - flow1->pos_cv;
-                       double U3 = fp3->v + flow1->neg_cv;
-
-                       double i0 = 0;
-                       double i1 = 0;
-                       double i2 = 0;
-                       double i3 = 0;
-
-                       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);
-
-                       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_branch(f, bridge, 0, bridge->pins->size - 1, bridge->pr, changed, ns, count);
-                       if (ret < 0) {
-                               scf_loge("\n");
-                               goto error;
-                       }
-                       bridge->vflag = 1;
-
-                       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;
-               }
-       } else {
-               assert(p0->lid != Bp->lid);
-
-               if (p1->lid == Bn->lid) {
-
-                       R     = bridge->pr + flow0->neg_r;
-                       ja    = (cv - p0->v) / R;
-                       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;
-                       }
-                       bridge->vflag = 1;
-
-               } 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;
-
-                       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->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);
-
-                       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;
-                       }
-                       bridge->vflag = 1;
-
-                       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;
-               }
-       }
-
-       ret = 0;
-error:
-       ses_flow_free(flow0);
-       ses_flow_free(flow1);
-       return ret;
-}
-
-static int ses_path_va_capacitor(ScfEfunction* f, scf_vector_t* paths, ses_path_t* bridge, int* changed, int64_t ns, int64_t count)
-{
-       if (!bridge || bridge->pins->size < 2)
-               return -EINVAL;
-
-       return __ses_path_va_capacitor(f, paths, bridge, changed, ns, count);
-}
-
-static int _va_capacitor_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx)
-{
-       ses_path_t*    path;
-       ScfEcomponent* B  = f->components[0];
-       ScfEpin*       Bp = B->pins[SCF_EDA_Battery_POS];
-       ScfEpin*       Bn = B->pins[SCF_EDA_Battery_NEG];
-       ScfEpin*       p0;
-       ScfEpin*       p1;
-
-       int i;
-
-       for (i = 0; i < ctx->paths->size; i++) {
-               path      = ctx->paths->data[i];
-
-               p0 = path->pins->data[0];
-               p1 = path->pins->data[path->pins->size - 1];
-
-               if (p0->lid == Bp->lid && p1->lid == Bn->lid)
-                       continue;
-
-               scf_logi("i: %d, path->index: %d\n", i, path->index);
-
-               int changed = 0;
-
-               int ret = ses_path_va_capacitor(f, ctx->paths, path, &changed, ns, count);
-               if (ret < 0)
-                       return ret;
-
-               if (changed > 0)
-                       break;
-
-               printf("\n");
-       }
-
-       return 0;
-}
-
-ses_step_t  ses_step_va_capacitor =
-{
-       .name    = "va_capacitor",
-
-       .handler = _va_capacitor_handler,
-};