Skip to content

Commit

Permalink
Cleanup docs and refactor code
Browse files Browse the repository at this point in the history
Signed-off-by: David P. Chassin <[email protected]>
  • Loading branch information
David P. Chassin committed Sep 22, 2023
1 parent c419df4 commit 936f76d
Show file tree
Hide file tree
Showing 51 changed files with 9,566 additions and 9,342 deletions.
2 changes: 1 addition & 1 deletion converters/autotest/test_csvgeodata2kml.csv
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class,pole_length,pole_depth,ground_diameter,fiber_strength,name,tilt_angle,tilt_direction,latitude,longitude,configuration,weather,flags
class,pole_length,pole_depth,ground_diameter,fiber_strength,name,tilt_degree,tilt_direction,latitude,longitude,configuration,weather,flags
pole_configuration,40.0 ft,5.5 ft,9.87 in,8000 psi,pole_configuration_267462S,,,,,,,
pole_configuration,50.0 ft,7.5 ft,,8000 psi,pole_configuration_280565E,,,,,,,
pole_configuration,45.0 ft,6.5 ft,12.41 in,8000 psi,pole_configuration_306771E,,,,,,,
Expand Down
2 changes: 1 addition & 1 deletion converters/autotest/test_xls-spida2csv-geodata.csv
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class,pole_length,pole_depth,ground_diameter,fiber_strength,name,tilt_angle,tilt_direction,latitude,longitude,configuration,wind_speed,flags
class,pole_length,pole_depth,ground_diameter,fiber_strength,name,tilt_degree,tilt_direction,latitude,longitude,configuration,wind_speed,flags
pole_configuration,40.0 ft,5.5 ft,9.87 in,8000 psi,pole_configuration_267462S,,,,,,,
pole_configuration,50.0 ft,7.5 ft,12.18 in,8000 psi,pole_configuration_280565E,,,,,,,
pole_configuration,45.0 ft,6.5 ft,12.41 in,8000 psi,pole_configuration_306771E,,,,,,,
Expand Down
2 changes: 1 addition & 1 deletion converters/autotest/test_xls-spida2csv-network.csv
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class,pole_length,pole_depth,ground_diameter,fiber_strength,name,tilt_angle,tilt_direction,latitude,longitude,configuration,wind_speed,flags,equipment,parent,height,direction,pole_spacing,// cable_type,offset,area,weight,// equipment_type,phases,bustype,nominal_voltage,diameter,resistance,strength,distance_AE,conductor_A,spacing,from,to,length,connect_type,install_type,power_rating,primary_voltage,secondary_voltage,reactance
class,pole_length,pole_depth,ground_diameter,fiber_strength,name,tilt_degree,tilt_direction,latitude,longitude,configuration,wind_speed,flags,equipment,parent,height,direction,pole_spacing,// cable_type,offset,area,weight,// equipment_type,phases,bustype,nominal_voltage,diameter,resistance,strength,distance_AE,conductor_A,spacing,from,to,length,connect_type,install_type,power_rating,primary_voltage,secondary_voltage,reactance
pole_configuration,40.0 ft,5.5 ft,9.87 in,8000 psi,pole_configuration_267462S,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
pole_configuration,50.0 ft,7.5 ft,12.18 in,8000 psi,pole_configuration_280565E,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
pole_configuration,45.0 ft,6.5 ft,12.41 in,8000 psi,pole_configuration_306771E,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
Expand Down
2 changes: 1 addition & 1 deletion converters/mdb-cyme2glm.py
Original file line number Diff line number Diff line change
Expand Up @@ -2226,7 +2226,7 @@ def add_photovoltaic(self, photovoltaic_id, photovoltaic, version, **kwargs):
"panel_type": "MULTI_CRYSTAL_SILICON",
"efficiency": panel_efficiency,
"area": panel_area,
"tilt_angle": "45",
"tilt_degree": "45",
"orientation_azimuth": "180",
"orientation": "FIXED_AXIS",
}
Expand Down
233 changes: 130 additions & 103 deletions converters/xls-spida2csv-geodata.py

Large diffs are not rendered by default.

60 changes: 60 additions & 0 deletions docs/Converters/Import/Spida_data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
[[/Converters/Import/Spida_data]] -- SPIDACalc data import

