예제 #1
0
//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;
	}
}
예제 #2
0
//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();
}
예제 #3
0
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
}