📄 cfunc.mod
字号:
/* Retrieve H and B values. */ for (i=0; i<size; i++) { *(H+i) = PARAM(H_array[i]); *(B+i) = PARAM(B_array[i]); } /* See if input_domain is absolute...if so, test against */ /* breakpoint segments for violation of 50% rule... */ if (PARAM(fraction) == MIF_FALSE) { for (i=0; i<(size-1); i++) { if ( (*(H+i+1) - *(H+i)) < (2.0*input_domain) ) { cm_message_send(limit_error); return; } } } /* Retrieve mmf_input value. */ mmf_input = INPUT(mc); /* Calculate H_input value from mmf_input... */ H_input = mmf_input / length; /* Determine segment boundaries within which H_input resides */ if (H_input <= (*(H+1) + *H)/2.0) {/*** H_input below lowest midpoint ***/ dout_din = (*(B+1) - *B)/(*(H+1) - *H); B_out = *B + (H_input - *H) * dout_din; } else { if (H_input >= (*(H+size-2) + *(H+size-1))/2.0) { /*** H_input above highest midpoint ***/ dout_din = (*(B+size-1) - *(B+size-2)) / (*(H+size-1) - *(H+size-2)); B_out = *(B+size-1) + (H_input - *(H+size-1)) * dout_din; } else { /*** H_input within bounds of end midpoints... ***/ /*** must determine position progressively & then ***/ /*** calculate required output. ***/ for (i=1; i<size; i++) { if (H_input < (*(H+i) + *(H+i+1))/2.0) { /* approximate position known... */ lower_seg = (*(H+i) - *(H+i-1)); upper_seg = (*(H+i+1) - *(H+i)); /* Calculate input_domain about this region's breakpoint.*/ if (PARAM(fraction) == MIF_TRUE) { /* Translate input_domain */ /* into an absolute.... */ if ( lower_seg <= upper_seg ) /* Use lower */ /* segment */ /* for % calc.*/ input_domain = input_domain * lower_seg; else /* Use upper */ /* segment */ /* for % calc.*/ input_domain = input_domain * upper_seg; } /* Set up threshold values about breakpoint... */ threshold_lower = *(H+i) - input_domain; threshold_upper = *(H+i) + input_domain; /* Determine where H_input is within region & determine */ /* output and partial values.... */ if (H_input < threshold_lower) { /* Lower linear region */ dout_din = (*(B+i) - *(B+i-1))/lower_seg; B_out = *(B+i) + (H_input - *(H+i)) * dout_din; } else { if (H_input < threshold_upper) { /* Parabolic region */ lower_slope = (*(B+i) - *(B+i-1))/lower_seg; upper_slope = (*(B+i+1) - *(B+i))/upper_seg; cm_smooth_corner(H_input,*(H+i),*(B+i),input_domain, lower_slope,upper_slope,&B_out,&dout_din); } else { /* Upper linear region */ dout_din = (*(B+i+1) - *(B+i))/upper_seg; B_out = *(B+i) + (H_input - *(H+i)) * dout_din; } } break; /* Break search loop...H_input has been found, */ /* and B_out and dout_din have been assigned. */ } } } } /* Calculate value of flux_out... */ flux_out = B_out * area; /* Adjust dout_din value to reflect area and length multipliers... */ dout_din = dout_din * area / length; if(ANALYSIS != MIF_AC) { /* Output DC & Transient Values */ OUTPUT(mc) = flux_out; PARTIAL(mc,mc) = dout_din; } else { /* Output AC Gain */ ac_gain.real = dout_din; ac_gain.imag= 0.0; AC_GAIN(mc,mc) = ac_gain; } } /******** hysteresis mode ******************/ else { /** Retrieve frequently used parameters... **/ in_low = PARAM(in_low); in_high = PARAM(in_high); hyst = PARAM(hyst); out_lower_limit = PARAM(out_lower_limit); out_upper_limit = PARAM(out_upper_limit); input_domain = PARAM(input_domain); /** Calculate Hysteresis Linear Region Slopes & Derived Values **/ /* Define slope of rise and fall lines when not being smoothed */ slope = (out_upper_limit - out_lower_limit)/(in_high - in_low); x_rise_linear = in_low + hyst; /* Breakpoint - x rising to linear region */ x_rise_zero = in_high + hyst; /* Breakpoint - x rising to zero-slope (out_upper_limit) */ x_fall_linear = in_high - hyst; /* Breakpoint - x falling to linear region */ x_fall_zero = in_low - hyst; /* Breakpoint - x falling to zero-slope (out_lower_limit) */ /* Set range to absolute value */ if (PARAM(fraction) == MIF_TRUE) input_domain = input_domain * (in_high - in_low); /** Retrieve frequently used inputs... **/ in = INPUT(mc); /** Test for INIT; if so, allocate storage, otherwise, retrieve previous timepoint value for output... **/ /* First pass...allocate storage for previous state. */ /* Also, calculate roughly where the current output */ /* will be and use this value to define current state. */ if (INIT==1) { hyst_state = cm_analog_alloc(TRUE,sizeof(Boolean_t)); old_hyst_state = cm_analog_get_ptr(TRUE,1); if (in < x_rise_zero + input_domain) { /* Set state to X_RISING */ *old_hyst_state = X_RISING; } else { *old_hyst_state = X_FALLING; } } else { /* Allocation not necessary...retrieve previous values */ hyst_state = cm_analog_get_ptr(TRUE,0); /* Set out pointer to current time storage */ old_hyst_state = cm_analog_get_ptr(TRUE,1); /* Set old-output-state pointer to previous time storage */ } /** Set *hyst_out = *old_hyst_out, unless changed below... we don't need the last iteration value of *hyst_state. **/ *hyst_state = *old_hyst_state; /*** Calculate value of hyst_state, pout_pin.... ***/ if (*old_hyst_state == X_RISING) { /* Assume calculations on lower */ /* hysteresis section (x rising) */ if ( in <= x_rise_linear - input_domain ) { /* Output @ lower limit */ out = out_lower_limit; pout_pin = 0.0; } else { if ( in <= x_rise_linear + input_domain ) { /* lower smoothing region */ cm_smooth_corner(in,x_rise_linear,out_lower_limit,input_domain, 0.0,slope,&out,&pout_pin); } else { if (in <= x_rise_zero - input_domain) { /* Rising linear region */ out = (in - x_rise_linear)*slope + out_lower_limit; pout_pin = slope; } else { if (in <= x_rise_zero + input_domain) { /* Upper smoothing region */ cm_smooth_corner(in,x_rise_zero,out_upper_limit,input_domain, slope,0.0,&out,&pout_pin); } else { /* input has transitioned to X_FALLING region... */ out = out_upper_limit; pout_pin = 0.0; *hyst_state = X_FALLING; } } } } } else { /* Assume calculations on upper hysteresis section (x falling) */ if ( in >= x_fall_linear + input_domain ) { /* Output @ upper limit */ out = out_upper_limit; pout_pin = 0.0; } else { if ( in >= x_fall_linear - input_domain ) { /* Upper smoothing region */ cm_smooth_corner(in,x_fall_linear,out_upper_limit,input_domain, slope,0.0,&out,&pout_pin); } else { if (in >= x_fall_zero + input_domain) { /* Falling linear region */ out = (in - x_fall_zero)*slope + out_lower_limit; pout_pin = slope; } else { if (in >= x_fall_zero - input_domain) { /* Lower smoothing region */ cm_smooth_corner(in,x_fall_zero,out_lower_limit,input_domain, 0.0,slope,&out,&pout_pin); } else { /* input has transitioned to X_RISING region... */ out = out_lower_limit; pout_pin = 0.0; *hyst_state = X_RISING; } } } } } if (ANALYSIS != MIF_AC) { /* DC & Transient Analyses */ OUTPUT(mc) = out; PARTIAL(mc,mc) = pout_pin; } else { /* AC Analysis */ ac_gain.real = pout_pin; ac_gain.imag= 0.0; AC_GAIN(mc,mc) = ac_gain; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -