2025-02-14 20:18:03 +01:00
|
|
|
# These could be from the std math lib, but I like the numpy ones better personally
|
2025-02-14 21:42:21 +01:00
|
|
|
from numpy import sin, cos, pi, sqrt
|
2025-02-14 20:18:03 +01:00
|
|
|
|
2025-02-14 21:04:42 +01:00
|
|
|
# Pull a1 support
|
|
|
|
from a1_support import GRAVITY_ACC, WATER_DENSITY, HELP_MESSAGE
|
|
|
|
from a1_support import load_data, plot_water_height
|
|
|
|
|
2025-02-14 20:18:03 +01:00
|
|
|
# Fill these in with your details
|
|
|
|
__author__ = "Cal Wing"
|
|
|
|
__email__ = "cal@wing.id.au"
|
|
|
|
__date__ = "14/02/2025"
|
|
|
|
__version__ = "1.0.0"
|
|
|
|
|
2025-02-14 22:28:54 +01:00
|
|
|
# Task 1
|
2025-02-14 21:42:21 +01:00
|
|
|
def determine_power_used(water_mass: float, elevation: float,
|
|
|
|
pumping_time: float, efficiency: float) -> float:
|
2025-02-14 21:04:42 +01:00
|
|
|
"""
|
|
|
|
Calculates the power required to pump a certain mass of water a certain height
|
|
|
|
taking into account the pumping_time and efficiency.
|
|
|
|
|
|
|
|
Parameters:
|
|
|
|
water_mass (float): the mass of the water pumped [kg]
|
|
|
|
elevation (float): the height difference [m]
|
|
|
|
pumping_time (float): the amount of time the pump is running for [hrs]
|
|
|
|
efficiency (float): the conversion efficiency [%]
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
(float): the power required by the pump [kW]
|
|
|
|
"""
|
|
|
|
# Ideal energy needed to lift the water
|
|
|
|
potenital_energy = water_mass * GRAVITY_ACC * elevation # J = kg * m/s^2 * m = mgh
|
|
|
|
|
|
|
|
# Actual amount of energy needed based on eff
|
|
|
|
# Here an 85% eff means an extra 15% is needed to pump the water up
|
2025-02-14 22:28:54 +01:00
|
|
|
# [NOTE] I got stuck on this for a bit, unsure if it was my sleep deprived brain but took me
|
|
|
|
# me a bit to get the efficiency calc.
|
2025-02-14 21:33:43 +01:00
|
|
|
electrical_energy = potenital_energy / (efficiency/100) # J = J * SCALER
|
2025-02-14 20:18:03 +01:00
|
|
|
|
2025-02-14 21:04:42 +01:00
|
|
|
# Actual electrial power used to pump the water
|
|
|
|
power_used = electrical_energy / (pumping_time*60*60) # W = J / S = J / (hr*60*60)
|
|
|
|
|
2025-02-14 21:33:43 +01:00
|
|
|
return power_used / 1e3 # W -> kW
|
2025-02-14 20:18:03 +01:00
|
|
|
|
2025-02-14 21:15:53 +01:00
|
|
|
# Task 2
|
2025-02-14 21:42:21 +01:00
|
|
|
def determine_water_released(gen_power: float, elevation: float,
|
|
|
|
pumping_time: float, efficiency: float) -> float:
|
2025-02-14 21:15:53 +01:00
|
|
|
"""
|
2025-02-14 21:42:21 +01:00
|
|
|
Calculates the mass of water released required to generate a specified power
|
|
|
|
|
|
|
|
Parameters:
|
|
|
|
gen_power (float): the specified power to be generated [kW]
|
|
|
|
elevation (float): the height difference [m]
|
|
|
|
pumping_time (float): the time the pump is running for [hrs]
|
|
|
|
efficiency (float): the conversion efficiency [%]
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
(float): the mass of the water required [kg]
|
2025-02-14 21:15:53 +01:00
|
|
|
"""
|
|
|
|
|
|
|
|
# How much electrical engery was generated?
|
2025-02-14 21:33:43 +01:00
|
|
|
electrical_energy = (gen_power * 1e3) * (pumping_time*60*60) # J = W * S = (kW * 10^3) * (hrs*60*60)
|
2025-02-14 21:15:53 +01:00
|
|
|
|
|
|
|
# Need more potential energy to get electrial energy
|
|
|
|
# Again here for 85% eff need 15% more potenitial enegry to get pot-eng
|
2025-02-14 21:33:43 +01:00
|
|
|
potential_energy = electrical_energy * (efficiency/100) # J = J * Scaler
|
2025-02-14 21:15:53 +01:00
|
|
|
|
2025-02-14 21:33:43 +01:00
|
|
|
water_mass = potential_energy / (GRAVITY_ACC * elevation) # kg = J / (m/s^2 * m)
|
2025-02-14 21:15:53 +01:00
|
|
|
|
|
|
|
return water_mass
|
|
|
|
|
2025-02-14 21:33:43 +01:00
|
|
|
# Task 3
|
2025-02-14 21:42:21 +01:00
|
|
|
def determine_cost_to_pump(gen_power: float, pumping_time: float,
|
|
|
|
off_peak_tariff: float) -> float:
|
2025-02-14 21:36:10 +01:00
|
|
|
"""
|
|
|
|
Calculates the cost of using the pump during off peak period
|
|
|
|
|
|
|
|
Parameters:
|
|
|
|
gen_power (float): the amount of power generated by the pump [kW]
|
|
|
|
pumping_time (float): the amount of time the pump is running for [hrs]
|
|
|
|
off_peak_tariff (float): the off-peak tarriff cost for electricity [$/kWh]
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
(float): the cost of running the pump ($)
|
|
|
|
"""
|
|
|
|
|
|
|
|
cost = gen_power * pumping_time * off_peak_tariff
|
|
|
|
|
|
|
|
return cost
|
|
|
|
|
2025-02-14 21:42:21 +01:00
|
|
|
# Task 4
|
|
|
|
def calc_speed_at_outlet(water_height: float) -> float:
|
|
|
|
"""
|
|
|
|
Calculates the speed of the water at the outlet of the dam
|
|
|
|
|
|
|
|
Parameters:
|
|
|
|
water_height (float): the height of the water in the pipe [m]
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
(float): the speed of the water at the outlet [m/s]
|
|
|
|
"""
|
|
|
|
|
|
|
|
speed = sqrt(2 * water_height * GRAVITY_ACC)
|
|
|
|
|
|
|
|
return speed
|
|
|
|
|
|
|
|
# Task 5
|
|
|
|
def calc_new_water_height(old_water_height: float, reservoir_area: float,
|
|
|
|
outlet_area: float, time_inc: float) -> tuple[float, float]:
|
|
|
|
|
2025-02-14 21:45:36 +01:00
|
|
|
water_mass_out = outlet_area * calc_speed_at_outlet(old_water_height) \
|
|
|
|
* time_inc * WATER_DENSITY
|
2025-02-14 21:42:21 +01:00
|
|
|
|
2025-02-14 21:45:36 +01:00
|
|
|
new_water_height = old_water_height - \
|
|
|
|
(water_mass_out / (reservoir_area * WATER_DENSITY))
|
2025-02-14 21:36:10 +01:00
|
|
|
|
2025-02-14 21:45:36 +01:00
|
|
|
return new_water_height, water_mass_out
|
2025-02-14 20:18:03 +01:00
|
|
|
|
|
|
|
|
2025-02-14 22:28:54 +01:00
|
|
|
# Task 6
|
|
|
|
def calc_heights_water_out(initial_height: float, final_height: float,
|
|
|
|
reservoir_area: float, outlet_area: float,
|
|
|
|
time_inc: float
|
|
|
|
) -> tuple[tuple[float, ...], tuple[float, ...]]:
|
|
|
|
|
|
|
|
# Track the water height & mass
|
|
|
|
water_height, water_mass = [], []
|
|
|
|
|
|
|
|
# Do the first iteration
|
|
|
|
new_water_height, water_mass_out = \
|
|
|
|
calc_new_water_height(initial_height, reservoir_area,
|
|
|
|
outlet_area, time_inc)
|
|
|
|
|
|
|
|
# Store the new values
|
|
|
|
water_height.append(new_water_height)
|
|
|
|
water_mass.append(water_mass_out)
|
|
|
|
|
|
|
|
|
|
|
|
# Do the loop
|
|
|
|
while water_height[-1] > final_height:
|
|
|
|
new_water_height, water_mass_out = \
|
|
|
|
calc_new_water_height(water_height[-1], reservoir_area,
|
|
|
|
outlet_area, time_inc)
|
|
|
|
|
|
|
|
water_height.append(new_water_height)
|
|
|
|
water_mass.append(water_mass_out)
|
|
|
|
|
|
|
|
|
|
|
|
return water_height, water_mass
|
|
|
|
|
|
|
|
|
2025-02-20 18:45:22 +01:00
|
|
|
|
|
|
|
|
2025-02-14 21:04:42 +01:00
|
|
|
# See if I get what the task sheet wants
|
2025-02-14 22:28:54 +01:00
|
|
|
# [NOTE] It seems I am witing my own test suite :/ that wasn't the initention lol
|
2025-02-14 21:04:42 +01:00
|
|
|
def sheet_tasks():
|
2025-02-20 18:45:22 +01:00
|
|
|
from debug_lib import NO_EVAL, TUPLE_EVAL
|
|
|
|
from debug_lib import compair_outputs
|
2025-02-14 22:28:54 +01:00
|
|
|
|
2025-02-14 21:04:42 +01:00
|
|
|
TASKS = (
|
|
|
|
(determine_power_used, (5e6, 250, 8, 85), 500.9191176470588),
|
2025-02-14 21:36:10 +01:00
|
|
|
(determine_water_released, (300, 250, 8, 85), 2994495.4128440367),
|
2025-02-14 21:42:21 +01:00
|
|
|
(determine_cost_to_pump, (300, 8, 0.02), 48),
|
2025-02-14 21:45:36 +01:00
|
|
|
(calc_speed_at_outlet, (30,), 24.261079942986875),
|
2025-02-14 21:42:21 +01:00
|
|
|
(calc_new_water_height, (20, 40000, 1, 30), (19.985143183382704, 592567.1021442247)),
|
2025-02-14 22:28:54 +01:00
|
|
|
(calc_heights_water_out, (40, 5, 40000, 1, 30), ((39.97898928844613, 39.95798409574207, 39.93698442188801), (838016.4324684857, 837796.3120398963, 837576.1916037091), TUPLE_EVAL)),
|
2025-02-14 21:04:42 +01:00
|
|
|
)
|
2025-02-14 20:18:03 +01:00
|
|
|
|
2025-02-20 18:45:22 +01:00
|
|
|
compair_outputs(TASKS)
|
|
|
|
|
|
|
|
|
2025-02-14 20:13:04 +01:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2025-02-14 21:04:42 +01:00
|
|
|
sheet_tasks()
|