1 /**********
2 Copyright 1990 Regents of the University of California.  All rights reserved.
3 Author: 1985 Thomas L. Quarles
4 **********/
5 /*
6  */
7 
8     /* CKTsetBreak(ckt,time)
9      *   add the given time to the breakpoint table for the given circuit
10      */
11 
12 #include "ngspice/ngspice.h"
13 #include "ngspice/cktdefs.h"
14 #include "ngspice/ifsim.h"
15 #include "ngspice/sperror.h"
16 
17 /* define to enable breakpoint trace code */
18 /* #define TRACE_BREAKPOINT */
19 
20 int
CKTsetBreak(CKTcircuit * ckt,double time)21 CKTsetBreak(CKTcircuit *ckt, double time)
22 {
23     double *tmp;
24     int i,j;
25 
26 #ifdef TRACE_BREAKPOINT
27     printf("[t:%e] \t want breakpoint for t = %e\n", ckt->CKTtime, time);
28 #endif
29 
30     if(ckt->CKTtime > time) {
31         SPfrontEnd->IFerrorf (ERR_PANIC, "breakpoint in the past - HELP!");
32         return(E_INTERN);
33     }
34     for(i=0;i<ckt->CKTbreakSize;i++) {
35         if(ckt->CKTbreaks[i]>time) { /* passed */
36             if((ckt->CKTbreaks[i]-time) <= ckt->CKTminBreak) {
37                 /* very close together - take earlier point */
38 #ifdef TRACE_BREAKPOINT
39                 printf("[t:%e] \t %e replaces %e\n", ckt->CKTtime, time,
40 		ckt->CKTbreaks[i]);
41 		CKTbreakDump(ckt);
42 #endif
43                 ckt->CKTbreaks[i] = time;
44                 return(OK);
45             }
46             if(i>0 && time-ckt->CKTbreaks[i-1] <= ckt->CKTminBreak) {
47                 /* very close together, but after, so skip */
48 #ifdef TRACE_BREAKPOINT
49                 printf("[t:%e] \t %e skipped\n", ckt->CKTtime, time);
50 		CKTbreakDump(ckt);
51 #endif
52                 return(OK);
53             }
54             /* fits in middle - new array & insert */
55             tmp = TMALLOC(double, ckt->CKTbreakSize + 1);
56             if(tmp == NULL) return(E_NOMEM);
57             for(j=0;j<i;j++) {
58                 tmp[j] = ckt->CKTbreaks[j];
59             }
60             tmp[i]=time;
61 #ifdef TRACE_BREAKPOINT
62                 printf("[t:%e] \t %e added\n", ckt->CKTtime, time);
63 		CKTbreakDump(ckt);
64 #endif
65             for(j=i;j<ckt->CKTbreakSize;j++) {
66                 tmp[j+1] = ckt->CKTbreaks[j];
67             }
68             FREE(ckt->CKTbreaks);
69             ckt->CKTbreakSize++;
70             ckt->CKTbreaks=tmp;
71 
72             return(OK);
73         }
74     }
75     /* never found it - beyond end of time - extend out idea of time */
76     if(time-ckt->CKTbreaks[ckt->CKTbreakSize-1]<=ckt->CKTminBreak) {
77         /* very close tegether - keep earlier, throw out new point */
78 #ifdef TRACE_BREAKPOINT
79                 printf("[t:%e] \t %e skipped (at the end)\n", ckt->CKTtime, time);
80                 CKTbreakDump(ckt);
81 #endif
82         return(OK);
83     }
84     /* fits at end - grow array & add on */
85     ckt->CKTbreaks = TREALLOC(double, ckt->CKTbreaks, ckt->CKTbreakSize + 1);
86     ckt->CKTbreakSize++;
87     ckt->CKTbreaks[ckt->CKTbreakSize-1]=time;
88 #ifdef TRACE_BREAKPOINT
89                 printf("[t:%e] \t %e added at end\n", ckt->CKTtime, time);
90 		CKTbreakDump(ckt);
91 #endif
92     return(OK);
93 }
94