diff --git a/src/Model/InitialConditions/InitialConditions.py b/src/Model/InitialConditions/InitialConditions.py index 57d582c2b3399a1001e5c257b2eba33d365e0898..9b2264879009d420618c3cb568b8fe6cf31ada63 100644 --- a/src/Model/InitialConditions/InitialConditions.py +++ b/src/Model/InitialConditions/InitialConditions.py @@ -4,33 +4,121 @@ from copy import copy, deepcopy from tools import trace, timer from functools import reduce -class Data(object): - def __init__(self, reach = None, status = None): +from Model.DB import SQLSubModel + +class Data(SQLSubModel): + def __init__(self, name:str = "", + comment:str = "", reach = None, + kp:float = 0.0, discharge:float = 0.0, + height:float = 0.0, + status = None): super(Data, self).__init__() self._status = status self._reach = reach - self._name = "" - self._comment = "" + self._name = name + self._comment = comment - self._kp = 0.0 - self._discharge = 0.0 + self._kp = kp + self._discharge = discharge self._speed = 0.0 self._elevation = 0.0 - self._height = 0.0 + self._height = height - def copy(self): - new = Data(self._reach, self._status) + if self._kp != 0.0: + self._update_from_kp() + if self._height != 0.0: + self._update_from_height() + if self._discharge != 0.0: + self._update_from_discharge() + + @classmethod + def _sql_create(cls, execute): + execute(""" + CREATE TABLE initial_conditions( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + ind INTEGER NOT NULL, + name TEXT NOT NULL, + comment TEXT NOT NULL, + reach INTEGER, + kp REAL NOT NULL, + discharge REAL NOT NULL, + height REAL NOT NULL, + FOREIGN KEY(reach) REFERENCES river_reach(id) + ) + """) + + return cls._create_submodel(execute) + + @classmethod + def _sql_update(cls, execute, version): + return cls._update_submodel(execute, version) + + @classmethod + def _sql_load(cls, execute, data = None): + id = data["reach"].id + table = execute( + "SELECT ind, name, comment, kp, discharge, height " + + "FROM initial_conditions " + + f"WHERE reach = {id}" + ) + + new = [] + + for _ in table: + new.append(None) + + for row in table: + ind = row[0] + name = row[1] + comment = row[2] + kp = row[3] + discharge = row[4] + height = row[5] + + d = cls( + reach = data["reach"], + status = data["status"], + name = name, + comment = comment, + kp = kp, + discharge = discharge, + height = height, + ) - new._name = self._name - new._comment = self._comment - new._kp = self._kp - new._discharge = self._discharge - new._speed = self._speed - new._elevation = self._elevation - new._height = self._height + new[ind] = d + + return new + + def _sql_save(self, execute, data = None): + ind = data["ind"] + + execute( + "INSERT INTO " + + "initial_conditions(ind, name, comment, kp, discharge, height, reach) " + + "VALUES (" + + f"{ind}, '{self._sql_format(self.name)}', " + + f"'{self._sql_format(self._comment)}', " + + f"{self._kp}, {self._discharge}, {self._height}, " + + f"{self._reach.id}" + + ")" + ) + + return True + + + def copy(self): + new = Data( + name = self.name, + comment = self._comment, + kp = self._kp, + discharge = self._discharge, + height = self._height, + reach = self._reach, + status = self._status, + ) return new @@ -92,8 +180,8 @@ class Data(object): self._kp = float(value) self._update_from_kp() elif key == "speed": - self._speed = float(value) # Not supposed to be modified + self._speed = float(value) elif key == "discharge": self._discharge = float(value) self._update_from_discharge() @@ -106,7 +194,12 @@ class Data(object): self._status.modified() -class InitialConditions(object): + +class InitialConditions(SQLSubModel): + _sub_classes = [ + Data + ] + def __init__(self, reach = None, status = None): super(InitialConditions, self).__init__() @@ -115,6 +208,42 @@ class InitialConditions(object): self._reach = reach self._data = [] + @classmethod + def _sql_create(cls, execute): + return cls._create_submodel(execute) + + @classmethod + def _sql_update(cls, execute, version): + return cls._update_submodel(execute, version) + + @classmethod + def _sql_load(cls, execute, data = None): + new = cls( + reach = data["reach"], + status = data["status"] + ) + + new._data = Data._sql_load( + execute, + data = data + ) + + if new._data is None: + return None + + return new + + def _sql_save(self, execute, data = None): + ok = True + + ind = 0 + for d in self._data: + data["ind"] = ind + ok &= d._sql_save(execute, data) + ind += 1 + + return ok + def __len__(self): return len(self._data) diff --git a/src/Model/InitialConditions/InitialConditionsDict.py b/src/Model/InitialConditions/InitialConditionsDict.py index 71d707d07af230f0f5fb419451af4fbdf5a3f48b..5e8d5fbac9764527a8843312683c932ecbca3ef2 100644 --- a/src/Model/InitialConditions/InitialConditionsDict.py +++ b/src/Model/InitialConditions/InitialConditionsDict.py @@ -3,9 +3,14 @@ from copy import copy from tools import trace, timer +from Model.DB import SQLSubModel from Model.InitialConditions.InitialConditions import InitialConditions -class InitialConditionsDict(object): +class InitialConditionsDict(SQLSubModel): + _sub_classes = [ + InitialConditions, + ] + def __init__(self, status = None): super(InitialConditionsDict, self).__init__() @@ -13,6 +18,44 @@ class InitialConditionsDict(object): self._reach = {} + @classmethod + def _sql_create(cls, execute): + return cls._create_submodel(execute) + + @classmethod + def _sql_update(cls, execute, version): + return cls._update_submodel(execute, version) + + @classmethod + def _sql_load(cls, execute, data = None): + new = cls(status = data["status"]) + + for reach in data["edges"]: + data["reach"] = reach + + ic = InitialConditions._sql_load( + execute, + data = data + ) + + if ic is not None: + new._reach[reach] = ic + + return new + + def _sql_save(self, execute, data = None): + ok = True + if data is None: + data = {} + + execute("DELETE FROM initial_conditions") + + for reach in self._reach: + data["reach"] = reach + ok &= self._reach[reach]._sql_save(execute, data) + + return ok + def __len__(self): return len(self._reach) diff --git a/src/Model/River.py b/src/Model/River.py index 8a4f6fc69d184e6284f4661bc8d1053a0ba0ae2e..15f3e6e4e2c2c3aed9c8f19f04c1ab422d23eac4 100644 --- a/src/Model/River.py +++ b/src/Model/River.py @@ -182,7 +182,7 @@ class River(Graph, SQLSubModel): RiverReach, BoundaryConditionList, LateralContributionList, - # InitialConditionsDict, + InitialConditionsDict, StricklersList, SolverParametersList, ] @@ -237,6 +237,13 @@ class River(Graph, SQLSubModel): execute, data ) + + # Initial conditions + new._initial_conditions = InitialConditionsDict._sql_load( + execute, + data + ) + # Stricklers new._stricklers = StricklersList._sql_load( execute, @@ -256,8 +263,10 @@ class River(Graph, SQLSubModel): def _sql_save(self, execute, data = None): objs = (self._nodes + self._edges) objs.append(self._boundary_condition) + objs.append(self._initial_conditions) objs.append(self._lateral_contribution) objs.append(self._stricklers) + for solver in self._parameters: objs.append(self._parameters[solver])