add step 'mesh analysis' for va
authoryu.dongliang <18588496441@163.com>
Sun, 12 May 2024 11:57:17 +0000 (19:57 +0800)
committeryu.dongliang <18588496441@163.com>
Sun, 12 May 2024 11:57:23 +0000 (19:57 +0800)
Makefile
ses_core.h
ses_mesh_analysis.c
ses_step_va.c
ses_step_va_capacitor.c
ses_step_va_meshs.c [new file with mode: 0644]
ses_steps.c

index 12181bc49ee1acdb451acb56b711f053835da654..828f7642b769166d1b103e0e5170f96dcdf0e3b3 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -28,6 +28,7 @@ CFILES += ses_step_status.c
 CFILES += ses_step_va_line.c
 
 CFILES += ses_step_open.c
+CFILES += ses_step_va_meshs.c
 CFILES += ses_step_va_capacitor.c
 
 CFILES += ses_step_a_stat.c
index 3b926509314f6aa02e28f4899d7e49c6f2f33273..e38ebf31ec374c971a59dbb9dee30e42e10f9d84 100644 (file)
@@ -218,9 +218,10 @@ int ses_paths_find_flow(ses_flow_t* flow, scf_vector_t* paths, ScfEpin* vip,  se
 int ses_flow_find_pos  (ses_flow_t* flow, scf_vector_t* paths, ScfEfunction* f);
 int ses_flow_find_neg  (ses_flow_t* flow, scf_vector_t* paths, ScfEfunction* f);
 
-int  __ses_path_va_diode     (ScfEfunction* f, ses_path_t* path);
 int  __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path);
+int  __ses_path_va_diode     (ScfEfunction* f, ses_path_t* path);
 int  __ses_path_va_bridge    (ScfEfunction* f, ses_path_t* bridge, int* changed, scf_vector_t* paths, int64_t ns, int64_t count);
+int  __ses_path_va_branch    (ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ns, int64_t count);
 
 void __ses_path_split_i(ScfEfunction* f, ses_path_t* path, int i, int j, double la, double* a);
 int  __ses_status_check(ScfEfunction* f, ScfEcomponent* c, ScfEpin* pb, ScfEpin* pe, int vinit);
@@ -230,9 +231,9 @@ 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_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_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);
 
index ae44d9ed8622ccb95efc7dcbc4a04351f84d6b0a..0a9f62ea0daa4fce0b172f1bcdd596e8fa304b56 100644 (file)
@@ -28,7 +28,7 @@ int ses_mesh_add_edge(ses_mesh_t* mesh, ses_path_t* path, int m, int n, ses_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)
+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;
@@ -185,7 +185,7 @@ n + 1:   I[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)
+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;
@@ -211,7 +211,7 @@ int __ses_meshs_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int vi
        double* b = A + N * N;
        double* X = b + N;
        double cv;
-       double pr;
+       double r;
 
        __ses_path_jr(f, path);
 
@@ -223,19 +223,22 @@ int __ses_meshs_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int vi
                __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);
+               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 = pr;
+               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, pr: %lg, cv: %lg\n", p0->cid, p0->id, p1->cid, p1->id, pr, cv);
+               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] = -pr;
+               A[i * N + n + i] = -r;
 
                if (i < n - 1)
-                       A[i * N + n + i + 1] =  pr;
+                       A[i * N + n + i + 1] =  r;
        }
 
        mesh = meshs->data[meshs->size - 1];
@@ -246,9 +249,9 @@ int __ses_meshs_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int vi
                if (edge->vip_m > edge->vip_n) {
 
                        if (0 == edge->vip_n && edge->vip_m == edge->path->pins->size - 1)
-                               pr = edge->path->pr;
+                                = edge->path->pr;
                        else
-                               __ses_path_pr(f, edge->path, edge->vip_n, edge->vip_m, NULL, &pr);
+                               __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;
@@ -257,9 +260,9 @@ int __ses_meshs_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int vi
                        b[n + i] = cv;
 
                        if (0 == edge->vip_m && edge->vip_n == edge->path->pins->size - 1)
-                               pr = edge->path->pr;
+                                = edge->path->pr;
                        else
-                               __ses_path_pr(f, edge->path, edge->vip_m, edge->vip_n, NULL, &pr);
+                               __ses_path_sr(f, edge->path, edge->vip_m, edge->vip_n, &r);
                }
 
                if (i > 0)
