Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

There is more than one right way to do it. It all depends on what you are trying to achieve.

In load flow there are a few important types of buses, PQ where you can directly control the Power and Reactive Power; and PV where you can control the Power and Voltage. The reactive power will change to support the set voltage.

I'm sure you already know the above, but some other students reading might not.

I once wrote my own QV Curve generator by attaching a machine via a branch to a load bus and varying the voltage set point. Are you doing something similar?

There is more than one right way to do it. It all depends on what What are you are trying to achieve. achieve @Hector?

In load flow there are a few important Different buses will require different types of buses, control.

  • PQ where you can directly control the Power and Reactive Power; and Power; and
  • PV where you can control the Power and Voltage. The reactive power power will change to support the set set voltage.

I'm sure you already know the above, but some other students reading might not.

I once wrote my own Are you writing a QV Curve generator by attaching a machine via a branch to a load bus and varying the voltage set point. Are you doing something similar?generator?

There is more than one right way to do it. What are you trying to achieve @Hector?

Different buses will require different types of control.

  • PQ where you can directly control the Power and Reactive Power; and
  • PV where you can control the Power and Voltage. The reactive power will change to support the set voltage.

I'm sure you already know the above, but some other students reading might not.

Are you writing a QV Curve generator?

Here is some starter code:

def main():
  """Add a constant 20MVAr load to these buses."""

  buses = [101, 102, 103] # these should be PQ type buses
  for bus in buses
    load = {'ql': 20} # Constant MVAr
    add_load_to(bus, load)

and if you were curious about where that add_load_to function comes from? Here is the code.

import uuid
def available_load_id(bus):
  """Returns a random available load id for a bus."""
  taken_ids = load_ids_for_bus(bus)
  while True:
    newid = uuid.uuid4().hex[:2]
    if newid not in taken_ids: 
      break
  return newid


def load_ids_for_bus(target_bus):
  """returns existing load ids in a list for a bus."""
  buses, ierr = psspy.aloadint(
             -1,                # all buses
             flag=4,            # for all loads
             string=["NUMBER"]) # get bus number
  ids, ierr = psspy.aloadchar(
             -1,                # all buses
             flag=4,            # for all loads
             string=["ID"])     # get load id

  # converts [[101], [102]] and [['1'], ['2']] to [[101, '1'], [102, '2']]
  allbuses = zip(zip(*buses)[0], zip(*ids)[0])
  return [id for (bus, id) in allbuses if target_bus == bus]

def add_load_to(bus, load):
  """Create a load (can be negative) and add to bus.
     Returns load dictionary with new id ('id') and bus number ('i') set
  """
  newid = available_load_id(bus)
  psspy.load_data_3(
             bus,
             id=newid,
             realar1=load.get('pl', 0)    # set PL [default 0]
             realar2=load.get('ql', 0)    # set QL [default 0]
  )
  load['id'] = newid
  load['i'] = bus
  return load

I didn't test this code out with PSSE. I think it should work though.

There is more than one right way to do it. What are you trying to achieve @Hector?

Different buses will require different types of control.

  • PQ where you can directly control the Power and Reactive Power; and
  • PV where you can control the Power and Voltage. The reactive power will change to support the set voltage.

I'm sure you already know the above, but some other students reading might not.

Are you writing a QV Curve generator?

Here is some starter code:

def main():
  """Add a constant 20MVAr load to these buses."""

  buses = [101, 102, 103] # these should be PQ type buses
  for bus in buses
    load = {'ql': 20} # Constant MVAr
    add_load_to(bus, load)

and if you were curious about where that add_load_to function comes from? Here is the code.

import uuid
def available_load_id(bus):
  """Returns a random available load id for a bus."""
  taken_ids = load_ids_for_bus(bus)
  while True:
    newid = uuid.uuid4().hex[:2]
    if newid not in taken_ids: 
      break
  return newid


def load_ids_for_bus(target_bus):
  """returns existing load ids in a list for a bus."""
  buses, ierr = psspy.aloadint(
             -1,                # all buses
             flag=4,            # for all loads
             string=["NUMBER"]) # get bus number
  ids, ierr = psspy.aloadchar(
             -1,                # all buses
             flag=4,            # for all loads
             string=["ID"])     # get load id

  # converts [[101], [102]] and [['1'], ['2']] to [[101, '1'], [102, '2']]
  allbuses = zip(zip(*buses)[0], zip(*ids)[0])
  return [id for (bus, id) in allbuses if target_bus == bus]

def add_load_to(bus, load):
  """Create a load (can be negative) and add to bus.
     Returns load dictionary with new id ('id') and bus number ('i') set
  """
  newid = available_load_id(bus)
  psspy.load_data_3(
             bus,
             id=newid,
             realar1=load.get('pl', 0)    # set PL [default 0]
             realar2=load.get('ql', 0)    # set QL [default 0]
  )
  load['id'] = newid
  load['i'] = bus
  return load

def available_load_id(bus):
  """Returns a random available load id for a bus."""
  taken_ids = load_ids_for_bus(bus)
  while True:
    newid = uuid.uuid4().hex[:2]
    if newid not in taken_ids: 
      break
  return newid


