Ejemplo n.º 1
0
// Initialize a distribution meter, return 1 on success
int meter::init(OBJECT *parent)
{
	if(power_market != 0){
		price_prop = gl_get_property(power_market, "current_market.clearing_price");
		if(price_prop == 0){
			GL_THROW("meter::power_market object \'%s\' does not publish \'current_market.clearing_price\'", (power_market->name ? power_market->name : "(anon)"));
		}
	}

	// Count the number of phases...for use with meter_power_consumption
	if (meter_power_consumption != complex(0,0))
	{
		no_phases = 0;
		if (has_phase(PHASE_A))
			no_phases += 1;
		if (has_phase(PHASE_B))
			no_phases += 1;
		if (has_phase(PHASE_C))
			no_phases += 1;
	}

	check_prices();
	last_t = dt = 0;
	return node::init(parent);
}
Ejemplo n.º 2
0
TIMESTAMP meter::sync(TIMESTAMP t0)
{
	//Luca Meschiari Test- Start
		//printf("meter sync   |||   ");
	//Luca Meschiari Test- End
	
	// Luca Meschiari Test - Start
		//printf("--- %f ---", proj_power);
	// Luca Meschiari Test - Start

	int TempNodeRef;

	//Reliability check
	if ((NR_mode == false) && (fault_check_object != NULL) && (solver_method == SM_NR))	//solver cycle and fault_check is present (so might need to set flag
	{
		if (NR_node_reference==-99)	//Childed
		{
			TempNodeRef=*NR_subnode_reference;
		}
		else	//Normal
		{
			//Just assign it to our normal index
			TempNodeRef=NR_node_reference;
		}

		if ((NR_busdata[TempNodeRef].origphases & NR_busdata[TempNodeRef].phases) != NR_busdata[TempNodeRef].origphases)	//We have a phase mismatch - something has been lost
		{
			meter_interrupted = true;	//Someone is out of service, they just may not know it

			//See if we're flagged for a momentary as well - if we are, clear it
			if (meter_interrupted_secondary == true)
				meter_interrupted_secondary = false;
		}
		else
		{
			meter_interrupted = false;	//All is well
		}
	}

	if (meter_power_consumption != complex(0,0))
	{
		if (has_phase(PHASE_A))
			power[0] += meter_power_consumption / no_phases;
		if (has_phase(PHASE_B))
			power[1] += meter_power_consumption / no_phases;
		if (has_phase(PHASE_C))
			power[2] += meter_power_consumption / no_phases;
	}

	return node::sync(t0);
}
Ejemplo n.º 3
0
int relay::init(OBJECT *parent)
{
	int result = link::init(parent);

	if (recloser_limit == 0)
	{
		recloser_limit = 5;
		gl_warning("Recloser:%d tries limit was not specified, defaulted to 5 tries",OBJECTHDR(this)->id);
		/*  TROUBLESHOOT
		The recloser did not have a specified value for the maximum number of recloser tries.  5 was selected as a default value. 
		*/
	}

	if (recloser_delay == 0)
	{
		recloser_delay = 3;
		gl_warning("Recloser:%d reclose delay was not specified, defaulted to 3 seconds",OBJECTHDR(this)->id);
		/*  TROUBLESHOOT
		The recloser did not have a specified value for the recloser try delay.  3 was selected as a default value. 
		*/
	}

	if (recloser_delay<1.0)
	{
		GL_THROW("recloser delay must be at least 1 second");
		/*  TROUBLESHOOT
		The recloser delay must be at least one second long.  Please set the value of
		recloser_delay to something greater than or equal to 1.0.
		*/
	}
	
	a_mat[0][0] = d_mat[0][0] = A_mat[0][0] = (link::is_closed() && has_phase(PHASE_A) ? 1.0 : 0.0);
	a_mat[1][1] = d_mat[1][1] = A_mat[1][1] = (link::is_closed() && has_phase(PHASE_B) ? 1.0 : 0.0);
	a_mat[2][2] = d_mat[2][2] = A_mat[2][2] = (link::is_closed() && has_phase(PHASE_C) ? 1.0 : 0.0);

	b_mat[0][0] = c_mat[0][0] = B_mat[0][0] = 0.0;
	b_mat[1][1] = c_mat[1][1] = B_mat[1][1] = 0.0;
	b_mat[2][2] = c_mat[2][2] = B_mat[2][2] = 0.0;

	return result;
}
Ejemplo n.º 4
0
//Functionalized portion for deltamode compatibility
void meter::BOTH_meter_sync_fxn()
{
	int TempNodeRef;

	//Reliability check
	if ((fault_check_object != NULL) && (solver_method == SM_NR))	//proper solver and fault_object isn't null - may need to set a flag
	{
		if (NR_node_reference==-99)	//Childed
		{
			TempNodeRef=*NR_subnode_reference;
		}
		else	//Normal
		{
			//Just assign it to our normal index
			TempNodeRef=NR_node_reference;
		}

		if ((NR_busdata[TempNodeRef].origphases & NR_busdata[TempNodeRef].phases) != NR_busdata[TempNodeRef].origphases)	//We have a phase mismatch - something has been lost
		{
			meter_interrupted = true;	//Someone is out of service, they just may not know it

			//See if we're flagged for a momentary as well - if we are, clear it
			if (meter_interrupted_secondary == true)
				meter_interrupted_secondary = false;
		}
		else
		{
			meter_interrupted = false;	//All is well
		}
	}

	if (meter_power_consumption != complex(0,0))
	{
		if (has_phase(PHASE_A))
			power[0] += meter_power_consumption / no_phases;
		if (has_phase(PHASE_B))
			power[1] += meter_power_consumption / no_phases;
		if (has_phase(PHASE_C))
			power[2] += meter_power_consumption / no_phases;
	}
}
int triplex_node::init(OBJECT *parent)
{
	if ( !(has_phase(PHASE_S)) )
	{
		OBJECT *obj = OBJECTHDR(this);
		gl_warning("Init() triplex_node (name:%s, id:%d): Phases specified did not include phase S. Adding phase S.", obj->name,obj->id);
		/* TROUBLESHOOT
		Triplex nodes and meters require a single phase and a phase S component (for split-phase).
		This particular triplex object did not include it, so it is being added.
		*/
		phases = (phases | PHASE_S);
	}
	if ((pub_shunt[0] == 0) && (impedance[0] != 0))
		shunt[0] = complex(1.0,0)/impedance[0];

	if ((pub_shunt[1] == 0) && (impedance[1] != 0))
		shunt[1] = complex(1.0,0)/impedance[1];

	if ((pub_shunt[2] == 0) && (impedance[2] != 0))
		shunt[2] = complex(1.0,0)/impedance[2];

	return node::init(parent);
}
Ejemplo n.º 6
0
int powerflow_object::init(OBJECT *parent)
{
	/* unspecified phase inherits from parent, if any */
	if (parent && gl_object_isa(parent,"powerflow_object"))
	{
		powerflow_object *pParent = OBJECTDATA(parent,powerflow_object);
		if (phases==NO_PHASE)
			phases = pParent->phases;
	}

	/* no phase info */
	if (phases==0)
		throw "phases not specified";

	/* split connection must connect to a phase */
	if (has_phase(PHASE_S) && !(has_phase(PHASE_A) || has_phase(PHASE_B) || has_phase(PHASE_C)))
		throw "split connection is missing A,B, or C phase connection";

	/* split connection must connect to only one phase */
	if (has_phase(PHASE_S) && (
		(has_phase(PHASE_A) && has_phase(PHASE_B)) ||
		(has_phase(PHASE_B) && has_phase(PHASE_C)) ||
		(has_phase(PHASE_C) && has_phase(PHASE_A))))
		throw "split connection is connected to two phases simultaneously";

	/* split connection is not permitted with delta connection */
	if (has_phase(PHASE_S) && has_phase(PHASE_D))
		throw "split and delta connection cannot occur simultaneously";

	/* split connection is not permitted on neutral */
	if (has_phase(PHASE_N) && has_phase(PHASE_S)) 
	{
		gl_warning("neutral phase ignored on split connection.");
		phases ^= PHASE_N;
	}

	return 1;
}
Ejemplo n.º 7
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
}
Ejemplo n.º 8
0
/**
* Object initialization is called once after all object have been created
*
* @param parent a pointer to this object's parent
* @return 1 on success, 0 on error
*/
int fuse::init(OBJECT *parent)
{
	char jindex, kindex;
	OBJECT *obj = OBJECTHDR(this);

	if ((phases & PHASE_S) == PHASE_S)
	{
		GL_THROW("fuses cannot be placed on triplex circuits");
		/*  TROUBLESHOOT
		Fuses do not currently support triplex circuits.  Please place the fuse higher upstream in the three-phase power
		area or utilize another object (such as a circuit breaker in a house model) to limit the current flow.
		*/
	}

	//Special flag moved to be universal for all solvers - mainly so phase checks catch it now
	SpecialLnk = SWITCH;

	int result = link_object::init(parent);

	//Check current limit
	if (current_limit < 0.0)
	{
		GL_THROW("fuse:%s has a negative current limit value!",obj->name);
		/*  TROUBLESHOOT
		The fuse has a negative value current limit specified.  Please specify a positive
		value for the current and try again.
		*/
	}

	if (current_limit == 0.0)
	{
		current_limit = 9999.0;	//Set to arbitrary large value

		gl_warning("fuse:%s has a zero current limit - set to 9999.9 Amps",obj->name);
		/*  TROUBLESHOOT
		A fuse somehow had a current limit of 0.0 Amps set.  This is invalid, so a placeholder
		value of 9999.0 Amps is used.  Please adjust this value accordingly.
		*/
	}

	if (mean_replacement_time<=0.0)	//Make sure the time makes sense
	{
		gl_warning("Fuse:%s has a negative or 0 mean replacement time - defaulting to 1 hour",obj->name);
		/*  TROUBLESHOOT
		A fuse has a negative or zero time specified for mean_replacement_time.  The value has therefore been
		overridden to 1 hour.  If this is unacceptable, please change the value in your GLM file.
		*/
		mean_replacement_time = 3600.0;
	}

	//Set mean_repair_time to the same value
	mean_repair_time = mean_replacement_time;

	if (solver_method==SM_FBS)
	{
		gl_warning("Fuses only work for the attached node in the FBS solver, not any deeper.");
		/*  TROUBLESHOOT
		Under the Forward-Back sweep method, fuses can only affect their directly attached downstream node.
		Due to the nature of the FBS algorithm, nodes further downstream (especially constant current loads)
		will cause an oscillatory nature in the voltage and current injections, so they will no longer be accurate.
		Either ignore these values or figure out a way to work around this limitation (player objects).
		*/
	}
	//check the fuse resistance value to see that it is not zero
	if (solver_method == SM_NR){
		if(fuse_resistance == 0.0){
			gl_warning("Fuse:%s fuse_resistance has been set to zero. This will result singular matrix. Setting to the global default.",obj->name);
			/*  TROUBLESHOOT
			Under Newton-Raphson solution method the impedance matrix cannot be a singular matrix for the inversion process.
			Change the value of fuse_resistance to something small but larger that zero.
			*/
		}
		if(fuse_resistance < 0.0){
			fuse_resistance = default_resistance;
		}
	}

	//Initialize matrices
	for (jindex=0;jindex<3;jindex++)
	{
		for (kindex=0;kindex<3;kindex++)
		{
			a_mat[jindex][kindex] = d_mat[jindex][kindex] = A_mat[jindex][kindex] = 0.0;
			c_mat[jindex][kindex] = 0.0;
			B_mat[jindex][kindex] = b_mat[jindex][kindex] = 0.0;
		}
	}

	a_mat[0][0] = d_mat[0][0] = A_mat[0][0] = (is_closed() && has_phase(PHASE_A) ? 1.0 : 0.0);
	a_mat[1][1] = d_mat[1][1] = A_mat[1][1] = (is_closed() && has_phase(PHASE_B) ? 1.0 : 0.0);
	a_mat[2][2] = d_mat[2][2] = A_mat[2][2] = (is_closed() && has_phase(PHASE_C) ? 1.0 : 0.0);

	if (solver_method==SM_FBS)
	{
		b_mat[0][0] = c_mat[0][0] = B_mat[0][0] = 0.0;
		b_mat[1][1] = c_mat[1][1] = B_mat[1][1] = 0.0;
		b_mat[2][2] = c_mat[2][2] = B_mat[2][2] = 0.0;
	}
	else if (solver_method==SM_NR)
	{
		//Flagged it as special (we'll forgo inversion processes on this)

		//Initialize off-diagonals just in case
		From_Y[0][1] = From_Y[0][2] = From_Y[1][0] = 0.0;
		From_Y[1][2] = From_Y[2][0] = From_Y[2][1] = 0.0;


		if (status==LS_OPEN)	//Take this as all should be 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
			prev_full_status = 0x00;								//Confirm here
		}
		else	//LS_CLOSED - handle individually
		{
			if (has_phase(PHASE_A))
			{
				if (phase_A_state == GOOD)
				{
					From_Y[0][0] = complex(1/fuse_resistance,1/fuse_resistance);
					prev_full_status |= 0x04;
				}
				else	//Must be open
				{
					From_Y[0][0] = complex(0.0,0.0);
					prev_full_status &=0xFB;
				}
			}

			if (has_phase(PHASE_B))
			{
				if (phase_B_state == GOOD)
				{
					From_Y[1][1] = complex(1/fuse_resistance,1/fuse_resistance);
					prev_full_status |= 0x02;
				}
				else	//Must be open
				{
					From_Y[1][1] = complex(0.0,0.0);
					prev_full_status &=0xFD;
				}
			}

			if (has_phase(PHASE_C))
			{
				if (phase_C_state == GOOD)
				{
					From_Y[2][2] = complex(1/fuse_resistance,1/fuse_resistance);
					prev_full_status |= 0x01;
				}
				else	//Must be open
				{
					From_Y[2][2] = complex(0.0,0.0);
					prev_full_status &=0xFE;
				}
			}
		}
	}
	else
	{
		GL_THROW("Fuses are not supported by this solver method");
		/*  TROUBLESHOOT
		Fuses are currently only supported in Forward-Back Sweep and
		Newton-Raphson Solvers.  Using them in other solvers is
		untested and may provide erroneous answers (if any at all).
		*/
	}

	//Store fuse status - will get updated as things change later
	phased_fuse_status = prev_full_status;

	return result;
}
Ejemplo n.º 9
0
static int gravity_check_input( const ecl_grid_type * ecl_grid , 
                                const ecl_file_type * init_file , 
                                const ecl_file_type * restart_file1, 
                                const ecl_file_type * restart_file2,
                                int   * __model_phases,
                                int   * __file_phases) {
  {
    int model_phases = 0;
    int file_phases  = 0;

    /* Check which phases are present in the model */
    if (ecl_file_has_kw(restart_file1 , "OIL_DEN")) {
      model_phases += OIL;  
      simulator = ECLIPSE100 ;
    } else if (ecl_file_has_kw(restart_file1 , "DENO")) {
      model_phases += OIL;  
      simulator = ECLIPSE300 ;
    } ;
      
    if (ecl_file_has_kw(restart_file1 , "WAT_DEN")) {
      model_phases += WATER;                         
      simulator = ECLIPSE100 ;
    } else if (ecl_file_has_kw(restart_file1 , "DENW")) {
      model_phases += WATER;                         
      simulator = ECLIPSE300 ;
    } ;
    
    if (ecl_file_has_kw(restart_file1 , "GAS_DEN")) {
      model_phases += GAS;
      simulator = ECLIPSE100 ;
    } else if (ecl_file_has_kw(restart_file1 , "DENG")) {
      model_phases += GAS;
      simulator = ECLIPSE300 ;
    } ;
    
    
    /* Check which phases are present in the restart files. We assume the restart file NEVER has SOIL information */
    if (ecl_file_has_kw(restart_file1 , "SWAT"))
      file_phases += WATER;
    if (ecl_file_has_kw(restart_file1 , "SGAS"))
      file_phases += GAS;
    
    
    /* Consiency check */
    {
      /**
         The following assumptions are made:
         
         1. All restart files should have water, i.e. the SWAT keyword. 
         2. All phases present in the restart file should also be present as densities, 
            in addition the model must contain one additional phase. 
         3. The restart files can never contain oil saturation.
         
      */
      if ( !has_phase( file_phases , WATER ) )
        util_exit("Could not locate SWAT keyword in restart files\n");
      
      if ( has_phase( file_phases , OIL ))
        util_exit("Can not handle restart files with SOIL keyword\n"); 
      
      if (! has_phase( model_phases , WATER ) )
        util_exit("Could not locate WAT_DEN keyword in restart files\n");      
      
      if ( has_phase( file_phases , GAS )) {
        /** Restart file has both water and gas - means we need all three densities. */
        if (! (has_phase( model_phases , GAS) && has_phase( model_phases , OIL)))
          util_exit("Could not find GAS_DEN and OIL_DEN keywords in restart files\n");
      } else {
        /* This is (water + oil) or (water + gas) system. We enforce one of the densities.*/
        if ( !has_phase( model_phases , GAS + OIL))
          util_exit("Could not find either GAS_DEN or OIL_DEN kewyords in restart files\n");
      }
    }
    *__model_phases = model_phases;
    *__file_phases  = file_phases;
  }
  
  /* Check that the restart files have RPORV information. This is ensured by giving the argument RPORV to the RPTRST keyword. */
  if ( !(ecl_file_has_kw( restart_file1 , "RPORV") && ecl_file_has_kw( restart_file2 , "RPORV")) )
    util_exit("Sorry: the restartfiles do  not contain RPORV\n");       


  /**
     Check that the rporv values are in the right ballpark.  For
     ECLIPSE version 2008.2 they are way f*****g off. Check PORV
     versus RPORV for ten 'random' locations in the grid.
  */
  {
    const ecl_kw_type * rporv1_kw     = ecl_file_iget_named_kw( restart_file1 , "RPORV" , 0);      
    const ecl_kw_type * rporv2_kw     = ecl_file_iget_named_kw( restart_file2 , "RPORV" , 0);      
    const ecl_kw_type * init_porv_kw  = ecl_file_iget_named_kw( init_file     , "PORV" , 0);

    int    active_index;
    int    active_delta;
    int    active_size;
    
    ecl_grid_get_dims( ecl_grid , NULL , NULL , NULL , &active_size );
    active_delta = active_size / 12;
    for (active_index = active_delta; active_index < active_size; active_index += active_delta) {
      int    global_index = ecl_grid_get_global_index1A( ecl_grid , active_index );
      double init_porv    = ecl_kw_iget_as_double( init_porv_kw , global_index );   /* NB - this uses global indexing. */
      double rporv1       = ecl_kw_iget_as_double( rporv1_kw ,  active_index );
      double rporv2       = ecl_kw_iget_as_double( rporv2_kw ,  active_index );
      double rporv12      = 0.5 * ( rporv1 + rporv2 );
      double fraction     = util_double_min( init_porv , rporv12 ) / util_double_max( init_porv , rporv12 );

      if (fraction  < 0.50) {
        fprintf(stderr,"-----------------------------------------------------------------\n");
        fprintf(stderr,"INIT PORV: %g \n",init_porv);
        fprintf(stderr,"RPORV1   : %g \n",rporv1);
        fprintf(stderr,"RPORV2   : %g \n",rporv2);
        fprintf(stderr,"Hmmm - the RPORV values extracted from the restart file seem to be \n");
        fprintf(stderr,"veeery different from the initial rporv value. This might indicated\n");
        fprintf(stderr,"an ECLIPSE bug. Version 2007.2 is known to be ok in this respect, \n");
        fprintf(stderr,"whereas version 2008.2 is known to have a bug. \n");
        fprintf(stderr,"-----------------------------------------------------------------\n");
        exit(1);
      }
    }
  }

  return 0;
}
Ejemplo n.º 10
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
}
Ejemplo n.º 11
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.
		*/
	}
}
Ejemplo n.º 12
0
int switch_object::init(OBJECT *parent)
{
	double phase_total, switch_total;
	char indexa, indexb;

	OBJECT *obj = OBJECTHDR(this);

	//Special flag moved to be universal for all solvers - mainly so phase checks catch it now
	SpecialLnk = SWITCH;

	int result = link_object::init(parent);

	//secondary init stuff - should have been done, but we'll be safe
	//Basically zero everything
	if (solver_method==SM_FBS)
	{
		for (indexa=0; indexa<3; indexa++)
		{
			for (indexb=0; indexb<3; indexb++)
			{
				//These have to be zeroed (nature of switch)
				b_mat[indexa][indexb] = 0.0;
				c_mat[indexa][indexb] = 0.0;
				B_mat[indexa][indexb] = 0.0;

				//Paranoid initialization
				a_mat[indexa][indexb] = 0.0;
				A_mat[indexa][indexb] = 0.0;
				d_mat[indexa][indexb] = 0.0;
			}
		}

		//Generic warning for switches
		gl_warning("switch objects may not behave properly under FBS!");
		/*  TROUBLESHOOT
		Due to the nature of the forward-backward sweep algorithm, and open
		switch may induce the desired behavior on the system.  If open, it should prevent
		current flow and set the "to" end voltage to zero.  However, this may cause problems
		in many powerflow conditions or not properly solve.  Consider using the
		Newton-Raphson solver in conjunction with the reliability package, or rearrange your system.
		*/
	}
	else
	{
		//Flagged it as special (we'll forgo inversion processes on this)

		//Index out "voltage_ratio" matrix (same as A_mat, basically)
		//and From_Y - just because
		for (indexa=0; indexa<3; indexa++)
		{
			for (indexb=0; indexb<3; indexb++)
			{
				From_Y[indexa][indexb] = 0.0;
				a_mat[indexa][indexb] = 0.0;
			}
		}

		if(switch_resistance == 0.0){
			gl_warning("Switch:%s switch_resistance has been set to zero. This will result singular matrix. Setting to the global default.",obj->name);
			/*  TROUBLESHOOT
			Under Newton-Raphson solution method the impedance matrix cannot be a singular matrix for the inversion process.
			Change the value of switch_resistance to something small but larger that zero.
			*/
		}
		if(switch_resistance < 0.0){
			switch_resistance = default_resistance;
		}
	}//End NR mode

	//Make adjustments based on BANKED vs. INDIVIDUAL - replication of later code
	if (switch_banked_mode == BANKED_SW)
	{
		//Set reliability-related flag
		prefault_banked = true;

		//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
		{
			//Initial check, make sure stays open
			if (status == LS_OPEN)
			{
				phase_A_state = phase_B_state = phase_C_state = CLOSED;	//Set all to open - phase checks will sort it out
			}
			else
			{
				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
			}
		}

		if (status==LS_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);

				//Confirm a_mat is zerod too, just for portability
				a_mat[0][0] = complex(0.0,0.0);
				a_mat[1][1] = complex(0.0,0.0);
				a_mat[2][2] = complex(0.0,0.0);

				d_mat[0][0] = complex(0.0,0.0);
				d_mat[1][1] = complex(0.0,0.0);
				d_mat[2][2] = complex(0.0,0.0);
			}
			else	//Assumed FBS (GS not considered)
			{
				A_mat[0][0] = complex(0.0,0.0);
				A_mat[1][1] = complex(0.0,0.0);
				A_mat[2][2] = complex(0.0,0.0);

				d_mat[0][0] = complex(0.0,0.0);
				d_mat[1][1] = complex(0.0,0.0);
				d_mat[2][2] = complex(0.0,0.0);
			}

			phase_A_state = phase_B_state = phase_C_state = OPEN;	//All open
			prev_full_status = 0x00;								//Confirm here
		}
		else
		{
			if (has_phase(PHASE_A))
			{
				if (solver_method == SM_NR)
				{
					From_Y[0][0] = complex(1/switch_resistance,1/switch_resistance);
					a_mat[0][0] = 1.0;
					d_mat[0][0] = 1.0;
				}
				else
				{
					A_mat[0][0] = 1.0;
					d_mat[0][0] = 1.0;
				}

				phase_A_state = CLOSED;							//Flag as closed
				prev_full_status |= 0x04;
			}

			if (has_phase(PHASE_B))
			{
				if (solver_method == SM_NR)
				{
					From_Y[1][1] = complex(1/switch_resistance,1/switch_resistance);
					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;
				}

				phase_B_state = CLOSED;							//Flag as closed
				prev_full_status |= 0x02;
			}

			if (has_phase(PHASE_C))
			{
				if (solver_method == SM_NR)
				{
					From_Y[2][2] = complex(1/switch_resistance,1/switch_resistance);
					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;
				}

				phase_C_state = CLOSED;							//Flag as closed
				prev_full_status |= 0x01;
			}
		}
	}//End banked mode
	else	//Individual mode
	{
		if (status==LS_OPEN)	//Take this as all should be 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);

				//Ensure voltage ratio set too (technically not needed)
				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	//Assumed FBS (GS not considered)
			{
				A_mat[0][0] = complex(0.0,0.0);
				A_mat[1][1] = complex(0.0,0.0);
				A_mat[2][2] = complex(0.0,0.0);

				d_mat[0][0] = complex(0.0,0.0);
				d_mat[1][1] = complex(0.0,0.0);
				d_mat[2][2] = complex(0.0,0.0);
			}

			phase_A_state = phase_B_state = phase_C_state = OPEN;	//All open
			prev_full_status = 0x00;								//Confirm here
		}
		else	//LS_CLOSED - handle individually
		{
			if (has_phase(PHASE_A))
			{
				if (phase_A_state == CLOSED)
				{
					if (solver_method == SM_NR)
					{
						From_Y[0][0] = complex(1/switch_resistance,1/switch_resistance);
						a_mat[0][0] = 1.0;
						d_mat[0][0] = 1.0;
					}
					else
					{
						A_mat[0][0] = 1.0;
						d_mat[0][0] = 1.0;
					}
					prev_full_status |= 0x04;
				}
				else	//Must be open
				{
					if (solver_method == SM_NR)
					{
						From_Y[0][0] = complex(0.0,0.0);
						a_mat[0][0] = complex(0.0,0.0);
						d_mat[0][0] = complex(0.0,0.0);
					}
					else
					{
						A_mat[0][0] = complex(0.0,0.0);
						d_mat[0][0] = complex(0.0,0.0);
					}
					prev_full_status &=0xFB;
				}
			}

			if (has_phase(PHASE_B))
			{
				if (phase_B_state == CLOSED)
				{
					if (solver_method == SM_NR)
					{
						From_Y[1][1] = complex(1/switch_resistance,1/switch_resistance);
						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;
					}
					prev_full_status |= 0x02;
				}
				else	//Must be open
				{
					if (solver_method == SM_NR)
					{
						From_Y[1][1] = complex(0.0,0.0);
						a_mat[1][1] = complex(0.0,0.0);
						d_mat[1][1] = complex(0.0,0.0);
					}
					else
					{
						A_mat[1][1] = complex(0.0,0.0);
						d_mat[1][1] = complex(0.0,0.0);
					}
					prev_full_status &=0xFD;
				}
			}

			if (has_phase(PHASE_C))
			{
				if (phase_C_state == CLOSED)
				{
					if (solver_method == SM_NR)
					{
						From_Y[2][2] = complex(1/switch_resistance,1/switch_resistance);
						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;
					}
					prev_full_status |= 0x01;
				}
				else	//Must be open
				{
					if (solver_method == SM_NR)
					{
						From_Y[2][2] = complex(0.0,0.0);
						a_mat[2][2] = complex(0.0,0.0);
						d_mat[2][2] = complex(0.0,0.0);
					}
					else
					{
						A_mat[2][2] = complex(0.0,0.0);
						d_mat[2][2] = complex(0.0,0.0);
					}
					prev_full_status &=0xFE;
				}
			}
		}
	}//end individual

	//Store switch status - will get updated as things change later
	phased_switch_status = prev_full_status;

	return result;
}
Ejemplo n.º 13
0
//Function to replicate sync_switch_function, but not call anything (just for reliability checks)
unsigned char switch_object::switch_expected_sync_function(void)
{
	unsigned char phases_out;
	double phase_total, switch_total;
	SWITCHSTATE temp_A_state, temp_B_state, temp_C_state;
	enumeration temp_status;

	if (solver_method==SM_NR)	//Newton-Raphson checks
	{
		//Store current phases
		phases_out = NR_branchdata[NR_branch_reference].phases;
		temp_A_state = (SWITCHSTATE)phase_A_state;
		temp_B_state = (SWITCHSTATE)phase_B_state;
		temp_C_state = (SWITCHSTATE)phase_C_state;
		temp_status = status;

		if (switch_banked_mode == BANKED_SW)	//Banked mode
		{
			if (temp_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) && (temp_A_state == CLOSED))
					switch_total += 1.0;

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

				if (has_phase(PHASE_C) && (temp_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
				{
					temp_status = LS_CLOSED;	//If it wasn't here, it is now
					temp_A_state = temp_B_state = temp_C_state = CLOSED;	//Set all to closed - phase checks will sort it out
				}
				else	//Minority or stalemate
				{
					if (switch_total == 0.5)	//Stalemate
					{
						if (temp_status == LS_OPEN)	//These check assume phase_X_state will be manipulated, not status
						{
							temp_A_state = temp_B_state = temp_C_state = OPEN;
						}
						else	//Closed
						{
							temp_A_state = temp_B_state = temp_C_state = CLOSED;
						}
					}
					else	//Not stalemate - open all
					{
						temp_status = LS_OPEN;
						temp_A_state = temp_B_state = temp_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 (temp_status==LS_OPEN)
					temp_A_state = temp_B_state = temp_C_state = OPEN;	//Flag all as open
				else
					temp_A_state = temp_B_state = temp_C_state = CLOSED;	//Flag all as closed
			}//End not same

			if (temp_status==LS_OPEN)
			{
				if (has_phase(PHASE_A))
				{
					phases_out &= 0xFB;	//Remove this bit
				}

				if (has_phase(PHASE_B))
				{
					phases_out &= 0xFD;	//Remove this bit
				}

				if (has_phase(PHASE_C))
				{
					phases_out &= 0xFE;	//Remove this bit
				}
			}//end open
			else					//Must be closed then
			{
				if (has_phase(PHASE_A))
				{
					phases_out |= 0x04;	//Ensure we're set
				}

				if (has_phase(PHASE_B))
				{
					phases_out |= 0x02;	//Ensure we're set
				}

				if (has_phase(PHASE_C))
				{
					phases_out |= 0x01;	//Ensure we're set
				}
			}//end closed
		}//End banked mode
		else	//Individual mode
		{
			if (temp_status == LS_OPEN)	//Fully opened means all go open
			{
				temp_A_state = temp_B_state = temp_C_state = OPEN;	//All open
				phases_out &= 0xF0;		//Remove all our phases
			}
			else	//Closed means a phase-by-phase basis
			{
				if (has_phase(PHASE_A))
				{
					if (temp_A_state == CLOSED)
					{
						phases_out |= 0x04;	//Ensure we're set
					}
					else	//Must be open
					{
						phases_out &= 0xFB;	//Make sure we're removed
					}
				}

				if (has_phase(PHASE_B))
				{
					if (temp_B_state == CLOSED)
					{
						phases_out |= 0x02;	//Ensure we're set
					}
					else	//Must be open
					{
						phases_out &= 0xFD;	//Make sure we're removed
					}
				}

				if (has_phase(PHASE_C))
				{
					if (temp_C_state == CLOSED)
					{
						phases_out |= 0x01;	//Ensure we're set
					}
					else	//Must be open
					{
						phases_out &= 0xFE;	//Make sure we're removed
					}
				}
			}
		}//end individual mode
	}//end SM_NR

	//Return the phases
	return phases_out;
}
Ejemplo n.º 14
0
// Initialize a distribution meter, return 1 on success
int substation::init(OBJECT *parent)
{
	OBJECT *hdr = OBJECTHDR(this);
	int i,n;

	//Base check higher so can be used below
	if(base_power <= 0){
		gl_warning("substation:%i is using the default base power of 100 VA. This could cause instability on your system.", hdr->id);
		base_power = 100;//default gives a max power error of 1 VA.
	}

	//Check convergence-posting criterion
	if (power_convergence_value<=0.0)
	{
		gl_warning("power_convergence_value not set - defaulting to 0.01 base_power");
		/*  TROUBLESHOOT
		A value was not specified for the convergence criterion required before posting an 
		answer up to pw_load.  This value has defaulted to 1% of base_power.  If a different threshold
		is desired, set it explicitly.
		*/

		power_convergence_value = 0.01*base_power;
	}//End convergence value check

	//Check to see if it has a parent (no sense to ISAs if it is empty)

	if (parent != NULL)
	{
		if (gl_object_isa(parent,"pw_load","network"))
		{
			//Make sure it is done, otherwise defer
			if((parent->flags & OF_INIT) != OF_INIT){
				char objname[256];
				gl_verbose("substation::init(): deferring initialization on %s", gl_name(parent, objname, 255));

				return 2; // defer
			}

			//Map up the appropriate variables- error checks mostly inside
			fetch_complex(&pPositiveSequenceVoltage,"load_voltage",parent);
			fetch_complex(&pConstantPowerLoad,"load_power",parent);
			fetch_complex(&pConstantCurrentLoad,"load_current",parent);
			fetch_complex(&pConstantImpedanceLoad,"load_impedance",parent);
			fetch_double(&pTransNominalVoltage,"bus_nom_volt",parent);

			//Do a general check for nominal voltages - make sure they match
			if (fabs(*pTransNominalVoltage-nominal_voltage)>0.001)
			{
				gl_error("Nominal voltages of tranmission node (%.1f V) and substation (%.1f) do not match!",*pTransNominalVoltage,nominal_voltage);
				/*  TROUBLESHOOT
				The nominal voltage of the transmission node in PowerWorld does not match
				that of the value inside GridLAB-D's substation's nominal_voltage.  This could
				cause information mismatch and is therefore not allowed.  Please set the
				substation to the same nominal voltage as the transmission node.  Use transformers
				to step the voltage down to an appropriate distribution or sub-transmission level.
				*/
				return 0;	//Fail
			}

			//Check our bustype - otherwise we may get overridden (NR-esque check)
			if (bustype != SWING)
			{
				gl_warning("substation attached to pw_load and not a SWING bus - forcing to SWING");
				/*  TROUBLESHOOT
				When a substation object is connected to PowerWorld via a pw_load object, the
				substation must be designated as a SWING bus.  This designation will now be forced upon
				the bus.
				*/
				bustype = SWING;
			}//End bus check

			//Flag us as pw_load connected
			has_parent = 1;
		}
		else	//Parent isn't a pw_load, so we just become a normal node - let it handle things
		{
			has_parent = 2;	//Flag as "normal" - let node checks sort out if we are really valid or not
		}
	}//End parent
	else	//Parent is null, see what mode we're in
	{
		//Check for sequence voltages - if not set, we're normal (let node checks handle if we're valid)
		if ((seq_mat[0] != 0.0) || (seq_mat[1] != 0.0) || (seq_mat[2] != 0.0))
		{
			//See if we're a swing, if not, this is meaningless
			if (bustype != SWING)
			{
				gl_warning("substation is not a SWING bus, so answers may be unexpected");
				/*  TROUBLESHOOT
				A substation object appears set to accept sequence voltage values, but it is not a SWING bus.  This
				may end up causing the voltages to be converted from sequence, but then overridden by the distribution
				powerflow solver.
				*/
			}

			//Explicitly set
			has_parent = 0;
		}	
		else	//Else, nothing set, we're a normal old node
		{
			has_parent = 2;	//Normal node

			//Warn that nothing was found
			gl_warning("substation:%s is set up as a normal node, no sequence values will be calculated",hdr->name);
			/*  TROUBLESHOOT
			A substation is currently behaving just like a normal powerflow node.  If it was desired that it convert a 
			schedule or player of sequence values, please initialize those values to non-zero along with the player attachment.
			*/
		}
	}//End no parent

	//Set up reference items if they are needed
	if (has_parent != 2)	//Not a normal node
	{
		//New requirement to maintain positive sequence ability - three phases must be had, unless
		//we're just a normal node.  Then, we don't care.
		if (!has_phase(PHASE_A|PHASE_B|PHASE_C))
		{
			gl_error("substation needs to have all three phases!");
			/*  TROUBLESHOOT
			To meet the requirements for sequence voltage conversions, the substation node must have all three
			phases at the connection point.  If only a single phase or subset of full three phase is needed, those
			must be set in the distribution network, typically after a delta-ground wye transformer.
			*/
			return 0;
		}
	}//End not a normal node

	//set the reference phase number to shift the phase voltages appropriatly with the positive sequence voltage
	if(reference_phase == R_PHASE_A){
		reference_number.SetPolar(1,0);
	} else if(reference_phase == R_PHASE_B){
		reference_number.SetPolar(1,2*PI/3);
	} else if(reference_phase == R_PHASE_C){
		reference_number.SetPolar(1,-2*PI/3);
	}

	//create the sequence to phase transformation matrix
	for(i=0; i<3; i++){
		for(n=0; n<3; n++){
			if((i==1 && n==1) || (i==2 && n==2)){
				transformation_matrix[i][n].SetPolar(1,-2*PI/3);
			} else if((i==2 && n==1) || (i==1 && n==2)){
				transformation_matrix[i][n].SetPolar(1,2*PI/3);
			} else {
				transformation_matrix[i][n].SetPolar(1,0);
			}
		}
	}
	
	return node::init(parent);
}
Ejemplo n.º 15
0
// Initialize a distribution meter, return 1 on success
int meter::init(OBJECT *parent)
{
	char temp_buff[128];

	if(power_market != 0){
		price_prop = gl_get_property(power_market, "current_market.clearing_price");
		if(price_prop == 0){
			GL_THROW("meter::power_market object \'%s\' does not publish \'current_market.clearing_price\'", (power_market->name ? power_market->name : "(anon)"));
		}
	}

	// Count the number of phases...for use with meter_power_consumption
	if (meter_power_consumption != complex(0,0))
	{
		no_phases = 0;
		if (has_phase(PHASE_A))
			no_phases += 1;
		if (has_phase(PHASE_B))
			no_phases += 1;
		if (has_phase(PHASE_C))
			no_phases += 1;
	}

	check_prices();
	last_t = dt = 0;

	//Update tracking flag
	//Get server mode variable
	gl_global_getvar("multirun_mode",temp_buff,sizeof(temp_buff));

	//See if we're not in standalone
	if (strcmp(temp_buff,"STANDALONE"))	//strcmp returns a 0 if they are the same
	{
		if ((solver_method == SM_NR) && (bustype == SWING))
		{
			meter_NR_servered = true;	//Set this flag for later use

			//Allocate the storage vector
			prev_voltage_value = (complex *)gl_malloc(3*sizeof(complex));

			//Check it
			if (prev_voltage_value==NULL)
			{
				GL_THROW("Failure to allocate memory for voltage tracking array");
				/*  TROUBLESHOOT
				While attempting to allocate memory for the voltage tracking array used
				by the master/slave functionality, an error occurred.  Please try again.
				If the error persists, please submit your code and a bug report via the trac
				website.
				*/
			}

			//Populate it with zeros for now, just cause - init sets voltages in node
			prev_voltage_value[0] = complex(0.0,0.0);
			prev_voltage_value[1] = complex(0.0,0.0);
			prev_voltage_value[2] = complex(0.0,0.0);
		}
	}

	return node::init(parent);
}
Ejemplo n.º 16
0
int series_reactor::init(OBJECT *parent)
{
	int result = link_object::init(parent);

	a_mat[0][0] = d_mat[0][0] = A_mat[0][0] = (has_phase(PHASE_A)) ? 1.0 : 0.0;
	a_mat[1][1] = d_mat[1][1] = A_mat[1][1] = (has_phase(PHASE_B)) ? 1.0 : 0.0;
	a_mat[2][2] = d_mat[2][2] = A_mat[2][2] = (has_phase(PHASE_C)) ? 1.0 : 0.0;

	if (solver_method==SM_FBS)
	{
		c_mat[0][0] = 0.0;
		c_mat[1][1] = 0.0;
		c_mat[2][2] = 0.0;

		//Pass in impedance values
		b_mat[0][0] = B_mat[0][0] = phase_A_impedance;
		b_mat[1][1] = B_mat[1][1] = phase_B_impedance;
		b_mat[2][2] = B_mat[2][2] = phase_C_impedance;

	}
	else
	{
		//Flag it as special (we'll forgo inversion processes on this)
		SpecialLnk = SWITCH;

		//Initialize off-diagonals just in case
		From_Y[0][1] = From_Y[0][2] = From_Y[1][0] = 0.0;
		From_Y[1][2] = From_Y[2][0] = From_Y[2][1] = 0.0;

		//See if it has a particular phase, if so populate it.  If not
		//and has zero impedance, put a "default" value in its place
		if (has_phase(PHASE_A))
		{
			if (phase_A_impedance==0.0)
				From_Y[0][0] = complex(1e4,1e4);
			else
				From_Y[0][0] = complex(1.0,0.0)/phase_A_impedance;
		}
		else
			From_Y[0][0] = 0.0;		//Should already be 0, but let's be paranoid

		if (has_phase(PHASE_B))
		{
			if (phase_B_impedance==0.0)
				From_Y[1][1] = complex(1e4,1e4);
			else
				From_Y[1][1] = complex(1.0,0.0)/phase_B_impedance;
		}
		else
			From_Y[1][1] = 0.0;		//Should already be 0, but let's be paranoid

		if (has_phase(PHASE_C))
		{
			if (phase_C_impedance==0.0)
				From_Y[2][2] = complex(1e4,1e4);
			else
				From_Y[2][2] = complex(1.0,0.0)/phase_C_impedance;
		}
		else
			From_Y[2][2] = 0.0;		//Should already be 0, but let's be paranoid
	}

	return result;
}
Ejemplo n.º 17
0
static double gravity_response(const ecl_grid_type * ecl_grid      , 
                               const ecl_file_type * init_file     , 
                               const ecl_file_type * restart_file1 , 
                               const ecl_file_type * restart_file2 ,
                               const grav_station_type * grav_station , 
                               int model_phases, 
                               int file_phases) {
  
  ecl_kw_type * rporv1_kw   = NULL;  
  ecl_kw_type * rporv2_kw   = NULL;
  ecl_kw_type * oil_den1_kw = NULL;  
  ecl_kw_type * oil_den2_kw = NULL;
  ecl_kw_type * gas_den1_kw = NULL;
  ecl_kw_type * gas_den2_kw = NULL;
  ecl_kw_type * wat_den1_kw = NULL;
  ecl_kw_type * wat_den2_kw = NULL;
  ecl_kw_type * sgas1_kw    = NULL;
  ecl_kw_type * sgas2_kw    = NULL;
  ecl_kw_type * swat1_kw    = NULL;
  ecl_kw_type * swat2_kw    = NULL;
  ecl_kw_type * aquifern_kw = NULL ;
  double local_deltag = 0;

  /* Extracting the pore volumes */
  rporv1_kw = ecl_file_iget_named_kw( restart_file1 , "RPORV" , 0);      
  rporv2_kw = ecl_file_iget_named_kw( restart_file2 , "RPORV" , 0);      
  
  
  /** Extracting the densities */
  {
    // OIL_DEN
    if( has_phase(model_phases , OIL) ) {
      if (simulator == ECLIPSE100) {
        oil_den1_kw  = ecl_file_iget_named_kw(restart_file1, "OIL_DEN", 0);
        oil_den2_kw  = ecl_file_iget_named_kw(restart_file2, "OIL_DEN", 0);
      } else { // ECLIPSE300
        oil_den1_kw  = ecl_file_iget_named_kw(restart_file1, "DENO", 0);
        oil_den2_kw  = ecl_file_iget_named_kw(restart_file2, "DENO", 0);
      } ;
    }
    
    // GAS_DEN
    if( has_phase( model_phases , GAS) ) {
      if (simulator == ECLIPSE100) {
        gas_den1_kw  = ecl_file_iget_named_kw(restart_file1, "GAS_DEN", 0);
        gas_den2_kw  = ecl_file_iget_named_kw(restart_file2, "GAS_DEN", 0);
      } else { // ECLIPSE300
        gas_den1_kw  = ecl_file_iget_named_kw(restart_file1, "DENG", 0);
        gas_den2_kw  = ecl_file_iget_named_kw(restart_file2, "DENG", 0);
      } ;
    }
    
    // WAT_DEN
    if( has_phase( model_phases , WATER) ) {
      if (simulator == ECLIPSE100) {
        wat_den1_kw  = ecl_file_iget_named_kw(restart_file1, "WAT_DEN", 0);
        wat_den2_kw  = ecl_file_iget_named_kw(restart_file2, "WAT_DEN", 0);
      } else { // ECLIPSE300
        wat_den1_kw  = ecl_file_iget_named_kw(restart_file1, "DENW", 0);
        wat_den2_kw  = ecl_file_iget_named_kw(restart_file2, "DENW", 0);
      } ;
    }
  }
  
  
  /* Extracting the saturations */
  {
    // SGAS
    if( has_phase( file_phases , GAS )) {
      sgas1_kw     = ecl_file_iget_named_kw(restart_file1, "SGAS", 0);
      sgas2_kw     = ecl_file_iget_named_kw(restart_file2, "SGAS", 0);
    } 
    
    // SWAT
    if( has_phase( file_phases , WATER )) {
      swat1_kw     = ecl_file_iget_named_kw(restart_file1, "SWAT", 0);
      swat2_kw     = ecl_file_iget_named_kw(restart_file2, "SWAT", 0);
    } 
  }
  
  
  /* The numerical aquifer information */
  if( ecl_file_has_kw( init_file , "AQUIFERN")) 
    aquifern_kw     = ecl_file_iget_named_kw(init_file, "AQUIFERN", 0);
  {
    int     nactive  = ecl_grid_get_active_size( ecl_grid );
    float * zero     = util_calloc( nactive , sizeof * zero     );    /* Fake vector of zeros used for densities / sturations when you do not have data. */
    int   * int_zero = util_calloc( nactive , sizeof * int_zero );    /* Fake vector of zeros used for AQUIFER when the init file does not supply data. */
    /* 
       Observe that the fake vectors are only a coding simplification,
       they should not be really used.
    */

    {
      int i;
      for (i=0; i < nactive; i++) {
        zero[i]     = 0;
        int_zero[i] = 0;
      }
    }
    {
      const float * sgas1_v   = safe_get_float_ptr( sgas1_kw    , NULL );
      const float * swat1_v   = safe_get_float_ptr( swat1_kw    , NULL );
      const float * oil_den1  = safe_get_float_ptr( oil_den1_kw , zero );
      const float * gas_den1  = safe_get_float_ptr( gas_den1_kw , zero );
      const float * wat_den1  = safe_get_float_ptr( wat_den1_kw , zero );
      
      const float * sgas2_v   = safe_get_float_ptr( sgas2_kw    , NULL );
      const float * swat2_v   = safe_get_float_ptr( swat2_kw    , NULL );
      const float * oil_den2  = safe_get_float_ptr( oil_den2_kw , zero );
      const float * gas_den2  = safe_get_float_ptr( gas_den2_kw , zero );
      const float * wat_den2  = safe_get_float_ptr( wat_den2_kw , zero );
      
      const float * rporv1    = ecl_kw_get_float_ptr(rporv1_kw);
      const float * rporv2    = ecl_kw_get_float_ptr(rporv2_kw);
      double utm_x = grav_station->utm_x;
      double utm_y = grav_station->utm_y;
      double tvd   = grav_station->depth;
      
      int   * aquifern;
      int global_index;
          
      if (aquifern_kw != NULL)
        aquifern = ecl_kw_get_int_ptr( aquifern_kw );
      else
        aquifern = int_zero;

      for (global_index=0;global_index < ecl_grid_get_global_size( ecl_grid ); global_index++){
        const int act_index = ecl_grid_get_active_index1( ecl_grid , global_index );
        if (act_index >= 0) {

          // Not numerical aquifer 
          if(aquifern[act_index] >= 0){ 
            float swat1 = swat1_v[act_index];
            float swat2 = swat2_v[act_index];
            float sgas1 = 0;
            float sgas2 = 0;
            float soil1 = 0;
            float soil2 = 0;

            truncate_saturation( &swat1 );
            truncate_saturation( &swat2 );
            
            if (has_phase( model_phases , GAS)) {
              if (has_phase( file_phases , GAS )) {
                sgas1 = sgas1_v[act_index];
                sgas2 = sgas2_v[act_index];
                truncate_saturation( &sgas1 );
                truncate_saturation( &sgas2 );
              } else {
                sgas1 = 1 - swat1;
                sgas2 = 1 - swat2;
              }
            }
            
            if (has_phase( model_phases , OIL )) {
              soil1 =  1 - sgas1  - swat1;
              soil2 =  1 - sgas2  - swat2;
              truncate_saturation( &soil1 );
              truncate_saturation( &soil2 );
            }
            
                        
            /* 
               We have found all the info we need for one cell.
            */
            
            {
              double  mas1 , mas2;
              double  xpos , ypos , zpos;
              
              mas1 = rporv1[act_index]*(soil1 * oil_den1[act_index] + sgas1 * gas_den1[act_index] + swat1 * wat_den1[act_index] );
              mas2 = rporv2[act_index]*(soil2 * oil_den2[act_index] + sgas2 * gas_den2[act_index] + swat2 * wat_den2[act_index] );
              
              ecl_grid_get_xyz1(ecl_grid , global_index , &xpos , &ypos , &zpos);
              {
                double dist_x   = xpos - utm_x;
                double dist_y   = ypos - utm_y;
                double dist_d   = zpos - tvd;
                double dist_sq  = dist_x*dist_x + dist_y*dist_y + dist_d*dist_d;
                
                if(dist_sq == 0){
                  exit(1);
                }
                local_deltag += 6.67428E-3*(mas2 - mas1)*dist_d/pow(dist_sq, 1.5); // Gravity in units of \mu Gal = 10^{-8} m/s^2
              }
              
            }
          }
        }
      }
    }
    free( zero );
    free( int_zero );
  }
  return local_deltag;
}