__ses_path_va_balance()
authoryu.dongliang <18588496441@163.com>
Tue, 10 Oct 2023 09:28:22 +0000 (17:28 +0800)
committeryu.dongliang <18588496441@163.com>
Tue, 10 Oct 2023 09:28:22 +0000 (17:28 +0800)
Makefile
ses_step_va_balance.c
ses_steps.c
ses_utils.c [new file with mode: 0644]

index 730e426ded9cc3e74ca602c4ad1705d8c3c7a155..7314e59fce11455e8bf0967bf0d7d91fa77351f6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ CFILES += main.c
 CFILES += scf_eda.pb-c.c
 CFILES += scf_eda_pb.c
 CFILES += ses_layout.c
-CFILES += ses_loop.c
+CFILES += ses_utils.c
 
 CFILES += ses_steps.c
 CFILES += ses_step_battery.c
index 3829bfba21a3dac2e2938911ced29880d8c44ea6..5365b9ac8bc61362cf355bffee75acaaae455fdc 100644 (file)
@@ -67,6 +67,67 @@ static void inline __ses_bridge_i(double* i0, double* i1, double* i2, double* i3
        *v4 = *i4 * R4 + vd4;
 }
 
+static size_t __ses_line_update(ScfEfunction* f, ScfEline* el)
+{
+       ScfEcomponent* c;
+       ScfEpin*       p;
+       ScfEpin*       p2;
+
+       size_t n = 0;
+       size_t i;
+
+       for (i = 0; i + 1 < el->n_pins; i += 2) {
+
+               c    = f->components[el->pins[i]];
+               p    = c->pins      [el->pins[i + 1]];
+               p->v = el->v;
+
+               if (SCF_EDA_Diode == c->type) {
+
+                       if (SCF_EDA_Diode_POS == p->id) {
+
+                               p2 = c->pins[SCF_EDA_Diode_NEG];
+
+                               if (p->v - p2->v < SCF_EDA_V_Diode_ON) {
+                                       c->status    = SCF_EDA_Status_OFF;
+                                       n++;
+                               }
+
+                       } else {
+                               p2 = c->pins[SCF_EDA_Diode_POS];
+
+                               if (p2->v - p->v < SCF_EDA_V_Diode_ON) {
+                                       c->status    = SCF_EDA_Status_OFF;
+                                       n++;
+                               }
+                       }
+
+               } else if (SCF_EDA_Transistor == c->type) {
+
+                       if (SCF_EDA_Transistor_B == p->id) {
+
+                               p2 = c->pins[SCF_EDA_Transistor_E];
+
+                               if (p->v - p2->v < SCF_EDA_V_Diode_ON) {
+                                       c->status    = SCF_EDA_Status_OFF;
+                                       n++;
+                               }
+
+                       } else if (SCF_EDA_Transistor_E == p->id) {
+
+                               p2 = c->pins[SCF_EDA_Transistor_B];
+
+                               if (p2->v - p->v < SCF_EDA_V_Diode_ON) {
+                                       c->status    = SCF_EDA_Status_OFF;
+                                       n++;
+                               }
+                       }
+               }
+       }
+
+       return n;
+}
+
 static int __ses_path_va_balance(ScfEfunction* f, ses_path_t* bridge, ses_flow_t* flow0, ses_flow_t* flow1)
 {
        if (!bridge || !flow0 || !flow1)
@@ -124,9 +185,6 @@ static int __ses_path_va_balance(ScfEfunction* f, ses_path_t* bridge, ses_flow_t
                                0, 0, 0, 0,
                                bridge->n_diodes * SCF_EDA_V_Diode_ON);
 
-//             ses_flow_v_pos(flow0, a, ja);
-//             ses_flow_v_neg(flow1, a, ja);
-
                scf_loge("r0: %lg, r1: %lg, r2: %lg, r3: %lg, r4: %lg\n",
                                flow1->pr, flow0->pr,
                                flow1->nr, flow0->nr, bridge->r);
@@ -134,6 +192,17 @@ static int __ses_path_va_balance(ScfEfunction* f, ses_path_t* bridge, ses_flow_t
                scf_loge("v: %lg, a0: %lg, a1: %lg, a2: %lg, a3: %lg, a4: %lg\n", v, a0, a1, a2, a3, a4);
                scf_loge("v0: %lg, v1: %lg, v4: %lg, v1 - v0: %lg\n", v0, v1, v4, v1 - v0);
 
+               el    = f->elines[p0->lid];
+               el->v = v0;
+
+               el    = f->elines[p1->lid];
+               el->v = v1;
+
+               size_t n0 = __ses_line_update(f, f->elines[p0->lid]);
+               size_t n1 = __ses_line_update(f, f->elines[p1->lid]);
+
+               return n0 + n1 > 0;
+
        } else {
 
        }
@@ -169,6 +238,7 @@ static int _va_balance_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_c
                return -ENOMEM;
        }
 
