Exemple #1
0
void fetch_geo (struct geo *G) {
  unsigned x = fetch_int ();
  if (x == CODE_geo_point) {
    G->longitude = fetch_double ();
    G->latitude = fetch_double ();
  } else {
    assert (x == CODE_geo_point_empty);
    G->longitude = 0;
    G->latitude = 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);
}
Exemple #3
0
static int
printf_float (STREAM *stream,
	      struct printf_info *const pinfo,
	      union printf_arg const *args)
{
  snv_long_double value = 0.0;
  int sign, len, count_or_errorcode = SNV_OK;
#ifdef HAVE_LONG_DOUBLE
  char buffer[LDBL_MAX_10_EXP * 2 + 20], *p = buffer;
#else
  char buffer[DBL_MAX_10_EXP * 2 + 20], *p = buffer;
#endif

  return_val_if_fail (pinfo != NULL, SNV_ERROR);

  /* Check for valid pre-state */
  if (pinfo->prec == -1)
    pinfo->prec = SNV_POINTER_TO_INT (pinfo->extra);

  /* Check for valid pre-state. */
  if (pinfo->prec <= -1
     || pinfo->is_char || pinfo->is_short || pinfo->is_long)
    {
      PRINTF_ERROR (pinfo, "invalid flags");
      return -1;
    }

  /* Extract the correct argument from the arg vector. */
  value = fetch_double (pinfo, args);

  /* Convert the number into a string. */
  len = print_float (pinfo, buffer, buffer + sizeof (buffer), &sign, value);
  if (*buffer == '0')
    p++, len--;

  /* Compute the size of the padding.  */
  pinfo->width -= len;
  if (sign)
    pinfo->width--;

  /* Left pad to the remaining width if the supplied argument is less
     than the width specifier, and the padding character is ' '.  */
  if (pinfo->pad == ' ' && !pinfo->left)
    while ((count_or_errorcode >= 0) && (pinfo->width-- > 0))
      SNV_EMIT (pinfo->pad, stream, count_or_errorcode);

  /* Display any sign character. */
  if (count_or_errorcode >= 0 && sign)
    SNV_EMIT (sign, stream, count_or_errorcode);

  /* Left pad to the remaining width if the supplied argument is less
     than the width specifier, and the padding character is not ' '.  */
  if (pinfo->pad != ' ' && !pinfo->left)
    while ((count_or_errorcode >= 0) && (pinfo->width-- > 0))
	SNV_EMIT (pinfo->pad, stream, count_or_errorcode);

  /* Fill the stream buffer with as many characters from the number
     buffer as possible without overflowing.  */
  while ((count_or_errorcode >= 0) && (len-- > 0))
    SNV_EMIT (*p++, stream, count_or_errorcode);

  /* Right pad to the width if we still didn't reach the specified
     width and the left justify flag was set.  */
  if (pinfo->left)
    while ((count_or_errorcode >= 0) && (pinfo->width-- > 0))
      SNV_EMIT (pinfo->pad, stream, count_or_errorcode);

  /* Return the number of characters emitted. */
  return count_or_errorcode;
}