double pulse_newton_sim_voc(struct device *in) { printf_log("Looking for Voc\n"); double C = in->C; double clamp = 0.1; double step = 0.01; double e0; double e1; double i0; double i1; double deriv; double Rdrain = pulse_config.pulse_Rload + in->Rcontact; solve_all(in); i0 = get_I(in); e0 = fabs(i0 + in->Vapplied * (1.0 / in->Rshunt - 1.0 / Rdrain)); in->Vapplied += step; solve_all(in); i1 = get_I(in); e1 = fabs(i1 + in->Vapplied * (1.0 / in->Rshunt - 1.0 / Rdrain)); deriv = (e1 - e0) / step; step = -e1 / deriv; step = step / (1.0 + fabs(step / clamp)); in->Vapplied += step; int count = 0; int max = 200; do { e0 = e1; solve_all(in); i1 = get_I(in); e1 = fabs(i1 + in->Vapplied * (1.0 / in->Rshunt - 1.0 / Rdrain)); deriv = (e1 - e0) / step; step = -e1 / deriv; step = step / (1.0 + fabs(step / clamp)); in->Vapplied += step; if (get_dump_status(dump_print_text) == TRUE) { printf_log ("%d pulse voc find Voc Vapplied=%lf step=%le error=%le\n", count, in->Vapplied, step, e1); } if (count > max) break; count++; } while (e1 > 1e-12); double ret = in->Vapplied - C * (i1 - in->Ilast) / in->dt; return ret; }
gdouble newton_sim_voc(struct simulation *sim, struct device *in) { printf_log(sim,"Looking for Voc\n"); gdouble C=in->C; gdouble clamp=0.1; gdouble step=0.01; gdouble e0; gdouble e1; gdouble i0; gdouble i1; gdouble deriv; gdouble Rdrain=in->Rload+in->Rcontact; gdouble Vapplied=0.0; gdouble Vapplied_last=0.0; Vapplied=contact_get_voltage(sim,in,0); Vapplied_last=contact_get_voltage_last(sim,in,0); solve_all(sim,in); i0=get_I(in); e0=fabs(i0+Vapplied*(1.0/in->Rshunt-1.0/Rdrain)); Vapplied+=step; contact_set_voltage(sim,in,0,Vapplied); solve_all(sim,in); i1=get_I(in); e1=fabs(i1+Vapplied*(1.0/in->Rshunt-1.0/Rdrain)); deriv=(e1-e0)/step; step=-e1/deriv; step=step/(1.0+fabs(step/clamp)); Vapplied+=step; contact_set_voltage(sim,in,0,Vapplied); int count=0; int max=200; do { e0=e1; solve_all(sim,in); i1=get_I(in); e1=fabs(i1+Vapplied*(1.0/in->Rshunt-1.0/Rdrain)); deriv=(e1-e0)/step; step=-e1/deriv; step=step/(1.0+fabs(step/clamp)); Vapplied+=step; contact_set_voltage(sim,in,0,Vapplied); if (get_dump_status(sim,dump_print_text)==TRUE) { printf_log(sim,"%d voc find Voc Vapplied=%Lf step=%Le error=%Le\n",count,Vapplied,step,e1); } if (count>max) break; count++; }while(e1>1e-12); gdouble ret=Vapplied-C*(i1-in->Ilast)/in->dt; return ret; }
int main() { solve_all(); //solve_one(2); return 0; }