```
import math
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
```

# Firewood math and metrics

Firewood metrics and simulating firewood use

We inherited a large pile of firewood for a wood burning stove. We’ve never had a wood burning stove. People who actually know something about, or sell, firewood for such devices talk about *cords* and *face cords* of firewood. Time to learn something about firewood metrics.

`%matplotlib inline`

## Cords and face cords

A cord of firewood is about \(4 \text{ft} \times 4 \text{ft} \times 8 \text{ft}\), or \(128 \text{ft}^3\) in volume. Typically, a log for a wood burning stove is approximately \(16 \text{in}\). So, you can slice a full cord into three *face cords*, each being \(4 \text{ft} \times 1 \frac {1}{3} \text{ft} \times 8 \text{ft}\). Of course, that’s not all wood because there is a bunch of air in the stack. But, I’m not so interested in weight, I’m interested in number of logs and how long our stack of wood will last.

## How much wood do we have?

It appears that when our stack of logs was full, it was two cords (~16 feet long).

Obviously, the number of logs in a face cord is dependent on the diameter of the logs. I did a rough count and got about 20 logs wide by 10 logs high for each face cord.

```
= 10
pile_height_logs = 20
pile_width_logs = pile_height_logs * pile_width_logs
logs_per_facecord = 3 * logs_per_facecord
logs_per_cord print("Logs per face cord: {}".format(logs_per_facecord))
print("Logs per cord: {}".format(logs_per_cord))
```

```
Logs per face cord: 200
Logs per cord: 600
```

```
= 6
num_facecords = logs_per_facecord * num_facecords
tot_logs print("Total logs in full pile: {}".format(tot_logs))
```

`Total logs in full pile: 1200`

We’ve used some wood - maybe about 75% of a face cord.

```
= 0.75
num_facecords_used = logs_per_facecord * (num_facecords - num_facecords_used)
tot_logs_remaining print("Total logs left in partial pile: {}".format(int(tot_logs_remaining)))
```

`Total logs left in partial pile: 1050`

## How much wood do we use?

On a winter day in which we keep the stove going from morning until night, we use approximately 12-14 logs.

`= 13 logs_per_day `

The largest source of uncertainty is the number of *equivalent burning days* (EBD) in which we use the stove. Some days we might just burn a few logs in the evening. Here’s an estimate of EBD by month:

`= [5, 10, 5, 5, 2, 1, 2, 1, 3, 5, 5, 10] ebd_month_mean `

```
= [logs_per_day * ebd for ebd in ebd_month_mean]
logs_per_month_mean print(logs_per_month_mean)
= sum(logs_per_month_mean)
logs_per_year print("Total logs burned per year: {}".format(logs_per_year))
```

```
[65, 130, 65, 65, 26, 13, 26, 13, 39, 65, 65, 130]
Total logs burned per year: 702
```

## How long would a cord last?

`print("One cord lasts ~ {:.2f} years.".format(logs_per_cord / logs_per_year))`

`One cord lasts ~ 0.85 years.`

`print("Two cords lasts ~ {:.2f} years.".format(2 * logs_per_cord / logs_per_year))`

`Two cords lasts ~ 1.71 years.`

## Simulating firewood use

The largest component of uncertainty is our monthly usage. Let’s assume that log usage can be approximated by a normal distribution with monthly means specified by `logs_per_month_mean`

and monthly standard deviations equal to the square root of the means.

`= [math.sqrt(mean) for mean in logs_per_month_mean] logs_per_month_sd `

Let’s have the simulation clock tick in months and we’ll simulate until we run out of logs. We’ll record the month in which that happens.

```
def logsim(numlogs, logs_per_month_mean, logs_per_month_sd):
= 0
period = period % 12
month
while numlogs > 0:
= round(np.random.normal(logs_per_month_mean[month], logs_per_month_sd[month]))
logs_used -= logs_used
numlogs += 1
period = period % 12
month
return period
```

```
= 10000
nsim = 0
sim = []
stockout_period = tot_logs_remaining
num_logs_current
while sim < nsim:
= logsim(num_logs_current, logs_per_month_mean, logs_per_month_sd)
so_prd
stockout_period.append(so_prd)+= 1
sim
print(stockout_period[:100])
```

`[18, 19, 19, 16, 17, 16, 16, 16, 17, 16, 19, 20, 20, 16, 20, 18, 16, 16, 18, 18, 19, 18, 19, 19, 18, 16, 21, 19, 16, 20, 19, 16, 16, 20, 16, 17, 21, 16, 16, 16, 20, 16, 19, 19, 16, 17, 19, 17, 19, 21, 19, 18, 19, 17, 16, 18, 19, 17, 19, 17, 19, 17, 19, 18, 19, 16, 19, 17, 19, 18, 21, 19, 16, 19, 16, 17, 16, 21, 17, 17, 19, 19, 18, 18, 19, 20, 16, 20, 19, 17, 19, 18, 17, 17, 16, 17, 17, 19, 17, 18]`

Let’s compute summary stats and create a histogram.

```
= pd.DataFrame({'stockout_period': stockout_period})
stockout_df = stockout_df.describe()
stockout_stats stockout_stats
```

stockout_period | |
---|---|

count | 10000.000000 |

mean | 17.659300 |

std | 1.426474 |

min | 15.000000 |

25% | 17.000000 |

50% | 17.000000 |

75% | 19.000000 |

max | 22.000000 |

```
= int(stockout_stats.loc['min'])-1
minbin = int(stockout_stats.loc['max'])+1
maxbin = np.linspace(minbin, maxbin, maxbin - minbin + 1)
bins bins
```

`array([14., 15., 16., 17., 18., 19., 20., 21., 22., 23.])`

```
=bins) so_df.hist(bins
```

```
array([[<matplotlib.axes._subplots.AxesSubplot object at 0x7fc4df3dcd30>]],
dtype=object)
```

```
= pd.Period('2019-01-01',freq='M')
start_period = start_period + int(stockout_stats.loc['50%'])
median_stockout = start_period + int(stockout_stats.loc['25%'])
q1_stockout = start_period + int(stockout_stats.loc['75%']) q3_stockout
```

```
print("The median stockout period is: {}".format(median_stockout))
print("The IQR for the stockout period is: {} - {}".format(q1_stockout, q3_stockout))
```

```
The median stockout period is: 2020-06
The IQR for the stockout period is: 2020-06 - 2020-08
```

Looks like the log pile will be gone in summer of 2020.

## Reuse

## Citation

```
@online{isken2019,
author = {Mark Isken},
title = {Firewood Math and Metrics},
date = {2019-01-02},
langid = {en}
}
```