diff --git a/src/spicelib/analysis/cktsens.c b/src/spicelib/analysis/cktsens.c index 555462857..34e33e0d7 100644 --- a/src/spicelib/analysis/cktsens.c +++ b/src/spicelib/analysis/cktsens.c @@ -24,14 +24,14 @@ char SF2[] = "dc"; char SF3[] = "bf"; #endif -char *Sfilter = NULL; +char* Sfilter = NULL; double Sens_Delta = 0.000001; double Sens_Abs_Delta = 0.000001; -static int sens_setp(sgen *sg, CKTcircuit *ckt, IFvalue *val); -static int sens_load(sgen *sg, CKTcircuit *ckt, int is_dc); -static int sens_temp(sgen *sg, CKTcircuit *ckt); -static int count_steps(int type, double low, double high, int steps, double *stepsize); +static int sens_setp(sgen* sg, CKTcircuit* ckt, IFvalue* val); +static int sens_load(sgen* sg, CKTcircuit* ckt, int is_dc); +static int sens_temp(sgen* sg, CKTcircuit* ckt); +static int count_steps(int type, double low, double high, int steps, double* stepsize); static double inc_freq(double freq, int type, double step_size); #define save_context(thing, place) { \ @@ -40,8 +40,8 @@ static double inc_freq(double freq, int type, double step_size); #define release_context(thing, place) \ if(place) { \ - thing = place; \ - place = NULL; \ + thing = place; \ + place = NULL; \ } @@ -60,372 +60,376 @@ static double inc_freq(double freq, int type, double step_size); */ static int error; -int sens_sens(CKTcircuit *ckt, int restart) +int sens_sens(CKTcircuit* ckt, int restart) { -/* -#ifdef KLU - if (ckt->CKTkluMODE) - { - fprintf (stderr, "\n\n\tThe Sensitivity Analysis is not supported in KLU environment\n\tPlease add '.options sparse' in you netlist\n\n\n") ; - return OK ; - } else { -#endif -*/ - SENS_AN *job = (SENS_AN *) ckt->CKTcurJob; + /* + #ifdef KLU + if (ckt->CKTkluMODE) + { + fprintf (stderr, "\n\n\tThe Sensitivity Analysis is not supported in KLU environment\n\tPlease add '.options sparse' in you netlist\n\n\n") ; + return OK ; + } else { + #endif + */ + SENS_AN* job = (SENS_AN*)ckt->CKTcurJob; - static int size; - static double *delta_I, *delta_iI, - *delta_I_delta_Y, *delta_iI_delta_Y; - sgen *sg; - static double freq; - static int nfreqs; - static int i; - static SMPmatrix *delta_Y = NULL, *Y; - static double step_size; - double *E, *iE; - IFvalue value, nvalue; - double *output_values; - IFcomplex *output_cvalues; - double delta_var; - int (*fn) (SMPmatrix *, GENmodel *, CKTcircuit *, int *); - static int is_dc; - int k, j, n; - int num_vars, branch_eq=0; - runDesc *sen_data = NULL; - char namebuf[513]; - IFuid *output_names, freq_name; - int bypass; - int type; - double *saved_rhs = NULL, - *saved_irhs = NULL; - SMPmatrix *saved_matrix = NULL; + static int size; + static double* delta_I, * delta_iI, + * delta_I_delta_Y, * delta_iI_delta_Y; + sgen* sg; + static double freq; + static int nfreqs; + static int i; + static SMPmatrix* delta_Y = NULL, * Y; + static double step_size; + double* E, * iE; + IFvalue value, nvalue; + double* output_values; + IFcomplex* output_cvalues; + double delta_var; + int (*fn) (SMPmatrix*, GENmodel*, CKTcircuit*, int*); + static int is_dc; + int k, j, n; + int num_vars, branch_eq = 0; + runDesc* sen_data = NULL; + char namebuf[513]; + IFuid* output_names, freq_name; + int bypass; + int type; + double* saved_rhs = NULL, + * saved_irhs = NULL; + SMPmatrix* saved_matrix = NULL; #ifdef KLU - int size_CSC ; + int size_CSC; #endif #ifndef notdef #ifdef notdef - for (sg = sgen_init(ckt, 0); sg; sgen_next(&sg)) { - if (sg->is_instparam) - printf("%s:%s:%s -> param %s\n", - DEVices[sg->dev]->DEVpublic.name, - sg->model->GENmodName, - sg->instance->GENname, - sg->ptable[sg->param].keyword); - else - printf("%s:%s:%s -> mparam %s\n", - DEVices[sg->dev]->DEVpublic.name, - sg->model->GENmodName, - sg->instance->GENname, - sg->ptable[sg->param].keyword); - } + for (sg = sgen_init(ckt, 0); sg; sgen_next(&sg)) { + if (sg->is_instparam) + printf("%s:%s:%s -> param %s\n", + DEVices[sg->dev]->DEVpublic.name, + sg->model->GENmodName, + sg->instance->GENname, + sg->ptable[sg->param].keyword); + else + printf("%s:%s:%s -> mparam %s\n", + DEVices[sg->dev]->DEVpublic.name, + sg->model->GENmodName, + sg->instance->GENname, + sg->ptable[sg->param].keyword); + } #endif #ifdef ASDEBUG - DEBUG(1) - printf(">>> restart : %d\n", restart); + DEBUG(1) + printf(">>> restart : %d\n", restart); #endif - /* get to work */ + /* get to work */ - restart = 1; - if (restart) { + restart = 1; + if (restart) { - freq = 0.0; - is_dc = (job->step_type == SENS_DC); - nfreqs = count_steps(job->step_type, job->start_freq, - job->stop_freq, job->n_freq_steps, - &step_size); + freq = 0.0; + is_dc = (job->step_type == SENS_DC); + nfreqs = count_steps(job->step_type, job->start_freq, + job->stop_freq, job->n_freq_steps, + &step_size); - if (!is_dc) - freq = job->start_freq; + if (!is_dc) + freq = job->start_freq; - error = CKTop(ckt, - (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, - (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT, - ckt->CKTdcMaxIter); + error = CKTop(ckt, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT, + ckt->CKTdcMaxIter); #ifdef notdef - ckt->CKTmode = (ckt->CKTmode & MODEUIC) - | MODEDCOP | MODEINITSMSIG; + ckt->CKTmode = (ckt->CKTmode & MODEUIC) + | MODEDCOP | MODEINITSMSIG; #endif - if (error) - return error; + if (error) + return error; - size = SMPmatSize(ckt->CKTmatrix); + size = SMPmatSize(ckt->CKTmatrix); - /* Create the perturbation matrix */ - delta_Y = TMALLOC(SMPmatrix, 1); + /* Create the perturbation matrix */ + delta_Y = TMALLOC(SMPmatrix, 1); - error = SMPnewMatrix(delta_Y, size); - if (error) - return error; + error = SMPnewMatrix(delta_Y, size); + if (error) + return error; #ifdef KLU - delta_Y->SMPkluMatrix->KLUmatrixDiag = NULL ; + delta_Y->SMPkluMatrix->KLUmatrixDiag = NULL; #endif -// SMPprint(delta_Y, NULL); - size += 1; + // SMPprint(delta_Y, NULL); + size += 1; - /* Create an extra rhs */ - delta_I = TMALLOC(double, size); - delta_iI = TMALLOC(double, size); + /* Create an extra rhs */ + delta_I = TMALLOC(double, size); + delta_iI = TMALLOC(double, size); - delta_I_delta_Y = TMALLOC(double, size); - delta_iI_delta_Y = TMALLOC(double, size); + delta_I_delta_Y = TMALLOC(double, size); + delta_iI_delta_Y = TMALLOC(double, size); + num_vars = 0; + for (sg = sgen_init(ckt, is_dc); sg; sgen_next(&sg)) { + num_vars += 1; + } - num_vars = 0; - for (sg = sgen_init(ckt, is_dc); sg; sgen_next(&sg)) { - num_vars += 1; - } + if (!num_vars) + return OK; /* XXXX Should be E_ something */ - if (!num_vars) - return OK; /* XXXX Should be E_ something */ + k = 0; + output_names = TMALLOC(IFuid, num_vars); + for (sg = sgen_init(ckt, is_dc); sg; sgen_next(&sg)) { + if (!sg->is_instparam) { + sprintf(namebuf, "%s:%s", + sg->instance->GENname, + sg->ptable[sg->param].keyword); + } + else if ((sg->ptable[sg->param].dataType + & IF_PRINCIPAL) && sg->is_principle == 1) + { + sprintf(namebuf, "%s", sg->instance->GENname); + } + else { + sprintf(namebuf, "%s_%s", + sg->instance->GENname, + sg->ptable[sg->param].keyword); + } - k = 0; - output_names = TMALLOC(IFuid, num_vars); - for (sg = sgen_init(ckt, is_dc); sg; sgen_next(&sg)) { - if (!sg->is_instparam) { - sprintf(namebuf, "%s:%s", - sg->instance->GENname, - sg->ptable[sg->param].keyword); - } else if ((sg->ptable[sg->param].dataType - & IF_PRINCIPAL) && sg->is_principle == 1) - { - sprintf(namebuf, "%s", sg->instance->GENname); - } else { - sprintf(namebuf, "%s_%s", - sg->instance->GENname, - sg->ptable[sg->param].keyword); - } + SPfrontEnd->IFnewUid(ckt, + output_names + k, NULL, + namebuf, UID_OTHER, NULL); + k += 1; + } - SPfrontEnd->IFnewUid (ckt, - output_names + k, NULL, - namebuf, UID_OTHER, NULL); - k += 1; - } + if (is_dc) { + type = IF_REAL; + freq_name = NULL; + } + else { + type = IF_COMPLEX; + SPfrontEnd->IFnewUid(ckt, + &freq_name, NULL, + "frequency", UID_OTHER, NULL); + } - if (is_dc) { - type = IF_REAL; - freq_name = NULL; - } else { - type = IF_COMPLEX; - SPfrontEnd->IFnewUid (ckt, - &freq_name, NULL, - "frequency", UID_OTHER, NULL); - } + error = SPfrontEnd->OUTpBeginPlot( + ckt, ckt->CKTcurJob, + ckt->CKTcurJob->JOBname, + freq_name, IF_REAL, + num_vars, output_names, type, &sen_data); + if (error) + return error; - error = SPfrontEnd->OUTpBeginPlot ( - ckt, ckt->CKTcurJob, - ckt->CKTcurJob->JOBname, - freq_name, IF_REAL, - num_vars, output_names, type, &sen_data); - if (error) - return error; + FREE(output_names); + if (is_dc) { + output_values = TMALLOC(double, num_vars); + output_cvalues = NULL; + } + else { + output_values = NULL; + output_cvalues = TMALLOC(IFcomplex, num_vars); + if (job->step_type != SENS_LINEAR) + SPfrontEnd->OUTattributes(sen_data, NULL, OUT_SCALE_LOG, NULL); - FREE(output_names); - if (is_dc) { - output_values = TMALLOC(double, num_vars); - output_cvalues = NULL; - } else { - output_values = NULL; - output_cvalues = TMALLOC(IFcomplex, num_vars); - if (job->step_type != SENS_LINEAR) - SPfrontEnd->OUTattributes (sen_data, NULL, OUT_SCALE_LOG, NULL); + } - } - - } else { - /*XXX Restore saved state */ - output_values = NULL; - output_cvalues = NULL; - fprintf(stderr, "ERROR: restore is not implemented for cktsens\n"); - controlled_exit(1); - } + } + else { + /*XXX Restore saved state */ + output_values = NULL; + output_cvalues = NULL; + fprintf(stderr, "ERROR: restore is not implemented for cktsens\n"); + controlled_exit(1); + } #ifdef ASDEBUG - DEBUG(1) - printf("start: %f, num: %d, dc: %d\n", freq, nfreqs, is_dc); + DEBUG(1) + printf("start: %f, num: %d, dc: %d\n", freq, nfreqs, is_dc); #endif - if (!job->output_volt) - branch_eq = CKTfndBranch(ckt, job->output_src); - bypass = ckt->CKTbypass; - ckt->CKTbypass = 0; + if (!job->output_volt) + branch_eq = CKTfndBranch(ckt, job->output_src); + bypass = ckt->CKTbypass; + ckt->CKTbypass = 0; - /* CKTop solves into CKTrhs and CKTmatrix->SPmatrix, - * CKTirhs is hopefully zero (fresh allocated ?) */ + /* CKTop solves into CKTrhs and CKTmatrix->SPmatrix, + * CKTirhs is hopefully zero (fresh allocated ?) */ - E = ckt->CKTrhs; - iE = ckt->CKTirhs; - Y = ckt->CKTmatrix; + E = ckt->CKTrhs; + iE = ckt->CKTirhs; + Y = ckt->CKTmatrix; #ifdef KLU - if (ckt->CKTkluMODE) { + if (ckt->CKTkluMODE) { - /* Convert the KLU Circuit Matrix to Complex */ - for (i = 0 ; i < (int)Y->SMPkluMatrix->KLUmatrixNZ ; i++) { - Y->SMPkluMatrix->KLUmatrixAxComplex [2 * i] = Y->SMPkluMatrix->KLUmatrixAx [i] ; - Y->SMPkluMatrix->KLUmatrixAxComplex [2 * i + 1] = 0.0 ; - } + /* Convert the KLU Circuit Matrix to Complex */ + for (i = 0; i < (int)Y->SMPkluMatrix->KLUmatrixNZ; i++) { + Y->SMPkluMatrix->KLUmatrixAxComplex[2 * i] = Y->SMPkluMatrix->KLUmatrixAx[i]; + Y->SMPkluMatrix->KLUmatrixAxComplex[2 * i + 1] = 0.0; + } - Y->SMPkluMatrix->KLUmatrixIsComplex = KLUMatrixComplex ; + Y->SMPkluMatrix->KLUmatrixIsComplex = KLUMatrixComplex; - SMPcReorder (Y, ckt->CKTpivotAbsTol, ckt->CKTpivotRelTol, &size_CSC) ; // size_CSC is just a placeholder here - } + SMPcReorder(Y, ckt->CKTpivotAbsTol, ckt->CKTpivotRelTol, &size_CSC); // size_CSC is just a placeholder here + } #endif #ifdef ASDEBUG - DEBUG(1) { - printf("Operating point:\n"); - for (i = 0; i < size; i++) - printf(" E [%d] = %20.15g\n", i, E[i]); - } + DEBUG(1) { + printf("Operating point:\n"); + for (i = 0; i < size; i++) + printf(" E [%d] = %20.15g\n", i, E[i]); + } #endif #ifdef notdef - for (j = 0; j <= ckt->CKTmaxOrder + 1; j++) { - save_states[j] = ckt->CKTstates[j]; - ckt->CKTstates[j] = NULL; - } + for (j = 0; j <= ckt->CKTmaxOrder + 1; j++) { + save_states[j] = ckt->CKTstates[j]; + ckt->CKTstates[j] = NULL; + } #endif - for (i = 0; i < nfreqs; i++) { - /* XXX handle restart */ + for (i = 0; i < nfreqs; i++) { + /* XXX handle restart */ - n = 0; + n = 0; - if (SPfrontEnd->IFpauseTest()) { - /* XXX Save State */ - return E_PAUSE; - } + if (SPfrontEnd->IFpauseTest()) { + /* XXX Save State */ + return E_PAUSE; + } - for (j = 0; j < size; j++) { - delta_I[j] = 0.0; - delta_iI[j] = 0.0; - } + for (j = 0; j < size; j++) { + delta_I[j] = 0.0; + delta_iI[j] = 0.0; + } - if (freq != 0.0) { + if (freq != 0.0) { - /* This generates Y in LU form */ - ckt->CKTomega = 2.0 * M_PI * freq; + /* This generates Y in LU form */ + ckt->CKTomega = 2.0 * M_PI * freq; - /* Yes, all this has to be re-done */ - /* XXX Free old states */ - error = CKTunsetup(ckt); - if (error) - return error; + /* Yes, all this has to be re-done */ + /* XXX Free old states */ + error = CKTunsetup(ckt); + if (error) + return error; - /* XXX ckt->CKTmatrix->SPmatrix = Y; */ + /* XXX ckt->CKTmatrix->SPmatrix = Y; */ - error = CKTsetup(ckt); - if (error) - return error; + error = CKTsetup(ckt); + if (error) + return error; #ifdef notdef - for (j = 0; j <= ckt->CKTmaxOrder + 1; j++) { - /* XXX Free new states */ - ckt->CKTstates[j] = save_states[j]; - } + for (j = 0; j <= ckt->CKTmaxOrder + 1; j++) { + /* XXX Free new states */ + ckt->CKTstates[j] = save_states[j]; + } #endif - error = CKTtemp(ckt); - if (error) - return error; - error = CKTload(ckt); /* INITSMSIGS */ - if (error) - return error; + error = CKTtemp(ckt); + if (error) + return error; + error = CKTload(ckt); /* INITSMSIGS */ + if (error) + return error; #ifdef KLU - if (ckt->CKTmatrix->CKTkluMODE) - { - /* ReOrder */ - error = SMPpreOrder (ckt->CKTmatrix) ; + if (ckt->CKTmatrix->CKTkluMODE) + { + /* ReOrder */ + error = SMPpreOrder(ckt->CKTmatrix); - /* Conversion from Real Circuit Matrix to Complex Circuit Matrix */ - if (!ckt->CKTmatrix->SMPkluMatrix->KLUmatrixIsComplex) - { - for (i = 0 ; i < DEVmaxnum ; i++) - if (DEVices [i] && DEVices [i]->DEVbindCSCComplex && ckt->CKThead [i]) - DEVices [i]->DEVbindCSCComplex (ckt->CKThead [i], ckt) ; + /* Conversion from Real Circuit Matrix to Complex Circuit Matrix */ + if (!ckt->CKTmatrix->SMPkluMatrix->KLUmatrixIsComplex) + { + for (i = 0; i < DEVmaxnum; i++) + if (DEVices[i] && DEVices[i]->DEVbindCSCComplex && ckt->CKThead[i]) + DEVices[i]->DEVbindCSCComplex(ckt->CKThead[i], ckt); - ckt->CKTmatrix->SMPkluMatrix->KLUmatrixIsComplex = KLUMatrixComplex ; - } - } + ckt->CKTmatrix->SMPkluMatrix->KLUmatrixIsComplex = KLUMatrixComplex; + } + } #endif - error = NIacIter(ckt); - if (error) - return error; + error = NIacIter(ckt); + if (error) + return error; #ifdef notdef - /* XXX Why? */ - for (j = 0; j <= ckt->CKTmaxOrder + 1; j++) { - ckt->CKTstates[j] = NULL; - } + /* XXX Why? */ + for (j = 0; j <= ckt->CKTmaxOrder + 1; j++) { + ckt->CKTstates[j] = NULL; + } #endif - /* NIacIter solves into CKTrhsOld, CKTirhsOld and CKTmatrix->SPmatrix */ - E = ckt->CKTrhsOld; - iE = ckt->CKTirhsOld; - Y = ckt->CKTmatrix; - } + /* NIacIter solves into CKTrhsOld, CKTirhsOld and CKTmatrix->SPmatrix */ + E = ckt->CKTrhsOld; + iE = ckt->CKTirhsOld; + Y = ckt->CKTmatrix; + } - /* Use a different vector & matrix */ + /* Use a different vector & matrix */ - save_context(ckt->CKTrhs, saved_rhs); - save_context(ckt->CKTirhs, saved_irhs); - save_context(ckt->CKTmatrix, saved_matrix); + save_context(ckt->CKTrhs, saved_rhs); + save_context(ckt->CKTirhs, saved_irhs); + save_context(ckt->CKTmatrix, saved_matrix); - ckt->CKTrhs = delta_I; - ckt->CKTirhs = delta_iI; - ckt->CKTmatrix = delta_Y; + ckt->CKTrhs = delta_I; + ckt->CKTirhs = delta_iI; + ckt->CKTmatrix = delta_Y; - /* calc. effect of each param */ - for (sg = sgen_init(ckt, is_dc /* job->plist */); - sg; sgen_next(&sg)) - { + /* calc. effect of each param */ + for (sg = sgen_init(ckt, is_dc /* job->plist */); + sg; sgen_next(&sg)) + { #ifdef ASDEBUG - DEBUG(2) { - printf("E/iE: %x/%x; delta_I/iI: %x/%x\n", - E, iE, delta_I, delta_iI); - printf("cktrhs/irhs: %x/%x\n", - ckt->CKTrhs, ckt->CKTirhs); + DEBUG(2) { + printf("E/iE: %x/%x; delta_I/iI: %x/%x\n", + E, iE, delta_I, delta_iI); + printf("cktrhs/irhs: %x/%x\n", + ckt->CKTrhs, ckt->CKTirhs); - if (sg->is_instparam) - printf("%s:%s:%s -> param %s\n", - DEVices[sg->dev]->DEVpublic.name, - sg->model->GENmodName, - sg->instance->GENname, - sg->ptable[sg->param].keyword); - else - printf("%s:%s:%s -> mparam %s\n", - DEVices[sg->dev]->DEVpublic.name, - sg->model->GENmodName, - sg->instance->GENname, - sg->ptable[sg->param].keyword); - } + if (sg->is_instparam) + printf("%s:%s:%s -> param %s\n", + DEVices[sg->dev]->DEVpublic.name, + sg->model->GENmodName, + sg->instance->GENname, + sg->ptable[sg->param].keyword); + else + printf("%s:%s:%s -> mparam %s\n", + DEVices[sg->dev]->DEVpublic.name, + sg->model->GENmodName, + sg->instance->GENname, + sg->ptable[sg->param].keyword); + } #endif - SMPcClear(delta_Y); + SMPcClear(delta_Y); - for (j = 0; j < size; j++) { - delta_I[j] = 0.0; - delta_iI[j] = 0.0; - } + for (j = 0; j < size; j++) { + delta_I[j] = 0.0; + delta_iI[j] = 0.0; + } - /* ? should this just call CKTsetup - * ? but then CKThead would have to get fiddled with */ + /* ? should this just call CKTsetup + * ? but then CKThead would have to get fiddled with */ - ckt->CKTnumStates = sg->istate; + ckt->CKTnumStates = sg->istate; - fn = DEVices[sg->dev]->DEVsetup; - if (fn) { - CKTnode *node = ckt->CKTlastNode; + fn = DEVices[sg->dev]->DEVsetup; + if (fn) { + CKTnode* node = ckt->CKTlastNode; /* XXXX insert old state base here ?? */ - fn (delta_Y, sg->model, ckt, &ckt->CKTnumStates); + fn(delta_Y, sg->model, ckt, &ckt->CKTnumStates); if (node != ckt->CKTlastNode) { fprintf(stderr, "Internal Error: node allocation in DEVsetup() during sensitivity analysis, this will cause serious troubles !, please report this issue !\n"); controlled_exit(EXIT_FAILURE); @@ -433,162 +437,162 @@ int sens_sens(CKTcircuit *ckt, int restart) } #ifdef KLU - if (ckt->CKTmatrix->CKTkluMODE) - { - /* Populate the delta_Y KLU Matrix */ + if (ckt->CKTmatrix->CKTkluMODE) + { + /* Populate the delta_Y KLU Matrix */ - /* Convert the COO Storage to CSC for KLU and Fill the Binding Table */ - SMPconvertCOOtoCSC (delta_Y) ; + /* Convert the COO Storage to CSC for KLU and Fill the Binding Table */ + SMPconvertCOOtoCSC(delta_Y); - /* KLU Pointers Assignment */ - if (DEVices [sg->dev]->DEVbindCSC) - DEVices [sg->dev]->DEVbindCSC (sg->model, ckt) ; + /* KLU Pointers Assignment */ + if (DEVices[sg->dev]->DEVbindCSC) + DEVices[sg->dev]->DEVbindCSC(sg->model, ckt); - delta_Y->SMPkluMatrix->KLUmatrixIsComplex = KLUmatrixReal ; + delta_Y->SMPkluMatrix->KLUmatrixIsComplex = KLUmatrixReal; - /* Clear KLU Vectors */ - for (i = 0 ; i < (int)delta_Y->SMPkluMatrix->KLUmatrixNZ ; i++) - { - delta_Y->SMPkluMatrix->KLUmatrixAx [i] = 0 ; - delta_Y->SMPkluMatrix->KLUmatrixAxComplex [2 * i] = 0 ; - delta_Y->SMPkluMatrix->KLUmatrixAxComplex [2 * i + 1] = 0 ; - } - } + /* Clear KLU Vectors */ + for (i = 0; i < (int)delta_Y->SMPkluMatrix->KLUmatrixNZ; i++) + { + delta_Y->SMPkluMatrix->KLUmatrixAx[i] = 0; + delta_Y->SMPkluMatrix->KLUmatrixAxComplex[2 * i] = 0; + delta_Y->SMPkluMatrix->KLUmatrixAxComplex[2 * i + 1] = 0; + } + } #endif - /* ? CKTsetup would call NIreinit instead */ - ckt->CKTniState = NISHOULDREORDER | NIACSHOULDREORDER; + /* ? CKTsetup would call NIreinit instead */ + ckt->CKTniState = NISHOULDREORDER | NIACSHOULDREORDER; - /* XXX instead of calling temp here, just swap - * back to the original states */ - (void) sens_temp(sg, ckt); + /* XXX instead of calling temp here, just swap + * back to the original states */ + (void)sens_temp(sg, ckt); - /* XXX Leave original E until here!! so that temp reads - * the right node voltages */ + /* XXX Leave original E until here!! so that temp reads + * the right node voltages */ #ifdef KLU - if (ckt->CKTkluMODE) - { - if (!is_dc) - { - if (DEVices [sg->dev]->DEVbindCSCComplex) - DEVices [sg->dev]->DEVbindCSCComplex (sg->model, ckt) ; + if (ckt->CKTkluMODE) + { + if (!is_dc) + { + if (DEVices[sg->dev]->DEVbindCSCComplex) + DEVices[sg->dev]->DEVbindCSCComplex(sg->model, ckt); - delta_Y->SMPkluMatrix->KLUmatrixIsComplex = KLUMatrixComplex ; - } - } + delta_Y->SMPkluMatrix->KLUmatrixIsComplex = KLUMatrixComplex; + } + } #endif - if (sens_load(sg, ckt, is_dc)) { - if (error && error != E_BADPARM) - return error; /* XXX */ - continue; - } + if (sens_load(sg, ckt, is_dc)) { + if (error && error != E_BADPARM) + return error; /* XXX */ + continue; + } - /* Alter the parameter */ + /* Alter the parameter */ #ifdef ASDEBUG - DEBUG(1) printf("Original value: %g\n", sg->value); + DEBUG(1) printf("Original value: %g\n", sg->value); #endif #ifdef ASDEBUG - DEBUG(2) { - printf("Effect of device:\n"); - SMPprint(delta_Y, NULL); - printf("LHS:\n"); - for (j = 0; j < size; j++) - printf("%d: %g, %g\n", j, - delta_I[j], delta_iI[j]); - } + DEBUG(2) { + printf("Effect of device:\n"); + SMPprint(delta_Y, NULL); + printf("LHS:\n"); + for (j = 0; j < size; j++) + printf("%d: %g, %g\n", j, + delta_I[j], delta_iI[j]); + } #endif - if (sg->value != 0.0) - delta_var = sg->value * Sens_Delta; - else - delta_var = Sens_Abs_Delta; + if (sg->value != 0.0) + delta_var = sg->value * Sens_Delta; + else + delta_var = Sens_Abs_Delta; - nvalue.rValue = sg->value + delta_var; + nvalue.rValue = sg->value + delta_var; #ifdef ASDEBUG - DEBUG(1) - printf("New value: %g\n", nvalue.rValue); + DEBUG(1) + printf("New value: %g\n", nvalue.rValue); #endif - sens_setp(sg, ckt, &nvalue); - if (error && error != E_BADPARM) - return error; + sens_setp(sg, ckt, &nvalue); + if (error && error != E_BADPARM) + return error; - SMPconstMult(delta_Y, -1.0); + SMPconstMult(delta_Y, -1.0); - for (j = 0; j < size; j++) { - delta_I[j] *= -1.0; - delta_iI[j] *= -1.0; - } + for (j = 0; j < size; j++) { + delta_I[j] *= -1.0; + delta_iI[j] *= -1.0; + } #ifdef ASDEBUG - DEBUG(2) { - printf("Effect of negating matrix:\n"); - SMPprint(delta_Y, NULL); - for (j = 0; j < size; j++) - printf("%d: %g, %g\n", j, - delta_I[j], delta_iI[j]); - } + DEBUG(2) { + printf("Effect of negating matrix:\n"); + SMPprint(delta_Y, NULL); + for (j = 0; j < size; j++) + printf("%d: %g, %g\n", j, + delta_I[j], delta_iI[j]); + } #endif - /* XXX swap back to temp states ?? Naw ... */ - (void) sens_temp(sg, ckt); + /* XXX swap back to temp states ?? Naw ... */ + (void)sens_temp(sg, ckt); #ifdef ASDEBUG - DEBUG(1) { - if (sens_getp(sg, ckt, &value)) { - continue; - } + DEBUG(1) { + if (sens_getp(sg, ckt, &value)) { + continue; + } - printf("New value in device: %g\n", - value.rValue); - } + printf("New value in device: %g\n", + value.rValue); + } #endif - sens_load(sg, ckt, is_dc); + sens_load(sg, ckt, is_dc); #ifdef ASDEBUG - DEBUG(2) { - printf("Effect of changing the parameter:\n"); - SMPprint(delta_Y, NULL); - for (j = 0; j < size; j++) - printf("%d: %g, %g\n", j, - delta_I[j], delta_iI[j]); - } + DEBUG(2) { + printf("Effect of changing the parameter:\n"); + SMPprint(delta_Y, NULL); + for (j = 0; j < size; j++) + printf("%d: %g, %g\n", j, + delta_I[j], delta_iI[j]); + } #endif - /* Set the perturbed variable back to it's - * original value - */ + /* Set the perturbed variable back to it's + * original value + */ - value.rValue = sg->value; - sens_setp(sg, ckt, &value); - (void) sens_temp(sg, ckt); /* XXX is this necessary? */ + value.rValue = sg->value; + sens_setp(sg, ckt, &value); + (void)sens_temp(sg, ckt); /* XXX is this necessary? */ - /* Back to business . . . */ + /* Back to business . . . */ #ifdef ASDEBUG - DEBUG(2) - for (j = 0; j < size; j++) - printf(" E [%d] = %20.15g\n", - j, E[j]); + DEBUG(2) + for (j = 0; j < size; j++) + printf(" E [%d] = %20.15g\n", + j, E[j]); #endif - /* delta_Y E */ -// fprintf(stderr, "\n\nPRIMA\n"); -// SMPprint(delta_Y, NULL); - SMPmultiply(delta_Y, delta_I_delta_Y, E, - delta_iI_delta_Y, iE); -// fprintf(stderr, "\n\nDOPO\n"); -// SMPprint(delta_Y, NULL); + /* delta_Y E */ +// fprintf(stderr, "\n\nPRIMA\n"); +// SMPprint(delta_Y, NULL); + SMPmultiply(delta_Y, delta_I_delta_Y, E, + delta_iI_delta_Y, iE); +// fprintf(stderr, "\n\nDOPO\n"); +// SMPprint(delta_Y, NULL); #ifdef ASDEBUG - DEBUG(2) - for (j = 0; j < size; j++) - printf("delta_Y * E [%d] = %20.15g\n", - j, delta_I_delta_Y[j]); + DEBUG(2) + for (j = 0; j < size; j++) + printf("delta_Y * E [%d] = %20.15g\n", + j, delta_I_delta_Y[j]); #endif // fprintf (stderr, "\n\nPRIMA 1\n") ; @@ -597,11 +601,11 @@ int sens_sens(CKTcircuit *ckt, int restart) // fprintf (stderr, "RHS [%d]: %-.9g j%-.9g\n", j, delta_I [j], delta_iI [j]) ; // } - /* delta_I - delta_Y E */ - for (j = 0; j < size; j++) { - delta_I[j] -= delta_I_delta_Y[j]; - delta_iI[j] -= delta_iI_delta_Y[j]; - } + /* delta_I - delta_Y E */ + for (j = 0; j < size; j++) { + delta_I[j] -= delta_I_delta_Y[j]; + delta_iI[j] -= delta_iI_delta_Y[j]; + } // fprintf (stderr, "\n\nDOPO 1\n") ; // for (j = 0 ; j < size ; j++) @@ -610,13 +614,13 @@ int sens_sens(CKTcircuit *ckt, int restart) // } #ifdef ASDEBUG - DEBUG(2) { - printf(">>> Y:\n"); - SMPprint(Y, NULL); - for (j = 0; j < size; j++) - printf("%d: %g, %g\n", j, - delta_I[j], delta_iI[j]); - } + DEBUG(2) { + printf(">>> Y:\n"); + SMPprint(Y, NULL); + for (j = 0; j < size; j++) + printf("%d: %g, %g\n", j, + delta_I[j], delta_iI[j]); + } #endif // fprintf (stderr, "\n\nPRIMA\n") ; @@ -625,8 +629,8 @@ int sens_sens(CKTcircuit *ckt, int restart) // fprintf (stderr, "RHS [%d]: %-.14g j%-.14g\n", j, delta_I [j], delta_iI [j]) ; // } - /* Solve; Y already factored */ - SMPcSolve(Y, delta_I, delta_iI, NULL, NULL); + /* Solve; Y already factored */ + SMPcSolve(Y, delta_I, delta_iI, NULL, NULL); // fprintf (stderr, "\n\nDOPO\n") ; // for (j = 0 ; j < size ; j++) @@ -634,336 +638,340 @@ int sens_sens(CKTcircuit *ckt, int restart) // fprintf (stderr, "RHS [%d]: %-.14g j%-.14g\n", j, delta_I [j], delta_iI [j]) ; // } - /* the special `0' node - * the matrix indizes are [1..n] - * yet the vector indizes are [0..n] - * with [0] being implicit === 0 - */ - delta_I[0] = 0.0; - delta_iI[0] = 0.0; + /* the special `0' node + * the matrix indizes are [1..n] + * yet the vector indizes are [0..n] + * with [0] being implicit === 0 + */ + delta_I[0] = 0.0; + delta_iI[0] = 0.0; #ifdef ASDEBUG - DEBUG(2) { - for (j = 1; j < size; j++) { + DEBUG(2) { + for (j = 1; j < size; j++) { - if (sg->is_instparam) - printf("%d/%s.%s = %g, %g\n", - j, - sg->instance->GENname, - sg->ptable[sg->param].keyword, - delta_I[j], delta_iI[j]); - else - printf("%d/%s:%s = %g, %g\n", - j, - sg->instance->GENname, - sg->ptable[sg->param].keyword, - delta_I[j], delta_iI[j]); + if (sg->is_instparam) + printf("%d/%s.%s = %g, %g\n", + j, + sg->instance->GENname, + sg->ptable[sg->param].keyword, + delta_I[j], delta_iI[j]); + else + printf("%d/%s:%s = %g, %g\n", + j, + sg->instance->GENname, + sg->ptable[sg->param].keyword, + delta_I[j], delta_iI[j]); - } - } + } + } #endif - /* delta_I is now equal to delta_E */ + /* delta_I is now equal to delta_E */ - if (is_dc) { - if (job->output_volt) { - output_values[n] = - delta_I [job->output_pos->number] - - delta_I [job->output_neg->number]; + if (is_dc) { + if (job->output_volt) { + output_values[n] = + delta_I[job->output_pos->number] + - delta_I[job->output_neg->number]; // fprintf (stderr, "Pos: %d\tNeg: %d\n", job->output_pos->number, job->output_neg->number) ; - } - else { - output_values[n] = delta_I[branch_eq]; - } -// fprintf (stderr, "output_values real PRIMA: %-.14g\n", output_values [n]) ; - output_values[n] /= delta_var; -// fprintf(stderr, "output_values real DOPO: %-.14g - delta_var: %-.9g\n", output_values [n], delta_var); - } else { - if (job->output_volt) { - output_cvalues[n].real = - delta_I [job->output_pos->number] - - delta_I [job->output_neg->number]; - output_cvalues[n].imag = - delta_iI [job->output_pos->number] - - delta_iI [job->output_neg->number]; - } else { - output_cvalues[n].real = - delta_I[branch_eq]; - output_cvalues[n].imag = - delta_iI[branch_eq]; - } + } + else { + output_values[n] = delta_I[branch_eq]; + } +// fprintf (stderr, "output_values real PRIMA: %-.14g\n", output_values [n]) ; + output_values[n] /= delta_var; +// fprintf(stderr, "output_values real DOPO: %-.14g - delta_var: %-.9g\n", output_values [n], delta_var); + } + else { + if (job->output_volt) { + output_cvalues[n].real = + delta_I[job->output_pos->number] + - delta_I[job->output_neg->number]; + output_cvalues[n].imag = + delta_iI[job->output_pos->number] + - delta_iI[job->output_neg->number]; + } + else { + output_cvalues[n].real = + delta_I[branch_eq]; + output_cvalues[n].imag = + delta_iI[branch_eq]; + } // fprintf (stderr, "output_values complex: %-.9g j%-.9g\n", output_cvalues [n].real, output_cvalues [n].imag) ; - output_cvalues[n].real /= delta_var; - output_cvalues[n].imag /= delta_var; - } + output_cvalues[n].real /= delta_var; + output_cvalues[n].imag /= delta_var; + } + n += 1; + } - n += 1; + release_context(ckt->CKTrhs, saved_rhs); + release_context(ckt->CKTirhs, saved_irhs); - } + release_context(ckt->CKTmatrix, saved_matrix); - release_context(ckt->CKTrhs, saved_rhs); - release_context(ckt->CKTirhs, saved_irhs); + if (is_dc) + nvalue.v.vec.rVec = output_values; + else + nvalue.v.vec.cVec = output_cvalues; - release_context(ckt->CKTmatrix, saved_matrix); + value.rValue = freq; - if (is_dc) - nvalue.v.vec.rVec = output_values; - else - nvalue.v.vec.cVec = output_cvalues; + SPfrontEnd->OUTpData(sen_data, &value, &nvalue); - value.rValue = freq; + freq = inc_freq(freq, job->step_type, step_size); - SPfrontEnd->OUTpData (sen_data, &value, &nvalue); + } - freq = inc_freq(freq, job->step_type, step_size); + SPfrontEnd->OUTendPlot(sen_data); - } + if (is_dc) { + FREE(output_values); /* XXX free various vectors */ + } + else { + FREE(output_cvalues); /* XXX free various vectors */ + } - SPfrontEnd->OUTendPlot (sen_data); + release_context(ckt->CKTrhs, saved_rhs); + release_context(ckt->CKTirhs, saved_irhs); - if (is_dc) { - FREE(output_values); /* XXX free various vectors */ - } else { - FREE(output_cvalues); /* XXX free various vectors */ - } + release_context(ckt->CKTmatrix, saved_matrix); - release_context(ckt->CKTrhs, saved_rhs); - release_context(ckt->CKTirhs, saved_irhs); + SMPdestroy(delta_Y); + FREE(delta_I); + FREE(delta_iI); - release_context(ckt->CKTmatrix, saved_matrix); + FREE(delta_I_delta_Y); + FREE(delta_iI_delta_Y); - SMPdestroy(delta_Y); - FREE(delta_I); - FREE(delta_iI); - - FREE(delta_I_delta_Y); - FREE(delta_iI_delta_Y); - - ckt->CKTbypass = bypass; + ckt->CKTbypass = bypass; #ifdef notdef - for (j = 0; j <= ckt->CKTmaxOrder + 1; j++) { - if (ckt->CKTstates[j]) - FREE(ckt->CKTstates[j]); - ckt->CKTstates[j] = save_states[j]; - } + for (j = 0; j <= ckt->CKTmaxOrder + 1; j++) { + if (ckt->CKTstates[j]) + FREE(ckt->CKTstates[j]); + ckt->CKTstates[j] = save_states[j]; + } #endif #endif - return OK; -/* -#ifdef KLU - } -#endif -*/ + return OK; + /* + #ifdef KLU + } + #endif + */ } double inc_freq(double freq, int type, double step_size) { - if (type != LINEAR) - freq *= step_size; - else - freq += step_size; + if (type != LINEAR) + freq *= step_size; + else + freq += step_size; - return freq; + return freq; } /* static double next_freq(int type, double freq, double stepsize) { - double s=0; + double s=0; - switch (type) { - case SENS_DC: - s = 0; - break; + switch (type) { + case SENS_DC: + s = 0; + break; - case SENS_LINEAR: - s = freq + stepsize; - break; + case SENS_LINEAR: + s = freq + stepsize; + break; - case SENS_DECADE: - case SENS_OCTAVE: - s = freq * stepsize; - break; - } - return s; + case SENS_DECADE: + case SENS_OCTAVE: + s = freq * stepsize; + break; + } + return s; } */ int -count_steps(int type, double low, double high, int steps, double *stepsize) +count_steps(int type, double low, double high, int steps, double* stepsize) { - double s; - int n; + double s; + int n; - if (steps < 1) - steps = 1; + if (steps < 1) + steps = 1; - switch (type) { - default: - case SENS_DC: - n = 0; - s = 0; - break; + switch (type) { + default: + case SENS_DC: + n = 0; + s = 0; + break; - case SENS_LINEAR: - n = steps; - s = (high - low) / steps; - break; + case SENS_LINEAR: + n = steps; + s = (high - low) / steps; + break; - case SENS_DECADE: - if (low <= 0.0) - low = 1e-3; - if (high <= low) - high = 10.0 * low; - n = (int)(steps * log10(high/low) + 1.01); - s = pow(10.0, 1.0 / steps); - break; + case SENS_DECADE: + if (low <= 0.0) + low = 1e-3; + if (high <= low) + high = 10.0 * low; + n = (int)(steps * log10(high / low) + 1.01); + s = pow(10.0, 1.0 / steps); + break; - case SENS_OCTAVE: - if (low <= 0.0) - low = 1e-3; - if (high <= low) - high = 2.0 * low; - n = (int)(steps * log(high/low) / M_LOG2E + 1.01); - s = pow(2.0, 1.0 / steps); - break; - } + case SENS_OCTAVE: + if (low <= 0.0) + low = 1e-3; + if (high <= low) + high = 2.0 * low; + n = (int)(steps * log(high / low) / M_LOG2E + 1.01); + s = pow(2.0, 1.0 / steps); + break; + } - if (n <= 0) - n = 1; + if (n <= 0) + n = 1; - *stepsize = s; - return n; + *stepsize = s; + return n; } static int -sens_load(sgen *sg, CKTcircuit *ckt, int is_dc) -{//fprintf (stderr, "LOAD - is_dc: %d\n", is_dc) ; - int (*fn) (GENmodel *, CKTcircuit *); +sens_load(sgen* sg, CKTcircuit* ckt, int is_dc) +{ +// fprintf (stderr, "LOAD - is_dc: %d\n", is_dc) ; + int (*fn) (GENmodel*, CKTcircuit*); - error = 0; + error = 0; - if (!is_dc) - fn = DEVices[sg->dev]->DEVacLoad; - else - fn = DEVices[sg->dev]->DEVload; + if (!is_dc) + fn = DEVices[sg->dev]->DEVacLoad; + else + fn = DEVices[sg->dev]->DEVload; - if (fn) - error = fn (sg->model, ckt); - else - return 1; + if (fn) + error = fn(sg->model, ckt); + else + return 1; - return error; + return error; } static int -sens_temp(sgen *sg, CKTcircuit *ckt) +sens_temp(sgen* sg, CKTcircuit* ckt) { - int (*fn) (GENmodel *, CKTcircuit *); + int (*fn) (GENmodel*, CKTcircuit*); - error = 0; + error = 0; - fn = DEVices[sg->dev]->DEVtemperature; + fn = DEVices[sg->dev]->DEVtemperature; - if (fn) - error = fn (sg->model, ckt); - else - return 1; + if (fn) + error = fn(sg->model, ckt); + else + return 1; - return error; + return error; } /* Get parameter value */ int -sens_getp(sgen *sg, CKTcircuit *ckt, IFvalue *val) +sens_getp(sgen* sg, CKTcircuit* ckt, IFvalue* val) { - int pid; + int pid; - NG_IGNORE(ckt); + NG_IGNORE(ckt); - error = 0; + error = 0; - if (sg->is_instparam) { - int (*fn) (CKTcircuit*, GENinstance*, int, IFvalue*, IFvalue*); - fn = DEVices[sg->dev]->DEVask; - pid = DEVices[sg->dev]->DEVpublic.instanceParms[sg->param].id; - if (fn) - error = fn (ckt, sg->instance, pid, val, NULL); - else - return 1; - } else { - int (*fn) (CKTcircuit*, GENmodel*, int, IFvalue*); - fn = DEVices[sg->dev]->DEVmodAsk; - pid = DEVices[sg->dev]->DEVpublic.modelParms[sg->param].id; - if (fn) - error = fn (ckt, sg->model, pid, val); - else - return 1; - } + if (sg->is_instparam) { + int (*fn) (CKTcircuit*, GENinstance*, int, IFvalue*, IFvalue*); + fn = DEVices[sg->dev]->DEVask; + pid = DEVices[sg->dev]->DEVpublic.instanceParms[sg->param].id; + if (fn) + error = fn(ckt, sg->instance, pid, val, NULL); + else + return 1; + } + else { + int (*fn) (CKTcircuit*, GENmodel*, int, IFvalue*); + fn = DEVices[sg->dev]->DEVmodAsk; + pid = DEVices[sg->dev]->DEVpublic.modelParms[sg->param].id; + if (fn) + error = fn(ckt, sg->model, pid, val); + else + return 1; + } - if (error) { - if (sg->is_instparam) - printf("GET ERROR: %s:%s:%s -> param %s (%d)\n", - DEVices[sg->dev]->DEVpublic.name, - sg->model->GENmodName, - sg->instance->GENname, - sg->ptable[sg->param].keyword, pid); - else - printf("GET ERROR: %s:%s:%s -> mparam %s (%d)\n", - DEVices[sg->dev]->DEVpublic.name, - sg->model->GENmodName, - sg->instance->GENname, - sg->ptable[sg->param].keyword, pid); - } + if (error) { + if (sg->is_instparam) + printf("GET ERROR: %s:%s:%s -> param %s (%d)\n", + DEVices[sg->dev]->DEVpublic.name, + sg->model->GENmodName, + sg->instance->GENname, + sg->ptable[sg->param].keyword, pid); + else + printf("GET ERROR: %s:%s:%s -> mparam %s (%d)\n", + DEVices[sg->dev]->DEVpublic.name, + sg->model->GENmodName, + sg->instance->GENname, + sg->ptable[sg->param].keyword, pid); + } - return error; + return error; } /* Get parameter value */ int -sens_setp(sgen *sg, CKTcircuit *ckt, IFvalue *val) +sens_setp(sgen* sg, CKTcircuit* ckt, IFvalue* val) { - int pid; + int pid; - NG_IGNORE(ckt); + NG_IGNORE(ckt); - error = 0; + error = 0; - if (sg->is_instparam) { - int (*fn) (int, IFvalue *, GENinstance *, IFvalue *); - fn = DEVices[sg->dev]->DEVparam; - pid = DEVices[sg->dev]->DEVpublic.instanceParms[sg->param].id; - if (fn) - error = fn (pid, val, sg->instance, NULL); - else - return 1; - } else { - int (*fn) (int, IFvalue *, GENmodel *); - fn = DEVices[sg->dev]->DEVmodParam; - pid = DEVices[sg->dev]->DEVpublic.modelParms[sg->param].id; - if (fn) - error = fn (pid, val, sg->model); - else - return 1; - } + if (sg->is_instparam) { + int (*fn) (int, IFvalue*, GENinstance*, IFvalue*); + fn = DEVices[sg->dev]->DEVparam; + pid = DEVices[sg->dev]->DEVpublic.instanceParms[sg->param].id; + if (fn) + error = fn(pid, val, sg->instance, NULL); + else + return 1; + } + else { + int (*fn) (int, IFvalue*, GENmodel*); + fn = DEVices[sg->dev]->DEVmodParam; + pid = DEVices[sg->dev]->DEVpublic.modelParms[sg->param].id; + if (fn) + error = fn(pid, val, sg->model); + else + return 1; + } - if (error) { - if (sg->is_instparam) - printf("SET ERROR: %s:%s:%s -> param %s (%d)\n", - DEVices[sg->dev]->DEVpublic.name, - sg->model->GENmodName, - sg->instance->GENname, - sg->ptable[sg->param].keyword, pid); - else - printf("SET ERROR: %s:%s:%s -> mparam %s (%d)\n", - DEVices[sg->dev]->DEVpublic.name, - sg->model->GENmodName, - sg->instance->GENname, - sg->ptable[sg->param].keyword, pid); - } + if (error) { + if (sg->is_instparam) + printf("SET ERROR: %s:%s:%s -> param %s (%d)\n", + DEVices[sg->dev]->DEVpublic.name, + sg->model->GENmodName, + sg->instance->GENname, + sg->ptable[sg->param].keyword, pid); + else + printf("SET ERROR: %s:%s:%s -> mparam %s (%d)\n", + DEVices[sg->dev]->DEVpublic.name, + sg->model->GENmodName, + sg->instance->GENname, + sg->ptable[sg->param].keyword, pid); + } - return error; + return error; }