def load_ids_for_bus(target_bus):
  """returns existing load ids in a list for a bus."""
  buses, ierr = psspy.aloadint(
             -1,                # all buses
             flag=4,            # for all loads
             string=["NUMBER"]) # get bus number
  ids, ierr = psspy.aloadchar(
             -1,                # all buses
             flag=4,            # for all loads
             string=["ID"])     # get load id

  # converts [[101], [102]] and [['1'], ['2']] to [[101, '1'], [102, '2']]
  allbuses = zip(zip(*buses)[0], zip(*ids)[0])
  return [id for (bus, id) in allbuses if target_bus == bus]

I didn't test this code out with PSSE. I think it should work though.

click to hide/show revision 5
compare add load to and load data 4

There is more than one right way to do it. What are you trying to achieve @Hector?

Different buses will require different types of control.

  • PQ where you can directly control the Power and Reactive Power; and
  • PV where you can control the Power and Voltage. The reactive power will change to support the set voltage.

I'm sure you already know the above, but some other students reading might not.

Are you writing a QV Curve generator?

Here is some starter code:

def main():
  """Add a constant 20MVAr load to these buses."""

  buses = [101, 102, 103] # these should be PQ type buses
  for bus in buses
    load = {'ql': 20} # Constant MVAr
    add_load_to(bus, load)

and if you were curious about where that add_load_to function comes from? Here is the code.

import uuid

def add_load_to(bus, load):
  """Create a load (can be negative) and add to bus.
     Returns load dictionary with new id ('id') and bus number ('i') set
  """
  newid = available_load_id(bus)
  psspy.load_data_3(
             bus,
             id=newid,
             realar1=load.get('pl', 0)    # set PL [default 0]
             realar2=load.get('ql', 0)    # set QL [default 0]
  )
  load['id'] = newid
  load['i'] = bus
  return load

def available_load_id(bus):
  """Returns a random available load id for a bus."""
  taken_ids = load_ids_for_bus(bus)
  while True:
    newid = uuid.uuid4().hex[:2]
    if newid not in taken_ids: 
      break
  return newid


def load_ids_for_bus(target_bus):
  """returns existing load ids in a list for a bus."""
  buses, ierr = psspy.aloadint(
             -1,                # all buses
             flag=4,            # for all loads
             string=["NUMBER"]) # get bus number
  ids, ierr = psspy.aloadchar(
             -1,                # all buses
             flag=4,            # for all loads
             string=["ID"])     # get load id

  # converts [[101], [102]] and [['1'], ['2']] to [[101, '1'], [102, '2']]
  allbuses = zip(zip(*buses)[0], zip(*ids)[0])
  return [id for (bus, id) in allbuses if target_bus == bus]

I didn't test this code out with PSSE. I think it should work though.

though.

(edit) Compare using add_load_to with load_data_3 or load_data_4:

load = {'q': 20}
add_load_to(102, load)

# versus

psspy.load_data_4(102, '1 ', realar2=20)

The problem with load_data_4 is that if there is already a load with id '1 ' then it will be overwritten, add_load_to never overwrites a load because it creates a new unique load id for you.

There is more than one right way to do it. What are you trying to achieve @Hector?

Different buses will require different types of control.

  • PQ where you can directly control the Power and Reactive Power; and
  • PV where you can control the Power and Voltage. The reactive power will change to support the set voltage.

I'm sure you already know the above, but some other students reading might not.

Are you writing a QV Curve generator?

Here is some starter code:

def main():
  """Add a constant 20MVAr load to these buses."""

  buses = [101, 102, 103] # these should be PQ type buses
  for bus in buses
    load = {'ql': 20} # Constant MVAr
    add_load_to(bus, load)

and if you were curious about where that add_load_to function comes from? Here is the code.

import uuid

def add_load_to(bus, load):
  """Create a load (can be negative) and add to bus.
     Returns load dictionary with new id ('id') and bus number ('i') set
  """
  newid = available_load_id(bus)
  psspy.load_data_3(
             bus,
             id=newid,
             realar1=load.get('pl', 0)    # set PL [default 0]
             realar2=load.get('ql', 0)    # set QL [default 0]
  )
  load['id'] = newid
  load['i'] = bus
  return load

def available_load_id(bus):
  """Returns a random available load id for a bus."""
  taken_ids = load_ids_for_bus(bus)
  while True:
    newid = uuid.uuid4().hex[:2]
    if newid not in taken_ids: 
      break
  return newid


def load_ids_for_bus(target_bus):
  """returns existing load ids in a list for a bus."""
  buses, ierr = psspy.aloadint(
             -1,                # all buses
             flag=4,            # for all loads
             string=["NUMBER"]) # get bus number
  ids, ierr = psspy.aloadchar(
             -1,                # all buses
             flag=4,            # for all loads
             string=["ID"])     # get load id

  # converts [[101], [102]] and [['1'], ['2']] to [[101, '1'], [102, '2']]
  allbuses = zip(zip(*buses)[0], zip(*ids)[0])
  return [id for (bus, id) in allbuses if target_bus == bus]

I didn't test this code out with PSSE. I think it should work though.

(edit) Compare using add_load_to with load_data_3 or load_data_4:

load = {'q': {'ql': 20}
add_load_to(102, load)

# versus

psspy.load_data_4(102, '1 ', realar2=20)

The problem with load_data_4 is that if there is already a load with id '1 ' then it will be overwritten, add_load_to never overwrites a load because it creates a new unique load id for you.