Skip to content

Commit

Permalink
Merge pull request #55 from LBNL-ETA/guide-update
Browse files Browse the repository at this point in the history
Guide update
  • Loading branch information
TammieYu authored Mar 8, 2024
2 parents 1f9af7a + 125abe4 commit 6b4137d
Show file tree
Hide file tree
Showing 4 changed files with 204 additions and 14 deletions.
Binary file added docs/assets/daylight_factor.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 15 additions & 12 deletions docs/how-to/guide_ep1.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,19 @@ from pyenergyplus.dataset import ref_models, weather_files
!!! tip "Tips: Reference EnergyPlus models and weather files"
The `pyenergyplus.dataset` module contains a dictionary of EnergyPlus models and weather files. The keys are the names of the models and weather files. The values are the file paths to the models and weather files.

```python
ref_models.keys()
```
>>> ref_models.keys()
dict_keys([
'full_service_restaurant', 'hospital', 'large_hotel',
'large_office', 'medium_office', 'midrise_apartment',
'outpatient', 'primary_school', 'quick_service_restaurant',
'secondary_school', 'small_hotel', 'small_office',
'standalone_retail', 'strip_mall', 'supermarket', 'warehouse'
])
```

> ```
dict_keys([
'full_service_restaurant', 'hospital', 'large_hotel',
'large_office', 'medium_office', 'midrise_apartment',
'outpatient', 'primary_school', 'quick_service_restaurant',
'secondary_school', 'small_hotel', 'small_office',
'standalone_retail', 'strip_mall', 'supermarket', 'warehouse'
])
> ```

## 1 Initialize an EnergyPlus model

Expand Down Expand Up @@ -62,11 +65,11 @@ epmodel = fr.load_energyplus_model(idf)
You can access any EnergyPlus model objects (simulation parameters) as you would do to a class attribute. The EnergyPlus model objects share the same name as that in the Input Data File (IDF) but in lower case separated by underscores. For example, the `FenestrationSurface:Detailed` object in IDF is `fenestration_surface_detailed` in `EnergyPlusModel`.

```python
>>> epmodel.fenestration_surface_detailed
```
epmodel.fenestration_surface_detailed
```
> ```
{'Perimeter_bot_ZN_1_Wall_South_Window': FenestrationSurfaceDetailed(surface_type=<SurfaceType1.window: 'Window'>, construction_name='Window Non-res Fixed', building_surface_name='Perimeter_bot_ZN_1_Wall_South', outside_boundary_condition_object=None, view_factor_to_ground=<CeilingHeightEnum.autocalculate: 'Autocalculate'>, frame_and_divider_name=None, multiplier=1.0, number_of_vertices=NumberOfVertice2(root=4.0), vertex_1_x_coordinate=1.5, vertex_1_y_coordinate=0.0, vertex_1_z_coordinate=2.3293, vertex_2_x_coordinate=1.5, vertex_2_y_coordinate=0.0, vertex_2_z_coordinate=1.0213, vertex_3_x_coordinate=10.5, vertex_3_y_coordinate=0.0, vertex_3_z_coordinate=1.0213, vertex_4_x_coordinate=10.5, vertex_4_y_coordinate=0.0, vertex_4_z_coordinate=2.3293)}'
```
>```
!!! example "Example: Edit the `fenestration_surface_detailed` object"
Expand Down
185 changes: 185 additions & 0 deletions docs/how-to/guide_rad7.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
# How to set up a workflow configuration for Radiance simulation?

**What is daylight factor?**

Daylight factor (DF) is the ratio of the interior horizontal illuminance to the exterior unobsturcted horizontal illuminance under overcast sky conditions. The higher the daylight factor, the more daylight is available in the room. A minimum daylight factor of 2% is usually recommended for critical visual task zones.

## Workflow

1. Build a Radiance model
2. Generate a CIE overcast sky
3. Use raytracing to get the interior horizontal illuminance
4. Compute the daylight factor

## 0. Import the required classes and functions

```python
import datatime
import frads as fr
import pyradiance as pr
import numpy as np
```

## 1. Build a Radiance model

If you already have a Radiance model setup, please have a octree file storing the scene files and continue on to the next step. If not, follow below to set up a sample Radiance model. See [How to setup a simple rtrace workflow?](guide_rad1.md) for more details.

Use `gen room` in a command line interface to generate
a simple Radiance model. The example 'aroom' is a open-office sized side-lit room with four same-sized windows. The room will be 12 meters wide, 14 meters deep, a floor to floor height of 4 meters, and a ceiling height of 3 meters. Each window is 2.5 meters in width and 1.8 meters in height and has a sill height of 1 meter. Windows are 0.4 meters apart from each other. Finally, the facade has a thickness of 0.1 meters.

```
$ gen room 12 14 4 3 \
-w 0.4 1 2.5 1.8 \
-w 3.3 1 2.5 1.8 \
-w 6.2 1 2.5 1.8 \
-w 9.1 1 2.5 1.8 \
-t 0.1 -n aroom
```

In a Python environment, call `pyradiance.oconv` to generate a `octree` file storing the material and geometry files generated from the `gen room` command in the 'Objects' directory

```python
fpaths = ["Objects/materials_aroom.mat",
"Objects/ceiling_aroom.rad",
"Objects/wall_aroom.rad",
"Objects/floor_aroom.rad",
"Objects/window_00_aroom.rad",
"Objects/window_01_aroom.rad",
"Objects/window_02_aroom.rad",
"Objects/window_03_aroom.rad",
]
```

```python
room_octree = "aroom.oct"
with open(room_octree, 'wb') as f:
f.write(pr.oconv(*fpaths))
```

## 2. Generate a CIE overcast sky

Use `pyradiance.gensky` to generate a CIE overcast sky. The function returns a brightness function (skyfunc) to vary the brightness of the glow material. We will assume the overcast sky has a diffuse horizontal illuminance of 10,000 lux (horizontal diffuse irradiance of 55.866 w/m2).

```python
dif_hor_illum = 10000
dif_hor_ird = dif_hor_illum / 179
```
```python
sky_func = pr.gensky(
dt=datetime.datetime(2024, 12, 21, 12, 0),
cloudy=True,
horizontal_brightness=dif_hor_ird, # (1)
)

