bool _parser::has_previous_statement(void) { LOCK_OBJECT(std::recursive_mutex, _parser_lock); return _position > 0; }
size_t _parser::get_statement_position(void) { LOCK_OBJECT(std::recursive_mutex, _parser_lock); return _position; }
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; }
void _parser::reset(void) { LOCK_OBJECT(std::recursive_mutex, _parser_lock); _position = 0; }
void _parser::remove_statement(void) { LOCK_OBJECT(std::recursive_mutex, _parser_lock); remove_statement(_position); }
size_t _parser::size(void) { LOCK_OBJECT(std::recursive_mutex, _parser_lock); return _statement.size() - 2; }
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(); }
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(); }
std::string _parser::statement_to_string( bool verbose ) { LOCK_OBJECT(std::recursive_mutex, _parser_lock); return statement_to_string(_position, verbose); }
void _parser::initialize( const std::string &input, bool is_file ) { LOCK_OBJECT(std::recursive_mutex, _parser_lock); lexer::initialize(input, is_file); clear(); }
void _parser::initialize( const _parser &other ) { LOCK_OBJECT(std::recursive_mutex, _parser_lock); lexer::initialize(other); _position = other._position; _statement = other._statement; }
void _parser::discover(void) { LOCK_OBJECT(std::recursive_mutex, _parser_lock); clear(); while(has_next_statement()) { move_next_statement(); } reset(); }
_parser & _parser::operator=( const _parser &other ) { LOCK_OBJECT(std::recursive_mutex, _parser_lock); if(this != &other) { initialize(other); } return *this; }
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); }
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); } }
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"); } }
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(); }
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(); }
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; }
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); }
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; }
//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 }
//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 }
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; }
//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. */ } }