@@ -269,18 +272,18 @@ int __ses_meshs_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int vi
 
                if (i < n) {
                        A[(n + i) * N     + i] = -1;
-                       A[(n + i) * N + n + i] = -pr;
+                       A[(n + i) * N + n + i] = -r;
                } else
                        b[n + i] += pm->v;
 
-               A[(n + i) * N + 2 * n] = -pr;
+               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 = pr;
+               edge->r = r;
 
-               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);
+               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);
@@ -311,7 +314,7 @@ int __ses_meshs_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int vi
                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);
+               ret = __ses_path_va_branch(f, edge->path, edge->vip_m, edge->vip_n, edge->r, changed, ns, count);
                if (ret < 0)
                        goto error;
        }
@@ -324,7 +327,7 @@ int __ses_meshs_path_solve2(ScfEfunction* f, ses_path_t* path, int vip_m, int vi
                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);
+               ret = __ses_path_va_branch(f, edge->path, edge->vip_n, edge->vip_m, edge->r, changed, ns, count);
                if (ret < 0)
                        goto error;
        }
index 8f5cbc2beed39a419532ddabd83612027993d05b..cb1e84dc9aeea8ec91a9c64c7e70084c34a6e929 100644 (file)
@@ -159,6 +159,128 @@ int __ses_path_capacitors(ScfEfunction* f, ses_path_t* path, int m, int n, doubl
        return k;
 }
 
+int __ses_path_va_branch(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;
+
+//     if (path->vflag)
+//             return 0;
+
+       ScfEcomponent* c;
+       ScfEline*      el;
+       ScfEpin*       p;
+       ScfEpin*       p2;
+       ScfEpin*       p0 = path->pins->data[m];
+       ScfEpin*       p1 = path->pins->data[n];
+
+       double cv = 0;
+       double a  = 0;
+       double v  = p0->v - p1->v;
+
+       __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, 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;
+       double dv0 = 0;
+       double dvc = 0;
+
+       int i0 = m;
+       int i;
+
+       for (i = m; i <= n; i++) {
+               p  = path->pins->data[i];
+
+               c  = f->components[p->cid];
+               el = f->elines[p->lid];
+
+               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->a  = a;
+               p->v -= dv0 + dvc;
+               el->v = p->v;
+
+               r += p->r + p->dr;
+
+               if (i & 0x1) {
+                       p2  = path->pins->data[i - 1];
+                       dv -= p->v;
+                       r  += c->r + c->dr;
+
+                       int sign = !p->id - p->id;
+
+                       c->a  = a * sign;
+                       p2->a = a;
+
+                       if (SCF_EDA_Capacitor == c->type) {
+                               cv  = c->v * sign;
+                               dv -= cv;
+
+                               c->v += a * sign * ns / 1e3 / c->uf;
+
+                               dvc += cv;
+
+                               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);
+                       }
+                       c->count = count;
+
+                       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) {
+
+                               if (SCF_EDA_Diode_NEG == p->id) {
+                                       p2 = path->pins->data[i - 1];
+
+                                       *changed += __ses_status_check(f, c, p2, p, 1);
+                               }
+
+                       } else if (SCF_EDA_NPN == c->type) {
+
+                               if (SCF_EDA_NPN_E == p->id) {
+                                       p2 = path->pins->data[i - 1];
+
+                                       if (SCF_EDA_NPN_B == p2->id) {
+                                               *changed += __ses_status_check(f, c, p2, p, 1);
+
+                                               c->pins[SCF_EDA_NPN_C]->aconst = 1;
+                                       }
+                               }
+                       }
+
+                       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, 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");
+
+       path->vflag = 1;
+       return 0;
+}
+
 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)
@@ -174,22 +296,14 @@ int __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, i
 
        ses_path_t*    child;
        ScfEcomponent* c;
-       ScfEcomponent* B  = f->components[0];
-       ScfEpin*       Bn = B->pins[SCF_EDA_Battery_NEG];
        ScfEline*      el;
        ScfEpin*       p;
-       ScfEpin*       p0;
-       ScfEpin*       p1;
        ScfEpin*       p2;