print(sky_func)
```

1. zenith brightness is computed from the horizontal diffuse irradiance (in watts/meter2)

> ```
> void brightfunc skyfunc
> 2 skybr skybright.cal
> 0
> 3 2 2.286e+01 3.557e+00
> ```
```python
sky_glow = "skyfunc glow sky_glow 0 0 4 1 1 1 0".encode()
sky = "sky_glow source sky 0 0 4 0 0 1 180".encode()
```
```python
sky_scene = sky_func + b'\n' + sky_glow + b'\n' + sky
```

```python title="add sky scene to octree"
room_sky_octree = f"aroom_37_122_1221_1200.oct"
with open(room_sky_octree, "wb") as f:
f.write(pr.oconv(stdin=sky_descr, octree=room_octree))
```


## 3. Use raytracing to get the interior horizontal illuminance

Generate a grid of horizontal workplane sensors for interior horizontal illuminance computation. See [How to setup a simple rtrace workflow?](guide_rad1.md) for more details.

```python title="generate grid sensors based on the floor polygon"
floor_primitives = fr.unpack_primitives("Objects/floor_aroom.rad")
floor_polygon = fr.parse_polygon(floor_primitives[0])
grid = fr.gen_grid(floor_polygon, 1, 0.75)
```

Use `pyrandiance.rtrace` to compute ray tracing from the sensors. The function returns the irradiance results of all sensors in bytes.

```python title="rtrace to get irradiance"
option = ["-I+", "-ab", "1", "-ad", "64", "-aa", "0", "-lw", "0.01"]
rays = "\n".join([" ".join(map(str, row)) for row in grid])
ird_results = pr.rtrace(
rays.encode(), room_sky_octree, params=option, header=False
)
print(ird_results)
```
The sensor data are separeted by '\n'.

Each sensor data has rgb channels irradiance separated by '\t'

> ```'4.386912e+00\t4.386912e+00\t4.386912e+00\t\n2.373928e+00\t2.373928e+00\t2.373928e+00\t ... 0.000000e+00\t0.000000e+00\t0.000000e+00\t\n' ```
```python title="reformat the irradiance result"
rows = ird_results.decode().strip().split("\n")
data = [
[float(element) for element in row.split("\t") if element != ""]
for row in rows
]
ird_array = np.array(data)
```

Apply coefficients to convert irradiance into illuminance

```python title="convert irradiance to illuminance"
ird_array[:, 0] *= 47.4 #red
ird_array[:, 1] *= 119.9 #blue
ird_array[:, 2] *= 11.6 #green
illum = np.sum(ird_array, axis=1)
```

## 4. Compute the daylight factor


```python title="daylight factor = interior illuminance / exterior illuminance * 100"
df = illum / dif_hor_illum * 100
```

### data visualization

```python title="import visualization packages"
import matplotlib.pyplot as plt
```

```python
fig, ax = plt.subplots()
x = [data[0] for data in grid]
y = [data[1] for data in grid]
_plot = ax.scatter(
x,
y,
c=df,
cmap="plasma",
s=15,
vmin=0,
vmax=max(df),
rasterized=True,
)
ax.set(
xlabel="x position [m]",
ylabel="y position [m]",
)

fig.colorbar(_plot, ax=ax, label="Daylight Factor [%]")
fig.tight_layout()
```

![daylight_factor](../assets/daylight_factor.png)
6 changes: 4 additions & 2 deletions docs/how-to/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@

4. How to simulate spatial daylight autonomy using two-phase method?

6. How to simulate annual glare index using five-phase method?
5. How to simulate annual glare index using five-phase method?

7. How to simulate annual melanopic equivalent daylight illuminance?
6. How to simulate annual melanopic equivalent daylight illuminance?

7. [How to calculate daylight factor?](guide_rad7.md)

## EnergyPlus

Expand Down

0 comments on commit 6b4137d

Please sign in to comment.