-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparameters.py
148 lines (120 loc) · 3.46 KB
/
parameters.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import copy
import dataclasses
import json
from abc import ABC
import numpy as np
class Parameters(ABC):
@staticmethod
def get_bounds():
pass
def to_initial_params(self):
pass
def from_params(self, params):
field_names = [field.name for field in dataclasses.fields(self)]
bounds = self.get_bounds()
for i, (name, bound) in enumerate(zip(field_names, bounds)):
value = params[i]
if not (bound[0] <= value <= bound[1]):
raise ValueError(f"Value {value} for '{name}' is out of bounds {bound}")
setattr(self, name, value)
self.validate()
def validate(self):
params = self.to_initial_params()
field_names = [field.name for field in dataclasses.fields(self)]
for i, (param, bound) in enumerate(zip(params, self.get_bounds())):
if not (bound[0] <= param <= bound[1]):
raise ValueError(f"Attribute '{field_names[i]}' with value {param} is out of bounds {bound}")
def copy(self):
return copy.deepcopy(self)
def __post_init__(self):
self.validate()
def __str__(self):
return json.dumps(self.__dict__, indent=4)
@dataclasses.dataclass
class SubbasinParameters(Parameters):
t0_is: float = 0.01
t0_boc: float = 0.1
t0_soc_uo: float = 0.1
t0_soc_lo: float = 0.1
t0_soh_uo: float = 75.0
t0_soh_lo: float = 0.0
t1_is: float = 0.01
t1_boc: float = 0.01
t1_soc: float = 0.01
t1_soh: float = 0.0
t2_is: float = 0.01
t2_boc: float = 0.01
t2_soc: float = 0.01
t2_soh: float = 0.0
t3_is: float = 0.01
t3_soc: float = 0.01
@staticmethod
def get_bounds():
bounds = (
(0.01, 100), # t0_is
(0.01, 0.5), # t0_boc
(0.01, 0.5), # t0_soc_uo
(0.01, 0.5), # t0_soc_lo
(0, 100), # t0_soh_uo
(0, 50), # t0_soh_lo
(0.01, 100), # t1_is
(0.01, 0.5), # t1_boc
(0.01, 0.5), # t1_soc
(0, 100), # t1_soh
(0.01, 100), # t2_is
(0.01, 0.5), # t2_boc
(0.01, 0.5), # t2_soc
(0, 100), # t2_soh
(0.01, 100), # t3_is
(0.01, 0.5), # t3_soc
)
return bounds
def to_initial_params(self):
return np.array([
self.t0_is,
self.t0_boc,
self.t0_soc_uo,
self.t0_soc_lo,
self.t0_soh_uo,
self.t0_soh_lo,
self.t1_is,
self.t1_boc,
self.t1_soc,
self.t1_soh,
self.t2_is,
self.t2_boc,
self.t2_soc,
self.t2_soh,
self.t3_is,
self.t3_soc,
])
@dataclasses.dataclass
class JunctionParameters(Parameters):
@staticmethod
def get_bounds():
return ()
def to_initial_params(self):
return np.array([])
@dataclasses.dataclass
class SinkParameters(Parameters):
@staticmethod
def get_bounds():
return ()
def to_initial_params(self):
return np.array([])
@dataclasses.dataclass
class ReachParameters(Parameters):
k: float = 0.01
x: float = 0.01
@staticmethod
def get_bounds():
bounds = (
(0.01, 5.0), # k
(0.01, 0.5) # x
)
return bounds
def to_initial_params(self):
return np.array([
self.k,
self.x,
])