//Functionalized switch sync call -- before link call -- for deltamode functionality void switch_object::BOTH_switch_sync_pre(unsigned char *work_phases_pre, unsigned char *work_phases_post) { //unsigned char work_phases, work_phases_pre, work_phases_post, work_phases_closed; if ((solver_method == SM_NR) && (event_schedule != NULL)) //NR-reliability-related stuff { if (meshed_fault_checking_enabled == false) { //Store our phases going in *work_phases_pre = NR_branchdata[NR_branch_reference].phases & 0x07; //Call syncing function *work_phases_post = switch_expected_sync_function(); //Store our phases going out *work_phases_post &= 0x07; } else //Meshed checking, simplified operations { //Call syncing function switch_sync_function(); } } else //Normal execution { //Call syncing function switch_sync_function(); //Set phases the same *work_phases_pre = 0x00; *work_phases_post = 0x00; } }
//Function to externally set switch status - mainly for "out of step" updates under NR solver //where admittance needs to be updated - this function provides individual switching ability //0 = open, 1 = closed, 2 = don't care (leave as was) void switch_object::set_switch_full(char desired_status_A, char desired_status_B, char desired_status_C) { if (desired_status_A == 0) phase_A_state = OPEN; else if (desired_status_A == 1) phase_A_state = CLOSED; //defaulted else - do nothing, leave it as it is if (desired_status_B == 0) phase_B_state = OPEN; else if (desired_status_B == 1) phase_B_state = CLOSED; //defaulted else - do nothing, leave it as it is if (desired_status_C == 0) phase_C_state = OPEN; else if (desired_status_C == 1) phase_C_state = CLOSED; //defaulted else - do nothing, leave it as it is //Call syncing function (does all that used to occur here) switch_sync_function(); }
TIMESTAMP switch_object::sync(TIMESTAMP t0) { OBJECT *obj = OBJECTHDR(this); TIMESTAMP temp_time; unsigned char work_phases, work_phases_pre, work_phases_post, work_phases_closed; char fault_val[9]; int result_val, impl_fault; bool fault_mode; //Try to map the event_schedule function address, if we haven't tried yet if (event_schedule_map_attempt == false) { //First check to see if a fault_check object even exists if (fault_check_object != NULL) { //It exists, good start! - now see if the proper variable is populated! eventgen_obj = get_object(fault_check_object, "eventgen_object"); //See if it worked - if not, assume it doesn't exist if (*eventgen_obj != NULL) { //It's not null, map up the scheduler function event_schedule = (FUNCTIONADDR)(gl_get_function(*eventgen_obj,"add_event")); //Make sure it was found if (event_schedule == NULL) { gl_warning("Unable to map add_event function in eventgen:%s",*(*eventgen_obj)->name); /* TROUBLESHOOT While attempting to map the "add_event" function from an eventgen object, the function failed to be found. Ensure the target object in fault_check is an eventgen object and this function exists. If the error persists, please submit your code and a bug report via the trac website. */ } } //Defaulted elses - just leave things as is :( } //Defaulted else - doesn't exist, so leave function address empty //Flag the attempt as having occurred event_schedule_map_attempt = true; } //Update time variable if (prev_SW_time != t0) //New timestep prev_SW_time = t0; if ((solver_method == SM_NR) && (event_schedule != NULL)) //NR-reliability-related stuff { //Store our phases going in work_phases_pre = NR_branchdata[NR_branch_reference].phases & 0x07; //Call syncing function work_phases_post = switch_expected_sync_function(); //Store our phases going out work_phases_post &= 0x07; } else //Normal execution { //Call syncing function switch_sync_function(); //Set phases the same work_phases_pre = 0x00; work_phases_post = 0x00; } //Call overlying link sync TIMESTAMP t2=link_object::sync(t0); //See if we're in the proper cycle - NR only for now if ((solver_method == SM_NR) && (work_phases_pre != work_phases_post)) { //Find out what changed work_phases = (work_phases_pre ^ work_phases_post) & 0x07; //See if this transition is a "fault-open" or a "fault-close" work_phases_closed = work_phases & work_phases_post; //See how it looks if (work_phases_closed == work_phases) //It's a close { fault_mode = true; //work_phases = (~work_phases) & 0x07; } else //It's an open { fault_mode = false; //Work phases is already in the proper format } //Set up fault type fault_val[0] = 'S'; fault_val[1] = 'W'; fault_val[2] = '-'; //Default fault - none - will cause a failure if not caught impl_fault = -1; //Determine who opened and store the time switch (work_phases) { case 0x00: //No switches opened !?? GL_THROW("switch:%s supposedly opened, but doesn't register the right phases",obj->name); /* TROUBLESHOOT A switch reported changing to an open status. However, it did not appear to fully propogate this condition. Please try again. If the error persists, please submit your code and a bug report via the trac website. */ break; case 0x01: //Phase C action fault_val[3] = 'C'; fault_val[4] = '\0'; impl_fault = 20; break; case 0x02: //Phase B action fault_val[3] = 'B'; fault_val[4] = '\0'; impl_fault = 19; break; case 0x03: //Phase B and C action fault_val[3] = 'B'; fault_val[4] = 'C'; fault_val[5] = '\0'; impl_fault = 22; break; case 0x04: //Phase A action fault_val[3] = 'A'; fault_val[4] = '\0'; impl_fault = 18; break; case 0x05: //Phase A and C action fault_val[3] = 'A'; fault_val[4] = 'C'; fault_val[5] = '\0'; impl_fault = 23; break; case 0x06: //Phase A and B action fault_val[3] = 'A'; fault_val[4] = 'B'; fault_val[5] = '\0'; impl_fault = 21; break; case 0x07: //All three went fault_val[3] = 'A'; fault_val[4] = 'B'; fault_val[5] = 'C'; fault_val[6] = '\0'; impl_fault = 24; break; default: GL_THROW("switch:%s supposedly opened, but doesn't register the right phases",obj->name); //Defined above }//End switch if (event_schedule != NULL) //Function was mapped - go for it! { //Call the function if (fault_mode == true) //Restoration - make fail time in the past { if (mean_repair_time != 0) temp_time = 50 + (TIMESTAMP)(mean_repair_time); else temp_time = 50; //Call function result_val = ((int (*)(OBJECT *, OBJECT *, char *, TIMESTAMP, TIMESTAMP, int, bool))(*event_schedule))(*eventgen_obj,obj,fault_val,(t0-50),temp_time,impl_fault,fault_mode); } else //Failing - normal { result_val = ((int (*)(OBJECT *, OBJECT *, char *, TIMESTAMP, TIMESTAMP, int, bool))(*event_schedule))(*eventgen_obj,obj,fault_val,t0,TS_NEVER,-1,fault_mode); } //Make sure it worked if (result_val != 1) { GL_THROW("Attempt to change switch:%s failed in a reliability manner",obj->name); /* TROUBLESHOOT While attempting to propagate a changed switch's impacts, an error was encountered. Please try again. If the error persists, please submit your code and a bug report via the trac website. */ } //Ensure we don't go anywhere yet t2 = t0; } //End fault object present else //No object, just fail us out - save the iterations { gl_warning("No fault_check object present - Newton-Raphson solver may fail!"); /* TROUBLESHOOT A switch changed and created an open link. If the system is not meshed, the Newton-Raphson solver will likely fail. Theoretically, this should be a quick fail due to a singular matrix. However, the system occasionally gets stuck and will exhaust iteration cycles before continuing. If the fuse is blowing and the NR solver still iterates for a long time, this may be the case. */ } }//End NR call if (t2==TS_NEVER) return(t2); else return(-t2); //Soft limit it }