+       ScfEpin*       p0 = path->pins->data[m];
+       ScfEpin*       p1 = path->pins->data[n];
        ScfEpin*       cp0;
        ScfEpin*       cp1;
 
-       int i;
-       int j;
-
-       p0 = path->pins->data[m];
-       p1 = path->pins->data[n];
-
        double cv = 0;
        double a  = 0;
        double v  = p0->v - p1->v;
@@ -208,10 +322,11 @@ int __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, i
        double r   = 0;
        double dv  = 0;
        double dv0 = 0;
-       double dv1 = 0;
        double dvc = 0;
 
        int i0 = m;
+       int i;
+       int j;
 
        for (i = m; i <= n; i++) {
                p  = path->pins->data[i];
@@ -223,7 +338,6 @@ int __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, i
                __ses_path_split_v(f, path, i0, i, a);
 
                p->v -= dv0 + dvc;
-               dv1   = 0;
 
                double tmp = p->v;
 
@@ -262,9 +376,7 @@ int __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, i
                                dv -= cv;
                                ses_ur_i(&p->a, NULL, dv, 0, r, 0);
 
-//                             c->v += p->a * sign * ns / 1e3 / c->uf;
-                               c->a  = p->a * sign;
-
+                               c->a = p->a * sign;
                                dvc += cv;
 
                                scf_logi("c%ld->v: %lg, p->v: %lg, p2->v: %lg, dv: %lg, ja: %lg, ja0: %lg, ns: %ld, uf: %lg\n",
@@ -342,7 +454,6 @@ int __ses_path_va3(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, i
        }
        printf("\n");
 
-       path->vflag = 1;
        return 0;
 }
 
@@ -395,20 +506,17 @@ int __ses_path_va(ScfEfunction* f, ses_path_t* path, int* changed, int64_t ns, i
        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;
+       return 0;
 }
 
 static int _va_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx)
index 9740da1d0a77779a876bb19c3c10bde50c084ea2..3e004247eeb1998f6fbdb99e926cf53857256a2b 100644 (file)
@@ -467,40 +467,32 @@ error:
 
 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_path_t* child;
-
-       int ret;
-       int j;
-
        if (!bridge || bridge->pins->size < 2)
                return -EINVAL;
 
-       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++) {
-                       child     = bridge->bridges->data[j];
-
-                       ret = ses_path_va_capacitor(f, paths, child, changed, ns, count);
-                       if (ret < 0)
-                               return ret;
-               }
-       }
-
-       return 0;
+       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;
+       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;
diff --git a/ses_step_va_meshs.c b/ses_step_va_meshs.c
new file mode 100644 (file)
index 0000000..40afa37
--- /dev/null
@@ -0,0 +1,83 @@
+#include"ses_core.h"
+
+int __ses_path_va_meshs(ScfEfunction* f, ses_path_t* path, int* changed, scf_vector_t* paths, 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);
+       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 0;
+}
+
+static int ses_path_va_meshs(ScfEfunction* f, ses_path_t* path, int* changed, scf_vector_t* paths, int64_t ns, int64_t count)
+{
+       return __ses_path_va_meshs(f, path, changed, paths, ns, count);
+}
+
+static int _va_meshs_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 changed = 0;
+       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 ret = ses_path_va_meshs(f, path, &changed, ctx->paths, ns, count);
+               if (ret < 0)
+                       return ret;
+       }
+
+       ctx->changed += changed;
+       return 0;
+}
+
+ses_step_t  ses_step_va_meshs =
+{
+       .name    = "va_meshs",
+
+       .handler = _va_meshs_handler,
+};
index 6d9f5e01535526ee0c8d1fa43f245c851d752a6a..d9afffb4b1afe4d8c7a3bfbc19649033b73304f0 100644 (file)
@@ -20,6 +20,7 @@ extern ses_step_t   ses_step_va;
 extern ses_step_t   ses_step_status;
 
 extern ses_step_t   ses_step_open;
+extern ses_step_t   ses_step_va_meshs;
 extern ses_step_t   ses_step_va_capacitor;
 
 extern ses_step_t   ses_step_a_stat;
@@ -58,6 +59,7 @@ static ses_step_t*  ses_steps_2[] =
 {
        &ses_step_open,
 //     &ses_step_simplify2,
+       &ses_step_va_meshs,
        &ses_step_va_capacitor,
 
 //     &ses_step_a_stat,