# Synopis

GLM:
~~~
#convert SPIDACALC.xls GEODATA.csv -f xls-spida -t csv-geodata [precision=2] [extract_equipment=yes] [include_network=yes]
~~~

# Description

This converter extracts pole geodata from a SPIDAcalc pole asset report spreadsheet and generates a GriDLAB-D geodata CSV file.


# Options

- `precision=2`: specify the number of digits in a number and function ROUND will be used (default 2)

- `extract_equipment=yes`: enable the conversion of pole-mounted equipment, dummy values will be used for equipment properties (default None)

- `include_network=yes`: enable the generation of a bus-type feeder, dummy values will be used for properties of feeder and equipment (default None)

- `include_weather=NAME`: name the weather object and do not use dummy values for weather data (default None)

# Input

[SPIDAcalc](https://www.spidasoftware.com/spidacalc/) is proprietarty pole loading and line design software that some utilities use to model the forces on transmission and distribution systems. The data includes detailed specifications and location data for poles, mounted equipment and lines.

The input .xls must include a sheet called 'Design - Pole'.
If `extract_equipment=yes`, then it must also include a sheet called 'Design - Structure'

This SPIDACalc API documentation explains data in the pole asset report spreadsheet:
https://github.com/spidasoftware/schema/blob/66cb5d102dde5bf23b487dbddb261d3a88fc0907/doc/wfs.md
https://github.com/spidasoftware/schema/blob/master/doc/calc.md

For quick reference, some of the less obvious meanings are included below:
In 'Design - Pole':
* `AGL` means Above Ground Length
* `GLC` means GroundLine Circumference

In 'Design - Structure':
* `Direction` is a bearing for the mounted equipment, measured in degrees clockwise from North.
* A WEP is a Wire End Point, indicating the pole or building at the other end of a wire. Here `Offset/Lead` corresponds to the length of wire between the pole and this Wire End Point.
* For Insulators: "If on pole, then `offest` is attach height. If on cross arm, then `offset` is the distance from one end of the cross arm." - (SPIDAcalc docs)[https://github.com/spidasoftware/schema/blob/66cb5d102dde5bf23b487dbddb261d3a88fc0907/doc/wfs.md]
* For CrossArms: "Crossarm bearing is the direction the end of the crossarm points, not the direction of the bolt attachment." - (SPIDAcalc docs)[https://github.com/spidasoftware/schema/blob/66cb5d102dde5bf23b487dbddb261d3a88fc0907/doc/wfs.md]


# Output

A csv where each row represents a GridLAB-D object, columns are properties for that object.
**See the documentation for the respective GridLAB-D objects to interpret the properties.**

The following objects can be included in the output:
`pole`, `pole_configuration`
If `extract_equipment=yes`, it will also include `pole_mount`.


# See also

* [[/Converters/Import/Csv_files]]
2 changes: 1 addition & 1 deletion docs/Converters/Import/Table_data.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ This converter allows for any arbitrary object to be imported via CSV-formatted

Any arbitrary objects can be listed in a CSV file and convertered to GLM-formatted object. The table format is as below :

class | name | tilt_angle | tilt_direction | weather | configuration | equipment_area | equipment_height | install_year | repair_time | latitude | longitude | phases | nominal_voltage | tmyfile
class | name | tilt_degree | tilt_direction | weather | configuration | equipment_area | equipment_height | install_year | repair_time | latitude | longitude | phases | nominal_voltage | tmyfile
--- | --- | --- | --- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |---
powerflow.pole | pole1 | 5 deg | 270 | weather | WOOD-C-45/5 | | | 1990 | 1 h | 37.4275 | 122.1697 | ABC | 12470
powerflow.pole | pole2 | 8 deg | 270 | weather | WOOD-C-45/5 | | | 2000 | 8 h | 37.127 | 122.1646 | ABC | 12470
Expand Down
1 change: 1 addition & 0 deletions docs/Converters/Import/Xls_files.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ There are many different types of XLS files that can be imported. Each is docume
* [[/Converters/Import/Ceus_data]]
* [[/Converters/Import/Rbsa_data]]
* [[/Converters/Import/Scada_data]]
* [[/Converters/Import/Spida_data]]
* GLM models
* [[/Converters/Import/Config_data]]
* [[/Converters/Import/Ica_data]]
Expand Down
14 changes: 14 additions & 0 deletions docs/Developer/reading-the-code.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# C++ code files

The 'PT_' preffix for variable names means "Property Type".

oclass means object class
pclass means parent class

## get_<property>_offset()
These functions return offsets in memory location. Every object attribute is listed sequentially in memory (I believe in the order that they are declared?). This function returns the difference in the memory address of an attribute from the start of the object in memory. It's defined by a macro, `GL_ATOMIC(type, attribute name)` which generates a callable function specific to every attribute it's applied to.

The code looks like this:
`static inline size_t get_##X##_offset(void) { return (char*)&(defaults->X)-(char*)defaults; };`

`defaults` is a class attribute, a pointer to an object of the same type as the class it's a part of. Say we are looking at the `pole` class. `defaults` will be a pointer to a pole object. Confusingly, `defaults` is never inititialized to anything beyond NULL. How does this work? Back when this program was written in C, `defaults` pointed to a chunk of memory holding an object with all attributes initilized to default values. In C you could create a new object by simply copying this memory chunk. In C++ you need to declare all the attributes within an object, not just the object itself. The old method of setting defaults stopped working, so it's done differently now. The `defaults` pointer was retained as an attribute in the class declaration. The get offset function uses it for pointer math, finding the differences in memory location between the start of an object and all of it's attributes. Because a class declaration includes the type of all attributes, the compiler can figure out how much space they will take up in memory. (In C++ all types have a fixed size.) 'defaults' never needs to be initialized.
6 changes: 3 additions & 3 deletions docs/Module/Generators/Solar.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class solar {
complex VA_Out[VA];
object weather;
double shading_factor[pu];
double tilt_angle[deg];
double tilt_degree[deg];
double orientation_azimuth[deg];
bool latitude_angle_fix;
enumeration {DEFAULT=0,FIXED_AXIS=1,ONE_AXIS=2,TWO_AXIS=3,AZIMUTH_AXIS=4}orientation;
Expand Down Expand Up @@ -239,9 +239,9 @@ Reference to a climate object from which temperature, humidity, and solar flux a
double shading_factor[pu]
~~~
Shading factor for scaling solar power to the array.
### tilt_angle
### tilt_degree
~~~
double tilt_angle[deg]
double tilt_degree[deg]
~~~
Tilt angle of PV array.
### orientation_azimuth
Expand Down
54 changes: 29 additions & 25 deletions docs/Module/Powerflow/Pole.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
object pole
{
status "OK";
tilt_angle "0 deg";
tilt_degree "0 deg";
tilt_direction 0 deg";
weather "<climate-object>";
configuration "<pole-configuration-object>";
install_year "1970";
configuration "<pole-configuration-object>"; *
install_year "1970"; *
repair_time "24 h";
wind_speed 0.0 m/s;
wind_direction 0.0 deg;
Expand All @@ -23,19 +23,22 @@ object pole
total_moment "0 ft*lb";
resisting_moment "0 ft*lb";
pole_moment "0 ft*lb";
pole_moment_nowind "0 ft*lb";
pole_moment_per_wind "0 ft*lb";
equipment_moment "0 ft*lb";
equipment_moment_nowind "0 ft*lb";
equipment_moment_per_wind "0 ft*lb";
critical_wind_speed "0 m/s";
wire_moment "0 ft*lb";
wire_tension "0 ft*lb";
guy_height "0 ft";
}
~~~

\* Starred attributes are required.


# Description

The pole object models poles in powerflow network. The current pole object models pole failure by overstress at the base the pole from wind pressure on the equipment, wire, and tilt. The model does not model failures from ice loading on the lines or from foundation failure.
The pole object models poles in powerflow network. The current pole object models pole failure by overstress at the base the pole from wind pressure on the equipment, wire, and tilt. Ice on the line is modeled as an increase in the conductor diameter for respect to wind loading. The added weight is calculated assuming a cylindrically symmetric ice accumulation with constant density. The model does not model foundation failure.

Generally, any link object in a powerflow model can be mounted on a pole by creating a `pole_mount` object that uses the pole as a parent, and providing just the `weather` and `pole_configuration` object references to the pole. The `pole_mount` object specifies the position, size, and weight of the equipment on the pole to model the effect of wind give the aerodynamic cross-section.

Expand All @@ -49,10 +52,10 @@ Generally, any link object in a powerflow model can be mounted on a pole by crea

The status of the pole.

### `tilt_angle`
### `tilt_degree`

~~~
double tilt_angle[deg];
double tilt_degree[deg];
~~~

The tilt angle of the pole.
Expand Down Expand Up @@ -95,7 +98,7 @@ Year the pole was installed.
double repair_time[h];
~~~

Time required to repair or replace the pole after failure.
Time required to repair or replace the pole after failure. Includes time to identify the failure and reach the site.

### `wind_speed`

Expand Down Expand Up @@ -130,7 +133,7 @@ The wind gusts at the location of the pole. This is automatically set is the
double pole_stress[pu];
~~~

Ratio of actual stress to critical stress.
Ratio of actual (applied) moment to resisting moment (highest the pole can handle). When this reaches 1.0 or higher, the pole failes.

### `pole_stress_polynomial_a`

Expand Down Expand Up @@ -162,55 +165,56 @@ Constant c of the pole stress polynomial function.
double susceptibility[pu*s/m];
~~~

Susceptibility of pole to wind stress (derivative of pole stress w.r.t wind speed).
Susceptibility of pole to wind stress (derivative of pole stress with respect to wind speed).

### `total_moment`

~~~
double total_moment[ft*lb];
~~~

The total moment on the pole.
The total moment on the pole. This results from wind loads, gravitational loads, and potentially a transverse (perpendicular to the wires) load due to an angle in the conductors. There is wind pressure on the pole itself, the conductors attached to the pole, and the equipment mounted on the pole. Wind on equipment is usually much less signinficant than wind on the conductors. There are also gravitaional loads based on the pole tilt, it's weight and that of the mounted equipment and lines.


### `resisting_moment`

~~~
double resisting_moment[ft*lb];
~~~

Maximum moment the pole can withstand before snapping. This is calculated based on the fiber strength of the wood species and the pole diameter where it is supported - either at ground line or where guy wire(s) are attached.

### `pole_moment`

~~~
double pole_moment[ft*lb];
~~~

The moment of the pole.
Moment on the pole due to it's own weight and tilt.

### `pole_moment_nowind`
### `pole_moment_per_wind`

~~~
double pole_moment_nowind[ft*lb];
double pole_moment_per_wind[ft*lb];
~~~

The moment of the pole without wind.
The components of the equation for moment due to wind on the pole, except for wind pressure, i.e. moment per unit wind pressure. Accounts for the pole's cross-sectional area (for calculating the force of wind on the pole) and height (torque raduis).

### `equipment_moment`

~~~
double equipment_moment[ft*lb];
~~~

The moment of the equipment.
Moments on the pole due to gravitational load (equipment weight, pole tilt) and wind load (based on cross-sectional area of equipment).

### `equipment_moment_nowind`
### `equipment_moment_per_wind`

~~~
double equipment_moment_nowind[ft*lb];
double equipment_moment_per_wind[ft*lb];
~~~

The moment of the equipment without wind.

The resisting moment on the pole.
The components of the equation for moment due to wind on equipment, all except the wind pressure, i.e. moment per unit wind pressure.

### `critical_wind_speed`

Expand All @@ -226,7 +230,7 @@ Wind speed at pole failure.
double wire_moment[ft*lb];
~~~

Wire moment due to conductor weight.
Moments due to line tension, weight, and wind on the lines.

### `wire_tension`

Expand All @@ -248,10 +252,10 @@ Guy wire attachment height.

The pole failure model is described in [Pole Loading Model](https://source.gridlabd.us/raw/master/module/powerflow/docs/pole_loading.pdf).

The pole reaches end of life status based on a degradation rate that is defined by minimum shell thickness of 2". See [Pole Degradation Model](https://www.sciencedirect.com/science/article/pii/S0167473005000457) details.
[Out of date, change this:] The pole reaches end of life status based on a degradation rate that is defined by minimum shell thickness of 2". See [Pole Degradation Model](https://www.sciencedirect.com/science/article/pii/S0167473005000457) details.

# See also

* [[/Module/Powerflow/Pole_configuration]]
* [[/Module/Powerflow/Pole_configuration]](https://github.com/arras-energy/gridlabd/blob/master/docs/Module/Powerflow/Pole_configuration.md)
* [Pole Loading Model](https://source.gridlabd.us/raw/master/module/powerflow/docs/pole_loading.pdf)
* [Pole Degradation Model](https://www.sciencedirect.com/science/article/pii/S0167473005000457)
10 changes: 10 additions & 0 deletions docs/Module/Powerflow/Pole_mount.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ object pole
}
~~~

## Properties

### `direction`

~~~
double direction;
~~~

Bearing of the mounted equipment, an angle measured clockwise from North in degrees with vertex at the pole centerline.

# See also

* [[/Module/Powerflow/Pole.md]]
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ In addition, modules generally should be able to implement the following
It turns out that implementing these capabilities is not as easy as it
at first seems. In particular, the synchronization has typically been one
of the most challenging concepts for programmers to understand. Given
the amount of time spend in sync calls, it is recommended that
the amount of time spent in sync calls, it is recommended that
considerable time and effort be put into its design.

= Basic Synchronization =
Expand Down
4 changes: 2 additions & 2 deletions docs/Utilities/Create_poles.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ on using libraries.
Some network models include latitude and longitude information. When this information is present,
the line length information checked. If there is a discrepancy between these, a warning is printed
and the latitude/longitude information is used. The `--ignore_length` option will suppress this
warning. The `--ignore_location` warning will cause the model to use the line length data instead.
warning. The `--ignore_location` option will cause the model to use the line length data instead.

The `--include_network` adds a `#include "FILENAME"` directive in the output to ensure that the
resulting GLM file contains all the objects required to run the simulation, e.g.,
Expand All @@ -85,7 +85,7 @@ Pole and pole_mount objects are created with the following default properties:

* pole
- install_year: 2000
- tilt_angle: 0 deg
- tilt_degree: 0 deg
- tilt_direction: 0 deg
* pole_mount
height: 40 ft
Expand Down
13 changes: 7 additions & 6 deletions geodata/geodata_elevation.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def apply(data, options=default_options, config=default_config, warning=print):
# Elevation data processing
#

def get_elevation(pos,repourl=default_config["repourl"],cachedir=default_config["cachedir"]):
def get_elevation(pos,repo_url=default_config["repourl"],cachedir=default_config["cachedir"]):
"""Compute the elevations at the locations specified
Elevations are obtained for each entry in the args list. If the
Expand All @@ -148,21 +148,22 @@ def get_elevation(pos,repourl=default_config["repourl"],cachedir=default_config[
DataFrame Pandas dataframe containing the latitudes, longitudes,
and elevations.
"""
n,e = get_imagedata(pos,repourl,cachedir)
# elev_data (nparray) The elevation data from the image
_, elev_data = get_imagedata(pos,repo_url,cachedir)
row,col = get_rowcol(pos)
dx = 1.0-math.modf(abs(pos[1])*3600)[0]
dy = 1.0-math.modf(abs(pos[0])*3600)[0]
e00 = float(e[row][col])
e00 = float(elev_data[row][col])
if row > 0:
e10 = float(e[row-1][col])
e10 = float(elev_data[row-1][col])
else:
e10 = e00
if col > 0:
e01 = float(e[row][col-1])
e01 = float(elev_data[row][col-1])
else:
e01 = e00
if row > 0 and col > 0:
e11 = float(e[row-1][col-1])
e11 = float(elev_data[row-1][col-1])
else:
e11 = e00
e0 = dx*e00 + (1-dx)*e01
Expand Down
2 changes: 1 addition & 1 deletion geodata/geodata_powerline.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def TODO(value=float('nan')):
}

default_config = {
"cabletype_file" : f"{GLD_ETC}/geodata_powerline_cabletypes.csv",
"cabletype_file" : f"{GLD_ETC}/gridlabd/geodata_powerline_cabletypes.csv",
}

OPTIONS = default_options
Expand Down
Loading

0 comments on commit 936f76d

Please sign in to comment.