Beispiel #1
0
bool 
_parser::has_previous_statement(void)
{
	LOCK_OBJECT(std::recursive_mutex, _parser_lock);

	return _position > 0; 
}
Beispiel #2
0
size_t 
_parser::get_statement_position(void)
{
	LOCK_OBJECT(std::recursive_mutex, _parser_lock);

	return _position;
}
Beispiel #3
0
bool 
_parser::has_next_statement(void)
{
	LOCK_OBJECT(std::recursive_mutex, _parser_lock);

	return lexer::get_token(get_statement().front().get_id()).get_type() != TOKEN_END;
}
Beispiel #4
0
void 
_parser::reset(void)
{
	LOCK_OBJECT(std::recursive_mutex, _parser_lock);

	_position = 0;
}
Beispiel #5
0
void 
_parser::remove_statement(void)
{
	LOCK_OBJECT(std::recursive_mutex, _parser_lock);

	remove_statement(_position);
}
Beispiel #6
0
size_t 
_parser::size(void)
{
	LOCK_OBJECT(std::recursive_mutex, _parser_lock);

	return _statement.size() - 2;
}
Beispiel #7
0
std::string 
_parser::statement_to_string(
	size_t position,
	bool verbose
	)
{
	LOCK_OBJECT(std::recursive_mutex, _parser_lock);

	size_t i;
	std::stringstream ss;
	std::queue<node> que;
	std::vector<node> statement = get_statement(position);

	if(!statement.empty()) {
		que.push(statement.front());

		while(!que.empty()) {
			ss << lexer::get_token(que.front().get_id()).to_string(verbose) 
					<< que.front().to_string(false) << std::endl;

			for(i = 0; i < que.front().size(); ++i) {
				que.push(statement.at(que.front().get_child_position(i)));
			}
			que.pop();
		}
	}

	return ss.str();
}
Beispiel #8
0
std::vector<node> &
_parser::move_next_statement(void)
{
	LOCK_OBJECT(std::recursive_mutex, _parser_lock);

	std::vector<node> statement;

	if(!has_next_statement()) {
		THROW_PARSER_EXCEPTION_WITH_MESSAGE(
			PARSER_EXCEPTION_NO_NEXT_STATEMENT,
			"pos. " << _position
			);
	}

	if(has_next_token()
			&& _position == (_statement.size() - 2)) {

		if(lexer::get_token().get_type() == TOKEN_BEGIN) {
			_advance_token();
		}

		if(has_next_token()) {
			_enumerate_statement(statement);
			_statement.insert(_statement.begin() + (++_position), statement);
		} else {
			++_position;
		}
	} else if(_position < (_statement.size() - 1)) {
		++_position;
	}

	return get_statement();
}
Beispiel #9
0
std::string 
_parser::statement_to_string(
	bool verbose
	)
{
	LOCK_OBJECT(std::recursive_mutex, _parser_lock);

	return statement_to_string(_position, verbose);
}
Beispiel #10
0
void 
_parser::initialize(
	const std::string &input,
	bool is_file
	)
{
	LOCK_OBJECT(std::recursive_mutex, _parser_lock);

	lexer::initialize(input, is_file);
	clear();
}
Beispiel #11
0
void 
_parser::initialize(
	const _parser &other
	)
{
	LOCK_OBJECT(std::recursive_mutex, _parser_lock);

	lexer::initialize(other);
	_position = other._position;
	_statement = other._statement;
}
Beispiel #12
0
void 
_parser::discover(void)
{
	LOCK_OBJECT(std::recursive_mutex, _parser_lock);

	clear();

	while(has_next_statement()) {
		move_next_statement();
	}
	reset();
}
Beispiel #13
0
_parser &
_parser::operator=(
	const _parser &other
	)
{
	LOCK_OBJECT(std::recursive_mutex, _parser_lock);

	if(this != &other) {
		initialize(other);
	}

	return *this;
}
Beispiel #14
0
std::vector<node> &
_parser::get_statement(void)
{
	LOCK_OBJECT(std::recursive_mutex, _parser_lock);

	if(_position >= _statement.size()) {
		THROW_PARSER_EXCEPTION_WITH_MESSAGE(
			PARSER_EXCEPTION_INVALID_STATEMENT_POSITION,
			"pos. " << _position
			);
	}

	return _statement.at(_position);
}
Beispiel #15
0
void 
_parser::import_statements(
	std::vector<std::vector<node>> statements
	)
{
	LOCK_OBJECT(std::recursive_mutex, _parser_lock);

	size_t offset = _position;
	std::vector<std::vector<node>>::iterator statement_iter = statements.begin();

	for(; statement_iter != statements.end(); ++statement_iter) {
		_statement.insert(_statement.begin() + (++offset), *statement_iter);
	}
}
Beispiel #16
0
box_t
mts_server_status ()
{
  LOCK_OBJECT (local_rm);
  if (local_rm)
    {
      RELEASE_OBJECT (local_rm);
      return box_dv_short_string ("connected");
    }
  else
    {
      RELEASE_OBJECT (local_rm);
      return box_dv_short_string ("disconnected");
    }
}
Beispiel #17
0
std::vector<node> &
_parser::move_previous_statement(void)
{
	LOCK_OBJECT(std::recursive_mutex, _parser_lock);

	if(!has_previous_statement()) {
		THROW_PARSER_EXCEPTION_WITH_MESSAGE(
			PARSER_EXCEPTION_NO_PREVIOUS_STATEMENT,
			"pos. " << _position
			);
	}
	--_position;
	
	return get_statement();
}
Beispiel #18
0
std::string 
_parser::to_string(
	bool verbose
	)
{
	LOCK_OBJECT(std::recursive_mutex, _parser_lock);

	std::stringstream ss;

	if(verbose) {
		ss << "STATEMENT[" << _position << "]" << std::endl;
	}
	ss << statement_to_string(_position, verbose);

	return ss.str();
}
Beispiel #19
0
void 
_parser::remove_statement(
	size_t position
	)
{
	LOCK_OBJECT(std::recursive_mutex, _parser_lock);

	if(position >= _statement.size()) {
		THROW_PARSER_EXCEPTION_WITH_MESSAGE(
			PARSER_EXCEPTION_INVALID_STATEMENT_POSITION,
			"pos. " << position
			);
	}
	_statement.erase(_statement.begin() + position);
	--_position;
}
Beispiel #20
0
void 
_parser::clear(void)
{
	LOCK_OBJECT(std::recursive_mutex, _parser_lock);

	std::vector<node> begin_stmt, end_stmt;
	node begin_node(lexer::get_begin_token_id()),
		end_node(lexer::get_end_token_id());

	lexer::reset();
	begin_stmt.push_back(begin_node);
	end_stmt.push_back(end_node);
	_position = 0;
	_statement.clear();
	_statement.push_back(begin_stmt);
	_statement.push_back(end_stmt);
}
Beispiel #21
0
std::vector<std::vector<node>> 
_parser::export_statements(void)
{
	LOCK_OBJECT(std::recursive_mutex, _parser_lock);

	token tok;
	std::vector<std::vector<node>> result;
	std::vector<std::vector<node>>::iterator statement_iter = _statement.begin();
	
	for(; statement_iter != _statement.end(); ++statement_iter) {
		tok = get_token(statement_iter->front().get_id());

		if(tok.get_type() == TOKEN_BEGIN
				|| tok.get_type() == TOKEN_END) {
			continue;
		}
		result.push_back(*statement_iter);
	}

	return result;
}
Beispiel #22
0
//Function to perform actual switch sync calls (changes, etc.) - functionalized since essentially used in
//reliability calls as well, so need to make sure the two call points are consistent
void switch_object::switch_sync_function(void)
{
	unsigned char pres_status;
	double phase_total, switch_total;

	pres_status = 0x00;	//Reset individual status indicator - assumes all start open

	if (switch_banked_mode == BANKED_SW)	//Banked mode
	{
		if (status == prev_status)
		{
			//Banked mode is operated by majority rule.  If the majority are a different state, all become that state
			phase_total = (double)(has_phase(PHASE_A) + has_phase(PHASE_B) + has_phase(PHASE_C));	//See how many switches we have

			switch_total = 0.0;
			if (has_phase(PHASE_A) && (phase_A_state == CLOSED))
				switch_total += 1.0;

			if (has_phase(PHASE_B) && (phase_B_state == CLOSED))
				switch_total += 1.0;

			if (has_phase(PHASE_C) && (phase_C_state == CLOSED))
				switch_total += 1.0;

			switch_total /= phase_total;

			if (switch_total > 0.5)	//In two switches, a stalemate occurs.  We'll consider this a "maintain status quo" state
			{
				status = LS_CLOSED;	//If it wasn't here, it is now
				phase_A_state = phase_B_state = phase_C_state = CLOSED;	//Set all to closed - phase checks will sort it out
			}
			else	//Minority or stalemate
			{
				if (switch_total == 0.5)	//Stalemate
				{
					if (status == LS_OPEN)	//These check assume phase_X_state will be manipulated, not status
					{
						phase_A_state = phase_B_state = phase_C_state = OPEN;
					}
					else	//Closed
					{
						phase_A_state = phase_B_state = phase_C_state = CLOSED;
					}
				}
				else	//Not stalemate - open all
				{
					status = LS_OPEN;
					phase_A_state = phase_B_state = phase_C_state = OPEN;	//Set all to open - phase checks will sort it out
				}
			}
		}//End status is same
		else	//Not the same - force the inputs
		{
			if (status==LS_OPEN)
				phase_A_state = phase_B_state = phase_C_state = OPEN;	//Flag all as open
			else
				phase_A_state = phase_B_state = phase_C_state = CLOSED;	//Flag all as closed
		}//End not same

		if (status==LS_OPEN)
		{
			if (has_phase(PHASE_A))
			{
				if (solver_method == SM_NR)
				{
					From_Y[0][0] = complex(0.0,0.0);	//Update admittance
					a_mat[0][0] = 0.0;					//Update the voltage ratio matrix as well (for power calcs)
					d_mat[0][0] = 0.0;	
					NR_branchdata[NR_branch_reference].phases &= 0xFB;	//Remove this bit
				}
				else	//Assume FBS
				{
					A_mat[0][0] = 0.0;
					d_mat[0][0] = 0.0;
				}
			}

			if (has_phase(PHASE_B))
			{
				if (solver_method == SM_NR)
				{
					From_Y[1][1] = complex(0.0,0.0);	//Update admittance
					a_mat[1][1] = 0.0;					//Update the voltage ratio matrix as well (for power calcs)
					d_mat[1][1] = 0.0;	
					NR_branchdata[NR_branch_reference].phases &= 0xFD;	//Remove this bit
				}
				else
				{
					A_mat[1][1] = 0.0;
					d_mat[1][1] = 0.0;
				}
			}

			if (has_phase(PHASE_C))
			{
				if (solver_method == SM_NR)
				{
					From_Y[2][2] = complex(0.0,0.0);	//Update admittance
					a_mat[2][2] = 0.0;					//Update the voltage ratio matrix as well (for power calcs)
					d_mat[2][2] = 0.0;
					NR_branchdata[NR_branch_reference].phases &= 0xFE;	//Remove this bit
				}
				else
				{
					A_mat[2][2] = 0.0;
					d_mat[2][2] = 0.0;
				}
			}
		}//end open
		else					//Must be closed then
		{
			if (has_phase(PHASE_A))
			{
				pres_status |= 0x04;				//Flag as closed

				if (solver_method == SM_NR)
				{
					From_Y[0][0] = complex(1/switch_resistance,1/switch_resistance);	//Update admittance
					a_mat[0][0] = 1.0;					//Update the voltage ratio matrix as well (for power calcs)
					d_mat[0][0] = 1.0;
					NR_branchdata[NR_branch_reference].phases |= 0x04;	//Ensure we're set
				}
				else	//Assumed FBS
				{
					A_mat[0][0] = 1.0;
					d_mat[0][0] = 1.0;
				}
			}

			if (has_phase(PHASE_B))
			{
				pres_status |= 0x02;				//Flag as closed

				if (solver_method == SM_NR)
				{
					From_Y[1][1] = complex(1/switch_resistance,1/switch_resistance);	//Update admittance
					a_mat[1][1] = 1.0;					//Update the voltage ratio matrix as well (for power calcs)
					d_mat[1][1] = 1.0;
					NR_branchdata[NR_branch_reference].phases |= 0x02;	//Ensure we're set
				}
				else
				{
					A_mat[1][1] = 1.0;
					d_mat[1][1] = 1.0;
				}
			}

			if (has_phase(PHASE_C))
			{
				pres_status |= 0x01;				//Flag as closed

				if (solver_method == SM_NR)
				{
					From_Y[2][2] = complex(1/switch_resistance,1/switch_resistance);	//Update admittance
					a_mat[2][2] = 1.0;					//Update the voltage ratio matrix as well (for power calcs)
					d_mat[2][2] = 1.0;
					NR_branchdata[NR_branch_reference].phases |= 0x01;	//Ensure we're set
				}
				else
				{
					A_mat[2][2] = 1.0;
					d_mat[2][2] = 1.0;
				}
			}
		}//end closed
	}//End banked mode
	else	//Individual mode
	{
		if (status == LS_OPEN)	//Fully opened means all go open
		{
			phase_A_state = phase_B_state = phase_C_state = OPEN;	//All open

			if (solver_method == SM_NR)
			{
				From_Y[0][0] = complex(0.0,0.0);
				From_Y[1][1] = complex(0.0,0.0);
				From_Y[2][2] = complex(0.0,0.0);
	
				NR_branchdata[NR_branch_reference].phases &= 0xF0;		//Remove all our phases
			}
			else //Assumed FBS
			{
				A_mat[0][0] = 0.0;
				A_mat[1][1] = 0.0;
				A_mat[2][2] = 0.0;

				d_mat[0][0] = 0.0;
				d_mat[1][1] = 0.0;
				d_mat[2][2] = 0.0;
			}
		}
		else	//Closed means a phase-by-phase basis
		{
			if (has_phase(PHASE_A))
			{
				if (phase_A_state == CLOSED)
				{
					pres_status |= 0x04;

					if (solver_method == SM_NR)
					{
						From_Y[0][0] = complex(1/switch_resistance,1/switch_resistance);
						NR_branchdata[NR_branch_reference].phases |= 0x04;	//Ensure we're set
						a_mat[0][0] = 1.0;
						d_mat[0][0] = 1.0;
					}
					else	//Assumed FBS
					{
						A_mat[0][0] = 1.0;
						d_mat[0][0] = 1.0;
					}
				}
				else	//Must be open
				{
					if (solver_method == SM_NR)
					{
						From_Y[0][0] = complex(0.0,0.0);
						NR_branchdata[NR_branch_reference].phases &= 0xFB;	//Make sure we're removed
						a_mat[0][0] = 0.0;
						d_mat[0][0] = 0.0;
					}
					else
					{
						A_mat[0][0] = 0.0;
						d_mat[0][0] = 0.0;
					}
				}
			}

			if (has_phase(PHASE_B))
			{
				if (phase_B_state == CLOSED)
				{
					pres_status |= 0x02;

					if (solver_method == SM_NR)
					{
						From_Y[1][1] = complex(1/switch_resistance,1/switch_resistance);
						NR_branchdata[NR_branch_reference].phases |= 0x02;	//Ensure we're set
						a_mat[1][1] = 1.0;
						d_mat[1][1] = 1.0;
					}
					else
					{
						A_mat[1][1] = 1.0;
						d_mat[1][1] = 1.0;
					}
				}
				else	//Must be open
				{
					if (solver_method == SM_NR)
					{
						From_Y[1][1] = complex(0.0,0.0);
						NR_branchdata[NR_branch_reference].phases &= 0xFD;	//Make sure we're removed
						a_mat[1][1] = 0.0;
						d_mat[1][1] = 0.0;
					}
					else
					{
						A_mat[1][1] = 0.0;
						d_mat[1][1] = 0.0;
					}
				}
			}

			if (has_phase(PHASE_C))
			{
				if (phase_C_state == CLOSED)
				{
					pres_status |= 0x01;

					if (solver_method == SM_NR)
					{
						From_Y[2][2] = complex(1/switch_resistance,1/switch_resistance);
						NR_branchdata[NR_branch_reference].phases |= 0x01;	//Ensure we're set
						a_mat[2][2] = 1.0;
						d_mat[2][2] = 1.0;
					}
					else
					{
						A_mat[2][2] = 1.0;
						d_mat[2][2] = 1.0;
					}
				}
				else	//Must be open
				{
					if (solver_method == SM_NR)
					{
						From_Y[2][2] = complex(0.0,0.0);
						NR_branchdata[NR_branch_reference].phases &= 0xFE;	//Make sure we're removed
						a_mat[2][2] = 0.0;
						d_mat[2][2] = 0.0;
					}
					else
					{
						A_mat[2][2] = 0.0;
						d_mat[2][2] = 0.0;
					}
				}
			}
		}
	}//end individual mode

	//Check status before running sync (since it will clear it)
	//NR locking
	if (solver_method == SM_NR)
	{
		if ((status != prev_status) || (pres_status != prev_full_status))
		{
			LOCK_OBJECT(NR_swing_bus);	//Lock SWING since we'll be modifying this
			NR_admit_change = true;	//Flag an admittance change
			UNLOCK_OBJECT(NR_swing_bus);	//Finished
		}
	}

	prev_full_status = pres_status;	//Update the status flags
}
Beispiel #23
0
//Function to perform actual fuse sync calls (changes, etc.) - functionalized since essentially used in
//reliability calls as well, so need to make sure the two call points are consistent
void fuse::fuse_sync_function(void)
{
	unsigned char pres_status;

	if (solver_method==SM_NR)	//Newton-Raphson checks
	{
		pres_status = 0x00;	//Reset individual status indicator - assumes all start open

		if (status == LS_OPEN)	//Fully opened means all go open
		{
			From_Y[0][0] = complex(0.0,0.0);
			From_Y[1][1] = complex(0.0,0.0);
			From_Y[2][2] = complex(0.0,0.0);

			phase_A_state = phase_B_state = phase_C_state = BLOWN;	//All open
			NR_branchdata[NR_branch_reference].phases &= 0xF0;		//Remove all our phases
		}
		else	//Closed means a phase-by-phase basis
		{
			if (has_phase(PHASE_A))
			{
				if (phase_A_state == GOOD)
				{
					From_Y[0][0] = complex(1/fuse_resistance,1/fuse_resistance);
					pres_status |= 0x04;
					NR_branchdata[NR_branch_reference].phases |= 0x04;	//Ensure we're set
				}
				else	//Must be open
				{
					From_Y[0][0] = complex(0.0,0.0);
					NR_branchdata[NR_branch_reference].phases &= 0xFB;	//Make sure we're removed
				}
			}

			if (has_phase(PHASE_B))
			{
				if (phase_B_state == GOOD)
				{
					From_Y[1][1] = complex(1/fuse_resistance,1/fuse_resistance);
					pres_status |= 0x02;
					NR_branchdata[NR_branch_reference].phases |= 0x02;	//Ensure we're set
				}
				else	//Must be open
				{
					From_Y[1][1] = complex(0.0,0.0);
					NR_branchdata[NR_branch_reference].phases &= 0xFD;	//Make sure we're removed
				}
			}

			if (has_phase(PHASE_C))
			{
				if (phase_C_state == GOOD)
				{
					From_Y[2][2] = complex(1/fuse_resistance,1/fuse_resistance);
					pres_status |= 0x01;
					NR_branchdata[NR_branch_reference].phases |= 0x01;	//Ensure we're set
				}
				else	//Must be open
				{
					From_Y[2][2] = complex(0.0,0.0);
					NR_branchdata[NR_branch_reference].phases &= 0xFE;	//Make sure we're removed
				}
			}
		}

		//Check status before running sync (since it will clear it)
		if ((status != prev_status) || (pres_status != prev_full_status))
		{
			LOCK_OBJECT(NR_swing_bus);	//Lock SWING since we'll be modifying this
			NR_admit_change = true;	//Flag an admittance change
			UNLOCK_OBJECT(NR_swing_bus);	//Finished
		}

		prev_full_status = pres_status;	//Update the status flags
	}//end SM_NR
}
Beispiel #24
0
TIMESTAMP house::sync_panel(TIMESTAMP t0, TIMESTAMP t1)
{
	TIMESTAMP sync_time = TS_NEVER;
	OBJECT *obj = OBJECTHDR(this);

	// clear accumulators for panel currents
	complex I[3]; I[X12] = I[X23] = I[X13] = complex(0,0);

	// clear heatgain accumulator
	double heatgain = 0;

	// gather load power and compute current for each circuit
	CIRCUIT *c;
	for (c=panel.circuits; c!=NULL; c=c->next)
	{
		// get circuit type
		int n = (int)c->type;
		if (n<0 || n>2)
			GL_THROW("%s:%d circuit %d has an invalid circuit type (%d)", obj->oclass->name, obj->id, c->id, (int)c->type);
		/*	TROUBLESHOOT
			Invalid circuit types are an internal error for the house panel.  Please report this error.  The likely causes
			include an object that is not a house is being processed by the house model, or the panel was not correctly
			initialized.
		*/

		// if breaker is open and reclose time has arrived
		if (c->status==BRK_OPEN && t1>=c->reclose)
		{
			c->status = BRK_CLOSED;
			c->reclose = TS_NEVER;
			sync_time = t1; // must immediately reevaluate devices affected
			gl_debug("house:%d panel breaker %d closed", obj->id, c->id);
		}

		// if breaker is closed
		if (c->status==BRK_CLOSED)
		{
			// compute circuit current
			if ((c->pV)->Mag() == 0)
			{
				gl_debug("house:%d circuit %d (enduse %s) voltage is zero", obj->id, c->id, c->pLoad->name);
				break;
			}
			
			complex current = ~(c->pLoad->total*1000 / *(c->pV)); 

			// check breaker
			if (c->max_amps>0 && current.Mag()>c->max_amps)
			{
				// probability of breaker failure increases over time
				if (c->tripsleft>0 && gl_random_bernoulli(RNGSTATE,1/(c->tripsleft--))==0)
				{
					// breaker opens
					c->status = BRK_OPEN;

					// average five minutes before reclosing, exponentially distributed
					c->reclose = t1 + (TIMESTAMP)(gl_random_exponential(RNGSTATE,1/300.0)*TS_SECOND); 
					gl_debug("house:%d circuit breaker %d tripped - enduse %s overload at %.0f A", obj->id, c->id,
						c->pLoad->name, current.Mag());
				}

				// breaker fails from too frequent operation
				else
				{
					c->status = BRK_FAULT;
					c->reclose = TS_NEVER;
					gl_debug("house:%d circuit breaker %d failed", obj->id, c->id);
				}

				// must immediately reevaluate everything
				sync_time = t1; 
			}

			// add to panel current
			else
			{
				tload.power += c->pLoad->power;	// reminder: |a| + |b| != |a+b|
				tload.current += c->pLoad->current;
				tload.admittance += c->pLoad->admittance; // should this be additive? I don't buy t.a = c->pL->a ... -MH
				tload.total += c->pLoad->total;
				tload.heatgain += c->pLoad->heatgain;
				tload.energy += c->pLoad->power * gl_tohours(t1-t0);
				I[n] += current;
				c->reclose = TS_NEVER;
			}
		}

		// sync time
		if (sync_time > c->reclose)
			sync_time = c->reclose;
	}

	// compute line currents and post to meter
	if (obj->parent != NULL)
		LOCK_OBJECT(obj->parent);

	pLine_I[0] = I[X13];
	pLine_I[1] = I[X23];
	pLine_I[2] = 0;
	*pLine12 = I[X12];

	if (obj->parent != NULL)
		UNLOCK_OBJECT(obj->parent);

	return sync_time;
}
Beispiel #25
0
//Function to externally set switch status - mainly for "out of step" updates under NR solver
//where admittance needs to be updated
void switch_object::set_switch(bool desired_status)
{
	status = desired_status;	//Change the status
	//Check solver method - Only works for NR right now
	if (solver_method == SM_NR)
	{
		if (status != prev_status)	//Something's changed
		{
			//Copied from sync
			if (status==LS_OPEN)
			{
				if (has_phase(PHASE_A))
				{
					From_Y[0][0] = complex(0.0,0.0);	//Update admittance
					a_mat[0][0] = 0.0;					//Update the voltage ratio matrix as well (for power calcs)
					d_mat[0][0] = 0.0;
					NR_branchdata[NR_branch_reference].phases &= 0xFB;	//Ensure we're not set
					phase_A_state = OPEN;				//Open this phase
				}

				if (has_phase(PHASE_B))
				{
					From_Y[1][1] = complex(0.0,0.0);	//Update admittance
					a_mat[1][1] = 0.0;					//Update the voltage ratio matrix as well (for power calcs)
					d_mat[1][1] = 0.0;
					NR_branchdata[NR_branch_reference].phases &= 0xFD;	//Ensure we're not set
					phase_B_state = OPEN;				//Open this phase
				}

				if (has_phase(PHASE_C))
				{
					From_Y[2][2] = complex(0.0,0.0);	//Update admittance
					a_mat[2][2] = 0.0;					//Update the voltage ratio matrix as well (for power calcs)
					d_mat[2][2] = 0.0;
					NR_branchdata[NR_branch_reference].phases &= 0xFE;	//Ensure we're not set
					phase_C_state = OPEN;				//Open this phase
				}
			}//end open
			else					//Must be closed then
			{
				if (has_phase(PHASE_A))
				{
					From_Y[0][0] = complex(1/switch_resistance,1/switch_resistance);	//Update admittance
					a_mat[0][0] = 1.0;					//Update the voltage ratio matrix as well (for power calcs)
					d_mat[0][0] = 1.0;
					NR_branchdata[NR_branch_reference].phases |= 0x04;	//Ensure we're set
					phase_A_state = CLOSED;				//Close this phase
				}

				if (has_phase(PHASE_B))
				{
					From_Y[1][1] = complex(1/switch_resistance,1/switch_resistance);	//Update admittance
					a_mat[1][1] = 1.0;					//Update the voltage ratio matrix as well (for power calcs)
					d_mat[1][1] = 1.0;
					NR_branchdata[NR_branch_reference].phases |= 0x02;	//Ensure we're set
					phase_B_state = CLOSED;				//Close this phase
				}

				if (has_phase(PHASE_C))
				{
					From_Y[2][2] = complex(1/switch_resistance,1/switch_resistance);	//Update admittance
					a_mat[2][2] = 1.0;					//Update the voltage ratio matrix as well (for power calcs)
					d_mat[2][2] = 1.0;
					NR_branchdata[NR_branch_reference].phases |= 0x01;	//Ensure we're set
					phase_C_state = CLOSED;				//Close this phase
				}
			}//end closed

			//Lock the swing first
			LOCK_OBJECT(NR_swing_bus);

			//Flag an update
			NR_admit_change = true;	//Flag an admittance change

			//Unlock swing
			UNLOCK_OBJECT(NR_swing_bus);

			//Update prev_status
			prev_status = status;
		}
		//defaulted else - no change, so nothing needs to be done
	}
	else
	{
		gl_warning("Switch status updated, but no other changes made.");
		/*  TROUBLESHOOT
		When changed under solver methods other than NR, only the switch status
		is changed.  The solver handles other details in a specific step, so no
		other changes are performed.
		*/
	}
}