📄 mifload.c
字号:
cntl_src_type = MIFget_cntl_src_type(in_type, out_type); switch(cntl_src_type) { case MIF_VCVS: if(anal_type == MIF_AC) { *(smp_ptr->e.branch_poscntl) -= ac_gain.real; *(smp_ptr->e.branch_negcntl) += ac_gain.real; *(smp_ptr->e.branch_poscntl+1) -= ac_gain.imag; *(smp_ptr->e.branch_negcntl+1) += ac_gain.imag; } else { *(smp_ptr->e.branch_poscntl) -= partial; *(smp_ptr->e.branch_negcntl) += partial; rhs[smp_data_out->branch] -= partial * cntl_input; } break; case MIF_ICIS: if(anal_type == MIF_AC) { *(smp_ptr->f.pos_ibranchcntl) += ac_gain.real; *(smp_ptr->f.neg_ibranchcntl) -= ac_gain.real; *(smp_ptr->f.pos_ibranchcntl+1) += ac_gain.imag; *(smp_ptr->f.neg_ibranchcntl+1) -= ac_gain.imag; } else { *(smp_ptr->f.pos_ibranchcntl) += partial; *(smp_ptr->f.neg_ibranchcntl) -= partial; temp = partial * cntl_input; rhs[smp_data_out->pos_node] += temp; rhs[smp_data_out->neg_node] -= temp; } break; case MIF_VCIS: if(anal_type == MIF_AC) { *(smp_ptr->g.pos_poscntl) += ac_gain.real; *(smp_ptr->g.pos_negcntl) -= ac_gain.real; *(smp_ptr->g.neg_poscntl) -= ac_gain.real; *(smp_ptr->g.neg_negcntl) += ac_gain.real; *(smp_ptr->g.pos_poscntl+1) += ac_gain.imag; *(smp_ptr->g.pos_negcntl+1) -= ac_gain.imag; *(smp_ptr->g.neg_poscntl+1) -= ac_gain.imag; *(smp_ptr->g.neg_negcntl+1) += ac_gain.imag; } else { *(smp_ptr->g.pos_poscntl) += partial; *(smp_ptr->g.pos_negcntl) -= partial; *(smp_ptr->g.neg_poscntl) -= partial; *(smp_ptr->g.neg_negcntl) += partial; temp = partial * cntl_input; rhs[smp_data_out->pos_node] += temp; rhs[smp_data_out->neg_node] -= temp; } break; case MIF_ICVS: if(anal_type == MIF_AC) { *(smp_ptr->h.branch_ibranchcntl) -= ac_gain.real; *(smp_ptr->h.branch_ibranchcntl+1) -= ac_gain.imag; } else { *(smp_ptr->h.branch_ibranchcntl) -= partial; rhs[smp_data_out->branch] -= partial * cntl_input; } break; } /* end switch on controlled source type */ } /* end for number of input ports */ } /* end for number of input connections */ } /* end for number of output ports */ } /* end for number of output connections */ here->initialized = MIF_TRUE; } /* end for all instances */ } /* end for all models */ return(OK);}/*MIFauto_partialThis function is called by MIFload() when a code model requeststhat partial derivatives be computed automatically. It callsthe code model additional times with an individual input to themodel varied by a small amount at each call. Partialderivatives of each output with respect to the varied inputare then computed by divided differences.*/static void MIFauto_partial( MIFinstance *here, /* The instance structure */ void (*cm_func)(), /* The code model function to be called */ Mif_Private_t *cm_data) /* The data to be passed to the code model */{ Mif_Port_Data_t *fast; Mif_Port_Data_t *out_fast; Mif_Port_Type_t type; Mif_Port_Type_t out_type; int num_conn; int num_port; int num_port_k; int i; int j; int k; int l; double epsilon; double nominal_input; /* Reset init and anal_init flags before making additional calls */ /* to the model */ cm_data->circuit.init = MIF_FALSE; g_mif_info.circuit.init = MIF_FALSE; cm_data->circuit.anal_init = MIF_FALSE; g_mif_info.circuit.anal_init = MIF_FALSE; /* *************************** */ /* Save nominal analog outputs */ /* *************************** */ /* loop through all connections */ num_conn = here->num_conn; for(i = 0; i < num_conn; i++) { /* if the connection is null or is not an output */ /* skip to next connection */ if(here->conn[i]->is_null || (! here->conn[i]->is_output)) continue; /* loop through all ports on this connection */ num_port = here->conn[i]->size; for(j = 0; j < num_port; j++) { /*setup a pointer for fast access to port data */ fast = here->conn[i]->port[j]; /* skip if this port is null */ if(fast->is_null) continue; /* determine the type of this port */ type = fast->type; /* If not an analog port, continue to next port */ if((type == MIF_DIGITAL) || (type == MIF_USER_DEFINED)) continue; /* copy the output for use in computing output deltas */ fast->nominal_output = fast->output.rvalue; } /* end for number of output ports */ } /* end for number of output connections */ /* ***************************************************************** */ /* Change each analog input by a small amount and call the model to */ /* compute new outputs. */ /* ***************************************************************** */ /* loop through all connections */ num_conn = here->num_conn; for(i = 0; i < num_conn; i++) { /* if the connection is null, skip to next connection */ if(here->conn[i]->is_null) continue; /* if this connection is not an input, skip to next connection */ if(! here->conn[i]->is_input) continue; /* Get number of ports on this connection */ num_port = here->conn[i]->size; /* loop through all ports on this connection */ for(j = 0; j < num_port; j++) { /*setup a pointer for fast access to port data */ fast = here->conn[i]->port[j]; /* skip if this port is null */ if(fast->is_null) continue; /* determine the type of this port */ type = fast->type; /* If port type is Digital or User-Defined, skip it */ if((type == MIF_DIGITAL) || (type == MIF_USER_DEFINED)) continue; /* otherwise, it is an analog port and we need to perturb it and */ /* then call the model */ /* compute the perturbation amount depending on type of input */ switch(type) { case MIF_VOLTAGE: case MIF_DIFF_VOLTAGE: case MIF_CONDUCTANCE: case MIF_DIFF_CONDUCTANCE: epsilon = 1.0e-6; break; case MIF_CURRENT: case MIF_DIFF_CURRENT: case MIF_VSOURCE_CURRENT: case MIF_RESISTANCE: case MIF_DIFF_RESISTANCE: epsilon = 1.0e-12; break; default: printf("INTERNAL ERROR - MIFauto_partial. Invalid port type\n"); epsilon = 1.0e-30; break; } /* end switch on type of port */ /* record and perturb input value */ nominal_input = fast->input.rvalue; fast->input.rvalue += epsilon; /* call model to compute new outputs */ (*cm_func)(cm_data); /* ******************************************************* */ /* Compute the partials of each output with respect to the */ /* perturbed input by divided differences. */ /* ******************************************************* */ /* loop through all analog output connections */ for(k = 0; k < num_conn; k++) { /* if the connection is null or is not an output */ /* skip to next connection */ if((here->conn[k]->is_null) || (! here->conn[k]->is_output)) continue; /* loop through all the ports of this connection */ num_port_k = here->conn[k]->size; for(l = 0; l < num_port_k; l++) { /*setup a pointer for out_fast access to port data */ out_fast = here->conn[k]->port[l]; /* skip if this port is null */ if(out_fast->is_null) continue; /* determine the out_type of this port */ out_type = out_fast->type; /* If port type is Digital or User-Defined, skip it */ if((out_type == MIF_DIGITAL) || (out_type == MIF_USER_DEFINED)) continue; /* compute partial by divided differences */ out_fast->partial[i].port[j] = (out_fast->output.rvalue - out_fast->nominal_output) / epsilon; /* zero the output in preparation for next call */ out_fast->output.rvalue = 0.0; } /* end for number of output ports */ } /* end for number of output connections */ /* restore nominal input value */ fast->input.rvalue = nominal_input; } /* end for number of input ports */ } /* end for number of input connections */ /* *************************************************** */ /* Call model one last time to recompute nominal case. */ /* *************************************************** */ /* This is needed even though the outputs are recorded, because */ /* the model may compute other state values that cannot be restored */ /* to the nominal condition from here */ (*cm_func)(cm_data);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -