mirror of
https://gitlab.com/pamhyr/pamhyr2.git
synced 2026-10-30 03:20:41 +01:00
235 lines
7.2 KiB
Python
235 lines
7.2 KiB
Python
# WeatherParametersList.py -- Pamhyr
|
|
# Copyright (C) 2023-2025 INRAE
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
from copy import copy
|
|
from tools import trace, timer
|
|
|
|
from Model.Tools.PamhyrListExt import PamhyrModelList
|
|
from Model.Except import NotImplementedMethodeError
|
|
|
|
from Model.WeatherParameters.WeatherParameters import (
|
|
WeatherParameters,
|
|
WeatherParametersDefault,
|
|
)
|
|
from Model.WeatherParameters.WeatherParametersTypes import (
|
|
NotDefined, WeatherParam, AirTemperature, SpecificHumidity,
|
|
GlobalRadiation, ReferenceWindSpeed, GroundwaterTemperature,
|
|
GroundwaterFlowRate, Albedo, ShadingCoefficient, CloudCoverFraction
|
|
)
|
|
|
|
|
|
class WeatherParametersList(PamhyrModelList):
|
|
_sub_classes = [
|
|
WeatherParameters,
|
|
]
|
|
_default_types = [
|
|
"AT", "SH", "GR", "RWS", "GT", "GFR", "ALB", "SC", "CCF"
|
|
]
|
|
_default_values = {
|
|
"AT": 20.0,
|
|
"SH": 0.001,
|
|
"GR": 10.0,
|
|
"RWS": 1.0,
|
|
"GT": 0.0,
|
|
"GFR": 0.0,
|
|
"ALB": 0.06,
|
|
"SC": 0.15,
|
|
"CCF": 0.5,
|
|
}
|
|
|
|
def __init__(self, status=None):
|
|
super(WeatherParametersList, self).__init__(status=status)
|
|
self._default = []
|
|
self._init_missing_default_values()
|
|
|
|
@classmethod
|
|
def _db_load(cls, execute, data=None):
|
|
new = cls(status=data['status'])
|
|
|
|
if data is None:
|
|
data = {}
|
|
|
|
new._lst = WeatherParameters._db_load(
|
|
execute, data
|
|
)
|
|
|
|
data['loaded_pid'] = set()
|
|
new._default = WeatherParametersDefault._db_load(
|
|
execute, data
|
|
)
|
|
new._init_missing_default_values()
|
|
new._sort_default_values()
|
|
|
|
return new
|
|
|
|
def _db_save(self, execute, data=None):
|
|
execute(
|
|
"DELETE FROM weather_parameters " +
|
|
f"WHERE scenario = {self._status.scenario_id}"
|
|
)
|
|
execute(
|
|
"DELETE FROM weather_parameters_data " +
|
|
f"WHERE scenario = {self._status.scenario_id}"
|
|
)
|
|
execute(
|
|
"DELETE FROM weather_parameters_default " +
|
|
f"WHERE scenario = {self._status.scenario_id}"
|
|
)
|
|
|
|
if data is None:
|
|
data = {}
|
|
|
|
for wp in self._lst:
|
|
wp._db_save(execute, data=data)
|
|
|
|
for wp_default in self._default:
|
|
wp_default._db_save(execute, data=data)
|
|
|
|
return True
|
|
|
|
def _data_traversal(self,
|
|
predicate=lambda obj, data: True,
|
|
modifier=lambda obj, data: None,
|
|
data={}):
|
|
if predicate(self, data):
|
|
modifier(self, data)
|
|
|
|
for el in self._lst:
|
|
el._data_traversal(predicate, modifier, data)
|
|
|
|
for el in self._default:
|
|
el._data_traversal(predicate, modifier, data)
|
|
|
|
def _init_missing_default_values(self):
|
|
existing = [wp_default.type for wp_default in self.default]
|
|
for type in self._default_types:
|
|
if type not in existing:
|
|
self._default.append(
|
|
WeatherParametersDefault(
|
|
type=type,
|
|
value=self._default_values[type],
|
|
status=self._status,
|
|
)
|
|
)
|
|
|
|
self._sort_default_values()
|
|
|
|
def _sort_default_values(self):
|
|
self._default.sort(
|
|
key=lambda wp_default: self._default_types.index(wp_default.type)
|
|
if wp_default.type in self._default_types
|
|
else len(self._default_types)
|
|
)
|
|
|
|
def new(self, index, type="ND"):
|
|
if type == "AT":
|
|
n = AirTemperature(status=self._status)
|
|
elif type == "SH":
|
|
n = SpecificHumidity(status=self._status)
|
|
elif type == "GR":
|
|
n = GlobalRadiation(status=self._status)
|
|
elif type == "RWS":
|
|
n = ReferenceWindSpeed(status=self._status)
|
|
elif type == "GT":
|
|
n = GroundwaterTemperature(status=self._status)
|
|
elif type == "GFR":
|
|
n = GroundwaterFlowRate(status=self._status)
|
|
elif type == "ALB":
|
|
n = Albedo(status=self._status)
|
|
elif type == "SC":
|
|
n = ShadingCoefficient(status=self._status)
|
|
elif type == "CCF":
|
|
n = CloudCoverFraction(status=self._status)
|
|
else:
|
|
n = NotDefined(status=self._status)
|
|
self._lst.insert(index, n)
|
|
self._status.modified()
|
|
return n
|
|
|
|
def split_reach(self, reach, profile, reach1, reach2):
|
|
profiles = reach.reach.profiles
|
|
split_index = profiles.index(profile)
|
|
parts = [
|
|
(
|
|
reach1,
|
|
0,
|
|
split_index,
|
|
dict(zip(
|
|
profiles[:split_index + 1],
|
|
reach1.reach.profiles
|
|
))
|
|
),
|
|
(
|
|
reach2,
|
|
split_index,
|
|
len(profiles) - 1,
|
|
dict(zip(
|
|
profiles[split_index:],
|
|
reach2.reach.profiles
|
|
))
|
|
),
|
|
]
|
|
weather_parameters = [
|
|
weather_parameter
|
|
for weather_parameter in self.lst
|
|
if weather_parameter.reach is reach
|
|
]
|
|
clones = []
|
|
|
|
for weather_parameter in weather_parameters:
|
|
if (weather_parameter.begin_section not in profiles or
|
|
weather_parameter.end_section not in profiles):
|
|
continue
|
|
|
|
begin = profiles.index(weather_parameter.begin_section)
|
|
end = profiles.index(weather_parameter.end_section)
|
|
lower, upper = sorted((begin, end))
|
|
reverse = begin > end
|
|
|
|
for new_reach, part_lower, part_upper, sections in parts:
|
|
clipped_lower = max(lower, part_lower)
|
|
clipped_upper = min(upper, part_upper)
|
|
if clipped_lower >= clipped_upper:
|
|
continue
|
|
|
|
begin_index = clipped_upper if reverse else clipped_lower
|
|
end_index = clipped_lower if reverse else clipped_upper
|
|
clones.append(weather_parameter.cloned_for(
|
|
new_reach,
|
|
sections[profiles[begin_index]],
|
|
sections[profiles[end_index]]
|
|
))
|
|
|
|
if clones:
|
|
self._lst.extend(clones)
|
|
self._status.modified()
|
|
|
|
@property
|
|
def Weather_Parameters_List(self):
|
|
return self.lst
|
|
|
|
@property
|
|
def default(self):
|
|
return self._default.copy()
|
|
|
|
def default_for_type(self, type):
|
|
for wp_default in self.default:
|
|
if wp_default.type == type:
|
|
return wp_default
|
|
return None
|