+       int n = 0;
        int i;
 
        for (i = 0; i < ctx->paths->size; i++) {
@@ -217,11 +287,16 @@ static int _va_balance_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_c
                if (ret < 0)
                        return ret;
 
+               n += ret;
+
                printf("\n");
        }
 
        ses_flow_free(flow0);
        ses_flow_free(flow1);
+
+       if (n > 0)
+               return -EAGAIN;
        return 0;
 }
 
index d36aa1a7ff02ded644d373690c371fd60fe4f96a..4e75ddbf5f2c77b24472de5787d5a59748394abb 100644 (file)
@@ -45,448 +45,6 @@ static ses_step_t*  ses_steps[] =
        &ses_step_output,
 };
 
-ses_flow_t* ses_flow_alloc()
-{
-       ses_flow_t* flow = calloc(1, sizeof(ses_flow_t));
-       if (!flow)
-               return NULL;
-
-       flow->paths = scf_vector_alloc();
-       if (!flow->paths) {
-               ses_flow_free(flow);
-               return NULL;
-       }
-
-       return flow;
-}
-
-void ses_flow_free(ses_flow_t* flow)
-{
-       if (flow) {
-               if (flow->paths)
-                       scf_vector_free(flow->paths);
-
-               free(flow);
-       }
-}
-
-void ses_flow_v_pos(ses_flow_t* flow, double a, double ja)
-{
-       if (!flow || !flow->paths || flow->paths->size <= 0 || !flow->vip)
-               return;
-
-       ses_path_t* path = flow->paths->data[flow->paths->size - 1];
-       ScfEpin*    vip  = flow->vip;
-       ScfEpin*    p0;
-       ScfEpin*    p;
-
-       double tr  = flow->pr;
-       double jtr = flow->jpr;
-
-       int i;
-       int j;
-
-       for (i   = 0; i < flow->paths->size; i++) {
-               path =        flow->paths->data[i];
-
-               double v;
-               double jv;
-
-               p0 = NULL;
-               for (j = path->pins->size - 1; j >= 0; j--) {
-                       p  = path->pins->data[j];
-
-                       if (!p0) {
-                               if ((j & 0x1) && p->lid == vip->lid)
-                                       p0 = p;
-                               else
-                                       continue;
-                       }
-
-                       double r  = tr  - (p0->pr  - p->pr);
-                       double jr = jtr - (p0->jpr - p->jpr);
-
-                       ses_ir_u(&v, &jv, a, ja, r, jr);
-
-                       p->v  -= v;
-                       p->jv -= jv;
-
-                       scf_logw("c%ldp%ld->v: %lg + j%lg, r: %lg + j%lg\n", p->cid, p->id, p->v, p->jv, r, jr);
-                       break;
-               }
-
-               assert(p0);
-
-               vip  = path->pins->data[0];
-               tr  -= p0->pr;
-               jtr -= p0->jpr;
-
-               ses_ir_u(&v, &jv, a, ja, tr, jtr);
-
-               vip->v  -= v;
-               vip->jv -= jv;
-
-               scf_logw("c%ldp%ld->v: %lg + j%lg, r: %lg + j%lg\n", vip->cid, vip->id, vip->v, vip->jv, tr, jtr);
-       }
-}
-
-void ses_flow_v_neg(ses_flow_t* flow, double a, double ja)
-{
-       if (!flow || !flow->paths || flow->paths->size <= 0 || !flow->vip)
-               return;
-
-       ses_path_t* path = flow->paths->data[flow->paths->size - 1];
-       ScfEpin*    vip  = flow->vip;
-       ScfEpin*    p0;
-       ScfEpin*    p;
-
-       double tr  = flow->nr;
-       double jtr = flow->jnr;
-
-       int i;
-       int j;
-
-       for (i   = 0; i < flow->paths->size; i++) {
-               path =        flow->paths->data[i];
-
-               double v;
-               double jv;
-
-               p0 = NULL;
-               for (j = 0; j < path->pins->size; j++) {
-                       p  =        path->pins->data[j];
-
-                       if (!p0) {
-                               if (p->lid == vip->lid)
-                                       p0 = p;
-                               else
-                                       continue;
-                       }
-
-                       double r  = tr  - (p->sr  - p0->pr);
-                       double jr = jtr - (p->jsr - p0->jpr);
-
-                       if (p->sr != p->pr)
-                               p0 = p;
-
-                       ses_ir_u(&v, &jv, a, ja, r, jr);
-
-                       p->v  += v;
-                       p->jv += jv;
-
-                       scf_loge("c%ldp%ld->v: %lg + j%lg, r: %lg + j%lg, %lg\n", p->cid, p->id, p->v, p->jv, r, jr, p->sr);
-               }
-
-               assert(p0);
-
-               vip = path->pins->data[j - 1];
-
-               if (vip != p0) {
-
-                       tr  -= vip->sr  - p0->pr;
-                       jtr -= vip->jsr - p0->jpr;
-
-                       ses_ir_u(&v, &jv, a, ja, tr, jtr);
-
-                       vip->v  += v;
-                       vip->jv += jv;
-
-                       scf_logw("c%ldp%ld->v: %lg + j%lg, r: %lg + j%lg\n", vip->cid, vip->id, vip->v, vip->jv, tr, jtr);
-               }
-       }
-}
-
-void ses_flow_jr(ses_flow_t* flow)
-{
-       if (!flow)
-               return;
-
-       flow->pr  = 0;
-       flow->jpr = 0;
-
-       flow->nr  = 0;
-       flow->jnr = 0;
-
-       if (!flow->paths || !flow->vip)
-               return;
-
-       ses_path_t* path;
-       ScfEpin*    p;
-       ScfEpin*    p0;
-       ScfEpin*    vip = flow->vip;
-
-       int i;
-       int j;
-
-       for (i   = 0; i < flow->paths->size; i++) {
-               path =        flow->paths->data[i];
-
-               for (j = 0; j < path->pins->size; j++) {
-                       p  =        path->pins->data[j];
-
-                       if (p->lid == vip->lid) {
-
-                               vip = path->pins->data[0];
-
-                               flow->pr  += p->pr;
-                               flow->jpr += p->jpr;
-
-                               scf_loge("flow->pr: %lg, c%ldp%ld->pr: %lg, vip c%ldp%ld->pr: %lg\n",
-                                               flow->pr, p->cid, p->id, p->pr, vip->cid, vip->id, vip->pr);
-                               break;
-                       }
-               }
-       }
-
-       vip = flow->vip;
-
-       for (i   = 0; i < flow->paths->size; i++) {
-               path =        flow->paths->data[i];
-
-               p0 = NULL;
-               for (j = 0; j < path->pins->size; j++) {
-                       p  =        path->pins->data[j];
-
-                       if (!p0) {
-                               if (p->lid == vip->lid)
-                                       p0 = p;
-                               continue;
-                       }
-
-                       if (p->sr != p->pr) {
-
-                               flow->nr  += p->sr  - p0->pr;
-                               flow->jnr += p->jsr - p0->jpr;
-
-                               scf_logw("flow->nr: %lg, c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n",
-                                               flow->nr, p->cid, p->id, p->sr, p0->cid, p0->id, p0->pr);
-
-                               p0 = p;
-                       }
-               }
-
-               assert(p0);
-
-               vip = path->pins->data[j - 1];
-
-               if (vip != p0) {
-                       flow->nr  += vip->sr  - p0->pr;
-                       flow->jnr += vip->jsr - p0->jpr;
-               }
-
-               scf_loge("flow->nr: %lg, vip c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n",
-                               flow->nr, vip->cid, vip->id, vip->sr, p0->cid, p0->id, p0->pr);
-       }
-}
-
-void ses_flow_print(ses_flow_t* flow)
-{
-       if (!flow || !flow->paths || !flow->vip)
-               return;
-
-       ses_path_t* path;
-       ScfEpin*    p;
-       ScfEpin*    vip = flow->vip;
-
-       int i;
-       int j;
-
-       for (i   = 0; i < flow->paths->size; i++) {
-               path =        flow->paths->data[i];
-
-               for (j = 0; j < path->pins->size; j++) {
-                       p  =        path->pins->data[j];
-
-                       printf("c%ldp%ld ", p->cid, p->id);
-
-                       if (p->lid == vip->lid) {
-                               vip = path->pins->data[0];
-                               break;
-                       }
-               }
-               printf(", ");
-       }
-
-       printf(";\n");
-
-       vip = flow->vip;
-
-       for (i   = 0; i < flow->paths->size; i++) {
-               path =        flow->paths->data[i];
-
-               int flag = 0;
-
-               for (j = 0; j < path->pins->size; j++) {
-                       p  =        path->pins->data[j];
-
-                       if (!flag) {
-                               if (p->lid == vip->lid)
-                                       flag = 1;
-                               continue;
-                       }
-
-                       printf("c%ldp%ld ", p->cid, p->id);
-               }
-
-               printf(", ");
-
-               vip = path->pins->data[j - 1];
-       }
-
-       printf(".\n");
-}
-
-ses_path_t* ses_path_alloc()
-{
-       ses_path_t* path = calloc(1, sizeof(ses_path_t));
-       if (!path)
-               return NULL;
-
-       path->pins = scf_vector_alloc();
-       if (!path->pins) {
-               free(path);
-               return NULL;
-       }
-
-       return path;
-}
-
-void ses_path_free(ses_path_t* path)
-{
-       if (path) {
-               if (path->pins)
-                       scf_vector_free(path->pins);
-
-               if (path->childs) {
-                       scf_vector_clear(path->childs, ( void (*)(void*) )ses_path_free);
-                       scf_vector_free (path->childs);
-               }
-
-               free(path);
-       }
-}
-
-void ses_path_print(ses_path_t* path)
-{
-       if (!path)
-               return;
-
-       ses_path_t* path2;
-       ScfEpin*    p;
-
-       int i;
-
-       if (!path->parent)
-               printf("\033[31mpath: %d, n_diodes: %d, \033[0m", path->index, path->n_diodes);
-
-       for (i = 0; i < path->pins->size; i++) {
-               p  =        path->pins->data[i];
-
-               printf("c%ldp%ldd%d ", p->cid, p->id, p->n_diodes);
-       }
-       printf("\n");
-
-       if (!path->childs)
-               return;
-
-       for (i = 0; i < path->childs->size; i++) {
-               path2     = path->childs->data[i];
-
-               printf("\033[32mchild: %d, n_diodes: %d, parent: %d, \033[0m", path2->index, path2->n_diodes, path->index);
-
-               ses_path_print(path2);
-       }
-}
-
-int ses_path_add(ses_path_t* parent, ses_path_t* child)
-{
-       if (!parent || !child)
-               return -EINVAL;
-
-       if (!parent->childs) {
-               parent->childs = scf_vector_alloc();
-               if (!parent->childs)
-                       return -ENOMEM;
-       }
-
-       ses_path_t* path;
-       ScfEpin*    p0;
-       ScfEpin*    p1;
-       ScfEpin*    cp0 = child->pins->data[0];
-       ScfEpin*    cp1 = child->pins->data[child->pins->size - 1];
-
-       int j;
-
-       for (j = 0; j < parent->childs->size; j++) {
-               path      = parent->childs->data[j];
-
-               p0        = path->pins->data[0];
-               p1        = path->pins->data[path->pins->size - 1];
-
-               if (p0->lid == cp0->lid && p1->lid == cp1->lid) {
-
-                       if (child->pins->size == child->n_diodes * 2
-                         && path->pins->size  >  path->n_diodes * 2) {
-
-                               parent->childs->data[j] = child;
-                               child->parent           = parent;
-                               child->parent_p0        = path->parent_p0;
-                               child->parent_p1        = path->parent_p1;
-                               child->type             = SES_PATH_BRANCH;
-
-                               return ses_path_add(child, path);
-                       } else
-                               return ses_path_add(path, child);
-               }
-       }
-
-       if (scf_vector_add(parent->childs, child) < 0)
-               return -ENOMEM;
-
-       for (j = 0; j < parent->pins->size; j++) {
-               p0 =        parent->pins->data[j];
-
-               if (p0->lid == cp0->lid)
-                       child->parent_p0 = j;
-
-               if (p0->lid == cp1->lid) {
-                       child->parent_p1 = j;
-                       break;
-               }
-       }
-       assert(child->parent_p0 >= 0 && child->parent_p1 >= 0);
-
-       child->parent = parent;
-       child->type   = SES_PATH_BRANCH;
-       return 0;
-}
-
-ses_ctx_t* ses_ctx_alloc()
-{
-       ses_ctx_t* ctx = calloc(1, sizeof(ses_ctx_t));
-       if (!ctx)
-               return NULL;
-
-       ctx->paths = scf_vector_alloc();
-       if (!ctx->paths) {
-               free(ctx);
-               return NULL;
-       }
-
-       return ctx;
-}
-
-void ses_ctx_free(ses_ctx_t* ctx)
-{
-       if (ctx) {
-               if (ctx->paths) {
-                       scf_vector_clear(ctx->paths, ( void (*)(void*) )scf_vector_free);
-                       scf_vector_free (ctx->paths);
-               }
-
-               free(ctx);
-       }
-}
 
 int ses_steps_analyse(ScfEfunction* f, int64_t ns, int64_t count)
 {
diff --git a/ses_utils.c b/ses_utils.c
new file mode 100644 (file)
index 0000000..bfa53a7
--- /dev/null
@@ -0,0 +1,445 @@
+#include"ses_core.h"
+
+ses_flow_t* ses_flow_alloc()
+{
+       ses_flow_t* flow = calloc(1, sizeof(ses_flow_t));
+       if (!flow)
+               return NULL;
+
+       flow->paths = scf_vector_alloc();
+       if (!flow->paths) {
+               ses_flow_free(flow);
+               return NULL;
+       }
+
+       return flow;
+}
+
+void ses_flow_free(ses_flow_t* flow)
+{
+       if (flow) {
+               if (flow->paths)
+                       scf_vector_free(flow->paths);
+
+               free(flow);
+       }
+}
+
+void ses_flow_v_pos(ses_flow_t* flow, double a, double ja)
+{
+       if (!flow || !flow->paths || flow->paths->size <= 0 || !flow->vip)
+               return;
+
+       ses_path_t* path = flow->paths->data[flow->paths->size - 1];
+       ScfEpin*    vip  = flow->vip;
+       ScfEpin*    p0;
+       ScfEpin*    p;
+
+       double tr  = flow->pr;
+       double jtr = flow->jpr;
+
+       int i;
+       int j;
+
+       for (i   = 0; i < flow->paths->size; i++) {
+               path =        flow->paths->data[i];
+
+               double v;
+               double jv;
+
+               p0 = NULL;
+               for (j = path->pins->size - 1; j >= 0; j--) {
+                       p  = path->pins->data[j];
+
+                       if (!p0) {
+                               if ((j & 0x1) && p->lid == vip->lid)
+                                       p0 = p;
+                               else
+                                       continue;
+                       }
+
+                       double r  = tr  - (p0->pr  - p->pr);
+                       double jr = jtr - (p0->jpr - p->jpr);
+
+                       ses_ir_u(&v, &jv, a, ja, r, jr);
+
+                       p->v  -= v;
+                       p->jv -= jv;
+
+                       scf_logw("c%ldp%ld->v: %lg + j%lg, r: %lg + j%lg\n", p->cid, p->id, p->v, p->jv, r, jr);
+                       break;
+               }
+
+               assert(p0);
+
+               vip  = path->pins->data[0];
+               tr  -= p0->pr;
+               jtr -= p0->jpr;
+
+               ses_ir_u(&v, &jv, a, ja, tr, jtr);
+
+               vip->v  -= v;
+               vip->jv -= jv;
+
+               scf_logw("c%ldp%ld->v: %lg + j%lg, r: %lg + j%lg\n", vip->cid, vip->id, vip->v, vip->jv, tr, jtr);
+       }
+}
+
+void ses_flow_v_neg(ses_flow_t* flow, double a, double ja)
+{
+       if (!flow || !flow->paths || flow->paths->size <= 0 || !flow->vip)
+               return;
+
+       ses_path_t* path = flow->paths->data[flow->paths->size - 1];
+       ScfEpin*    vip  = flow->vip;
+       ScfEpin*    p0;
+       ScfEpin*    p;
+
+       double tr  = flow->nr;
+       double jtr = flow->jnr;
+
+       int i;
+       int j;
+
+       for (i   = 0; i < flow->paths->size; i++) {
+               path =        flow->paths->data[i];
+
+               double v;
+               double jv;
+
+               p0 = NULL;
+               for (j = 0; j < path->pins->size; j++) {
+                       p  =        path->pins->data[j];
+
+                       if (!p0) {
+                               if (p->lid == vip->lid)
+                                       p0 = p;
+                               else
+                                       continue;
+                       }
+
+                       double r  = tr  - (p->sr  - p0->pr);
+                       double jr = jtr - (p->jsr - p0->jpr);
+
+                       if (p->sr != p->pr)
+                               p0 = p;
+
+                       ses_ir_u(&v, &jv, a, ja, r, jr);
+
+                       p->v  += v;
+                       p->jv += jv;
+
+                       scf_loge("c%ldp%ld->v: %lg + j%lg, r: %lg + j%lg, %lg\n", p->cid, p->id, p->v, p->jv, r, jr, p->sr);
+               }
+
+               assert(p0);
+
+               vip = path->pins->data[j - 1];
+
+               if (vip != p0) {
+
+                       tr  -= vip->sr  - p0->pr;
+                       jtr -= vip->jsr - p0->jpr;
+
+                       ses_ir_u(&v, &jv, a, ja, tr, jtr);
+
+                       vip->v  += v;
+                       vip->jv += jv;
+
+                       scf_logw("c%ldp%ld->v: %lg + j%lg, r: %lg + j%lg\n", vip->cid, vip->id, vip->v, vip->jv, tr, jtr);
+               }
+       }
+}
+
+void ses_flow_jr(ses_flow_t* flow)
+{
+       if (!flow)
+               return;
+
+       flow->pr  = 0;
+       flow->jpr = 0;
+
+       flow->nr  = 0;
+       flow->jnr = 0;
+
+       if (!flow->paths || !flow->vip)
+               return;
+
+       ses_path_t* path;
+       ScfEpin*    p;
+       ScfEpin*    p0;
+       ScfEpin*    vip = flow->vip;
+
+       int i;
+       int j;
+
+       for (i   = 0; i < flow->paths->size; i++) {
+               path =        flow->paths->data[i];
+
+               for (j = 0; j < path->pins->size; j++) {
+                       p  =        path->pins->data[j];
+
+                       if (p->lid == vip->lid) {
+
+                               vip = path->pins->data[0];
+
+                               flow->pr  += p->pr;
+                               flow->jpr += p->jpr;
+
+                               scf_loge("flow->pr: %lg, c%ldp%ld->pr: %lg, vip c%ldp%ld->pr: %lg\n",
+                                               flow->pr, p->cid, p->id, p->pr, vip->cid, vip->id, vip->pr);
+                               break;
+                       }
+               }
+       }
+
+       vip = flow->vip;
+
+       for (i   = 0; i < flow->paths->size; i++) {
+               path =        flow->paths->data[i];
+
+               p0 = NULL;
+               for (j = 0; j < path->pins->size; j++) {
+                       p  =        path->pins->data[j];
+
+                       if (!p0) {
+                               if (p->lid == vip->lid)
+                                       p0 = p;
+                               continue;
+                       }
+
+                       if (p->sr != p->pr) {
+
+                               flow->nr  += p->sr  - p0->pr;
+                               flow->jnr += p->jsr - p0->jpr;
+
+                               scf_logw("flow->nr: %lg, c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n",
+                                               flow->nr, p->cid, p->id, p->sr, p0->cid, p0->id, p0->pr);
+
+                               p0 = p;
+                       }
+               }
+
+               assert(p0);
+
+               vip = path->pins->data[j - 1];
+
+               if (vip != p0) {
+                       flow->nr  += vip->sr  - p0->pr;
+                       flow->jnr += vip->jsr - p0->jpr;
+               }
+
+               scf_loge("flow->nr: %lg, vip c%ldp%ld->sr: %lg, p0 c%ldp%ld->pr: %lg\n",
+                               flow->nr, vip->cid, vip->id, vip->sr, p0->cid, p0->id, p0->pr);
+       }
+}
+
+void ses_flow_print(ses_flow_t* flow)
+{
+       if (!flow || !flow->paths || !flow->vip)
+               return;
+
+       ses_path_t* path;
+       ScfEpin*    p;
+       ScfEpin*    vip = flow->vip;
+
+       int i;
+       int j;
+
+       for (i   = 0; i < flow->paths->size; i++) {
+               path =        flow->paths->data[i];
+
+               for (j = 0; j < path->pins->size; j++) {
+                       p  =        path->pins->data[j];
+
+                       printf("c%ldp%ld ", p->cid, p->id);
+
+                       if (p->lid == vip->lid) {
+                               vip = path->pins->data[0];
+                               break;
+                       }
+               }
+               printf(", ");
+       }
+
+       printf(";\n");
+
+       vip = flow->vip;
+
+       for (i   = 0; i < flow->paths->size; i++) {
+               path =        flow->paths->data[i];
+
+               int flag = 0;
+
+               for (j = 0; j < path->pins->size; j++) {
+                       p  =        path->pins->data[j];
+
+                       if (!flag) {
+                               if (p->lid == vip->lid)
+                                       flag = 1;
+                               continue;
+                       }
+
+                       printf("c%ldp%ld ", p->cid, p->id);
+               }
+
+               printf(", ");
+
+               vip = path->pins->data[j - 1];
+       }
+
+       printf(".\n");
+}
+
+ses_path_t* ses_path_alloc()
+{
+       ses_path_t* path = calloc(1, sizeof(ses_path_t));
+       if (!path)
+               return NULL;
+
+       path->pins = scf_vector_alloc();
+       if (!path->pins) {
+               free(path);
+               return NULL;
+       }
+
+       return path;
+}
+
+void ses_path_free(ses_path_t* path)
+{
+       if (path) {
+               if (path->pins)
+                       scf_vector_free(path->pins);
+
+               if (path->childs) {
+                       scf_vector_clear(path->childs, ( void (*)(void*) )ses_path_free);
+                       scf_vector_free (path->childs);
+               }
+
+               free(path);
+       }
+}
+
+void ses_path_print(ses_path_t* path)
+{
+       if (!path)
+               return;
+
+       ses_path_t* path2;
+       ScfEpin*    p;
+
+       int i;
+
+       if (!path->parent)
+               printf("\033[31mpath: %d, n_diodes: %d, \033[0m", path->index, path->n_diodes);
+
+       for (i = 0; i < path->pins->size; i++) {
+               p  =        path->pins->data[i];
+
+               printf("c%ldp%ldd%d ", p->cid, p->id, p->n_diodes);
+       }
+       printf("\n");
+
+       if (!path->childs)
+               return;
+
+       for (i = 0; i < path->childs->size; i++) {
+               path2     = path->childs->data[i];
+
+               printf("\033[32mchild: %d, n_diodes: %d, parent: %d, \033[0m", path2->index, path2->n_diodes, path->index);
+
+               ses_path_print(path2);
+       }
+}
+
+int ses_path_add(ses_path_t* parent, ses_path_t* child)
+{
+       if (!parent || !child)
+               return -EINVAL;
+
+       if (!parent->childs) {
+               parent->childs = scf_vector_alloc();
+               if (!parent->childs)
+                       return -ENOMEM;
+       }
+
+       ses_path_t* path;
+       ScfEpin*    p0;
+       ScfEpin*    p1;
+       ScfEpin*    cp0 = child->pins->data[0];
+       ScfEpin*    cp1 = child->pins->data[child->pins->size - 1];
+
+       int j;
+
+       for (j = 0; j < parent->childs->size; j++) {
+               path      = parent->childs->data[j];
+
+               p0        = path->pins->data[0];
+               p1        = path->pins->data[path->pins->size - 1];
+
+               if (p0->lid == cp0->lid && p1->lid == cp1->lid) {
+
+                       if (child->pins->size == child->n_diodes * 2
+                         && path->pins->size  >  path->n_diodes * 2) {
+
+                               parent->childs->data[j] = child;
+                               child->parent           = parent;
+                               child->parent_p0        = path->parent_p0;
+                               child->parent_p1        = path->parent_p1;
+                               child->type             = SES_PATH_BRANCH;
+
+                               return ses_path_add(child, path);
+                       } else
+                               return ses_path_add(path, child);
+               }
+       }
+
+       if (scf_vector_add(parent->childs, child) < 0)
+               return -ENOMEM;
+
+       for (j = 0; j < parent->pins->size; j++) {
+               p0 =        parent->pins->data[j];
+
+               if (p0->lid == cp0->lid)
+                       child->parent_p0 = j;
+
+               if (p0->lid == cp1->lid) {
+                       child->parent_p1 = j;
+                       break;
+               }
+       }
+       assert(child->parent_p0 >= 0 && child->parent_p1 >= 0);
+
+       child->parent = parent;
+       child->type   = SES_PATH_BRANCH;
+       return 0;
+}
+
+ses_ctx_t* ses_ctx_alloc()
+{
+       ses_ctx_t* ctx = calloc(1, sizeof(ses_ctx_t));
+       if (!ctx)
+               return NULL;
+
+       ctx->paths = scf_vector_alloc();
+       if (!ctx->paths) {
+               free(ctx);
+               return NULL;
+       }
+
+       return ctx;
+}
+
+void ses_ctx_free(ses_ctx_t* ctx)
+{
+       if (ctx) {
+               if (ctx->paths) {
+                       scf_vector_clear(ctx->paths, ( void (*)(void*) )scf_vector_free);
+                       scf_vector_free (ctx->paths);
+               }
+
+               free(ctx);
+       }
+}
+