Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

upgrade 1D #390

Merged
merged 44 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
d95ba9a
Remove setting views on schema upgrade
margrietpalm Oct 23, 2024
cc2ab37
Merge branch 'master' into margriet_389_schema_300_1D
margrietpalm Oct 23, 2024
9d03000
* Implement easy renames
margrietpalm Oct 23, 2024
d6220d1
Modify compute_bottom_level to work without manhole_id.
margrietpalm Oct 29, 2024
b10e584
Modify ConnectionNodes.get_1d2d_exchange_levels to work without manho…
margrietpalm Oct 29, 2024
6979b97
Modify connection_nodes.set_bottom_levels to work without manhole_id.
margrietpalm Oct 29, 2024
ab9cdac
Remove remaining occurances of manhole_id and use is_manhole were needed
margrietpalm Oct 29, 2024
2d8d0b3
Remove shape and width as ConnectionNode attributes
margrietpalm Oct 29, 2024
ec73ce8
Update docstring of Grid.from_connection_nodes
margrietpalm Oct 30, 2024
9b52b34
Modify tabulate_builtin for width and height as floats
margrietpalm Oct 30, 2024
ca04337
Modify tabulate_egg for width and height as floats
margrietpalm Oct 30, 2024
632a44f
Modify tabulate_closed_rectangle for width and height as floats
margrietpalm Oct 30, 2024
c4a369d
Modify _parse_tabulated to work with cross section table instead of w…
margrietpalm Oct 30, 2024
661b03f
Extend _parse_tabulated tests
margrietpalm Oct 30, 2024
f757e1e
Add cross_section_definition to CrossSectionDefinition
margrietpalm Oct 30, 2024
613f139
Fix tests that failed due to changes in reading cross section dimensions
margrietpalm Nov 4, 2024
165cc98
Read cross section definition from different tables
margrietpalm Oct 30, 2024
f6b489f
Add method to extract unique CrossSectionDefinitions
margrietpalm Nov 4, 2024
de6dba4
Add function to map unique cross section definitions to associated ta…
margrietpalm Nov 4, 2024
09849e1
Fix db tests
margrietpalm Nov 4, 2024
e98a008
Clean up new code for cross section definitions
margrietpalm Nov 5, 2024
f35990f
Merge branch 'margriet_389_schema_300_1D' of github.com:nens/threedig…
margrietpalm Nov 5, 2024
1de6b80
Use node_open_water_detection in ConnectionNodes.is_closed
margrietpalm Nov 5, 2024
7a32e3a
Read vegetation related parameters into CrossSectionDefinition
margrietpalm Nov 5, 2024
b83b717
Fix processing of changed vegetation fields in set_friction_vegetatio…
margrietpalm Nov 5, 2024
38fb132
Revert "Use node_open_water_detection in ConnectionNodes.is_closed"
margrietpalm Nov 5, 2024
4573d6d
Fixes and prep for obstacle.affects_* parameters
margrietpalm Nov 5, 2024
9b1bd47
Implement use of node_open_water_detection setting
margrietpalm Nov 5, 2024
14f3478
Read obstacles.affects parameters and use them in Obstacles.compute_d…
margrietpalm Nov 6, 2024
54894d1
Use obstacle.affects_ settings for 1d2d obstacles
margrietpalm Nov 6, 2024
fb586fb
Make integration test pass :D
margrietpalm Nov 6, 2024
5aabff9
Make typehint backwards compatible
margrietpalm Nov 6, 2024
bf627d4
Clean up db tests
margrietpalm Nov 6, 2024
57c05ee
Fix getting pumps from schematisation
margrietpalm Nov 7, 2024
9a8503b
Update TODOs
margrietpalm Nov 7, 2024
114cb67
Read friction settings for Pipe, Orifice, Culvert and Weir from Mater…
margrietpalm Nov 7, 2024
ef19b3b
Clean up
margrietpalm Nov 11, 2024
981e2ea
Fix reading surfaces
margrietpalm Nov 11, 2024
14b1e9f
Merge branch 'master' into margriet_389_schema_300_1D
margrietpalm Nov 11, 2024
b9ce3c9
Add reading material_id to get_pipes
margrietpalm Nov 12, 2024
ba1bc99
Add manhole_id to gridadmin
margrietpalm Nov 18, 2024
bcba3a1
Rename has_channel to is_channel
margrietpalm Nov 18, 2024
4e3dbf0
Remove duplicate lines
margrietpalm Nov 19, 2024
950cbaf
Bump schema version
margrietpalm Nov 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions integration_tests/test_bergermeer.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ def test_integration(tmp_path, filename):
NodeType.NODE_1D_BOUNDARIES: 4,
}
assert np.count_nonzero(f["nodes"]["is_manhole"][:] == 1) == 42
is_manhole = f["nodes"]["is_manhole"][:] == 1
assert np.all(f["nodes"]["zoom_category"][is_manhole] != -9999)
assert np.count_nonzero(f["nodes"]["content_pk"][:] > 0) == 1360
assert (
np.count_nonzero(np.isfinite(f["nodes"]["initial_waterlevel"][:])) == 2531
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def get_version():

install_requires = [
"numpy>=1.15,<3.0",
"threedi-schema==0.227.*",
"threedi-schema @ git+https://github.com/nens/threedi-schema.git@margriet_89_schema_300_1D",
"shapely>=2",
"pyproj>=3",
"condenser[geo]>=0.1.1",
Expand Down
27 changes: 19 additions & 8 deletions threedigrid_builder/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
GridAdminOut,
SQLite,
)
from threedigrid_builder.interface.db import map_cross_section_definition

__all__ = ["make_grid", "make_gridadmin"]

Expand Down Expand Up @@ -87,7 +88,7 @@ def _make_gridadmin(
grid.meta.has_groundwater_flow, node_id_counter, line_id_counter
)

grid.set_obstacles(db.get_obstacles())
grid.set_obstacles_2d(db.get_obstacles())
grid.set_boundary_conditions_2d(
db.get_boundary_conditions_2d(),
quadtree,
Expand All @@ -101,6 +102,20 @@ def _make_gridadmin(
connection_nodes = db.get_connection_nodes()
if grid_settings.use_1d_flow and len(connection_nodes) > 0:
progress_callback(0.8, "Constructing 1D computational grid...")
locations = db.get_cross_section_locations()
pipes = db.get_pipes()
weirs = db.get_weirs()
culverts = db.get_culverts()
orifices = db.get_orifices()
cross_section_definitions = db.get_cross_section_definitions()
(
cross_section_definitions_unique,
mapping,
) = cross_section_definitions.get_unique()
map_cross_section_definition(
[locations, orifices, pipes, culverts, weirs], mapping
)

Comment on lines +105 to +118
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading of cross section locations, pipes, weirs, culverts and orifices is moved up so the extracted cross section definitions can be properly mapped.

cn_grid = Grid.from_connection_nodes(
connection_nodes=connection_nodes,
node_id_counter=node_id_counter,
Expand All @@ -109,6 +124,7 @@ def _make_gridadmin(
grid += cn_grid

channels = db.get_channels()

potential_breaches = db.get_potential_breaches()
breach_points = potential_breaches.project_on_channels(channels).merge()

Expand All @@ -125,13 +141,11 @@ def _make_gridadmin(
connection_node_offset=connection_node_first_id,
)

locations = db.get_cross_section_locations()
locations.apply_to_lines(channel_grid.lines, channels)
windshieldings = db.get_windshieldings()
windshieldings.apply_to_lines(channel_grid.lines)
grid += channel_grid

pipes = db.get_pipes()
grid += Grid.from_linear_objects(
connection_nodes=connection_nodes,
objects=pipes,
Expand All @@ -145,7 +159,6 @@ def _make_gridadmin(
connection_node_offset=connection_node_first_id,
)

culverts = db.get_culverts()
grid += Grid.from_linear_objects(
connection_nodes=connection_nodes,
objects=culverts,
Expand All @@ -159,15 +172,14 @@ def _make_gridadmin(
connection_node_offset=connection_node_first_id,
)

weirs = db.get_weirs()
orifices = db.get_orifices()
grid += grid.from_structures(
connection_nodes=connection_nodes,
weirs=weirs,
orifices=orifices,
line_id_counter=line_id_counter,
connection_node_offset=connection_node_first_id,
)
grid.set_cross_sections(cross_section_definitions_unique)

grid.set_calculation_types()
grid.set_bottom_levels()
Expand All @@ -179,7 +191,6 @@ def _make_gridadmin(
culverts=culverts,
)
grid.set_boundary_conditions_1d(db.get_boundary_conditions_1d())
grid.set_cross_sections(db.get_cross_section_definitions())
grid.set_pumps(db.get_pumps())

if grid.nodes.has_1d and grid.nodes.has_2d:
Expand All @@ -195,8 +206,8 @@ def _make_gridadmin(
culverts=culverts,
potential_breaches=potential_breaches,
line_id_counter=line_id_counter,
node_open_water_detection=grid_settings.node_open_water_detection,
)

if grid.meta.has_groundwater:
channels.apply_has_groundwater_exchange(grid.nodes, grid.lines)
pipes.apply_has_groundwater_exchange(grid.nodes, grid.lines)
Expand Down
2 changes: 1 addition & 1 deletion threedigrid_builder/base/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class Node:
breach_ids: Tuple[int, int] # referring to 1 or 2 ids of potential breaches
has_dem_averaged: int # Boolean attribute to tell if dem is averaged for node.
boundary_type: BoundaryType
manhole_id: int # referring to the id of a manhole
margrietpalm marked this conversation as resolved.
Show resolved Hide resolved
is_manhole: bool # node represents a manhole
drain_level: float # Drain level entered for manholes
initial_waterlevel: float
zoom_category: int
Expand Down
1 change: 1 addition & 0 deletions threedigrid_builder/base/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class GridSettings:
grid_space: float
dist_calc_points: float
kmax: int
node_open_water_detection: int
embedded_cutoff_threshold: float = 0.05
max_angle_1d_advection: float = 0.4 * np.pi

Expand Down
31 changes: 18 additions & 13 deletions threedigrid_builder/grid/connection_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,12 @@ class ConnectionNode:
the_geom: shapely.Geometry
code: str
storage_area: float
manhole_id: int
is_manhole: bool
margrietpalm marked this conversation as resolved.
Show resolved Hide resolved
calculation_type: CalculationType
manhole_indicator: int
bottom_level: float
drain_level: float
surface_level: float
shape: str # enum with classes "00", "01", "02"
width: float
initial_waterlevel: float
display_name: str
zoom_category: int
Expand Down Expand Up @@ -59,7 +57,7 @@ def get_nodes(self, node_id_counter):
- node_type: NODE_1D_STORAGE or NODE_1D_NO_STORAGE depending on storage_area
- calculation_type: from calculation_type (which comes from manhole)
- dmax: from bottom_level (which comes from manhole)
- manhole_id: id of associated manhole.
- is_manhole: node is a manhole
- drain_level: drain_level of associated manhole.
- storage_area: area of connection_node.
"""
Expand All @@ -77,7 +75,7 @@ def get_nodes(self, node_id_counter):
node_type=node_type,
calculation_type=self.calculation_type,
dmax=self.bottom_level,
manhole_id=self.manhole_id,
is_manhole=~np.isnan(self.bottom_level),
drain_level=self.drain_level,
storage_area=self.storage_area,
display_name=self.display_name,
Expand All @@ -93,6 +91,14 @@ def is_closed(self, content_pk):
"""
return self.storage_area[self.id_to_index(content_pk)] >= 0

def is_channel(self, content_pk, channels):
"""Whether object is connected to a channel"""
has_channel = np.logical_or(
np.isin(self.id, channels.connection_node_start_id),
Copy link
Collaborator

@martijn-siemerink martijn-siemerink Nov 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ik heb nog wel vraagteken bij deze check. Wat nu als de connection_node_start_id ook aan een pipe zit? Dan is dat nu altijd een channel, ondanks dat het misschien een manhole is en is_closed logischer is. Ik overzie het niet helemaal, maar potentieel is dit te strict.

als kcu bekend is hier voor aanliggende 1d2d verbinding zou ik die checken, ook omdat de dpumax uiteindelijk gezet wordt voor de 1d2d line.

LineType enum definieert de kcu types

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dit lijkt me niet de plek om zoiets aan te passen; dit doet namelijk niet meer dan checken of iets een channel is. Als dat de lading niet dekt moet hooguit de naam worden aangepast.

Ik overzie het niet helemaal, maar potentieel is dit te strict. Als kcu bekend is hier voor aanliggende 1d2d verbinding zou ik die checken, ook omdat de dpumax uiteindelijk gezet wordt voor de 1d2d line.

Lijkt me iets wat aangepast moet worden in het kiezen tussen is_closed en is_channel: https://github.com/nens/threedigrid-builder/blob/margriet_389_schema_300_1D/threedigrid_builder/grid/grid.py#L757-L765. Maar ik snap nog niet helemaal welke logica je hier zou willen zien. Is dat iets als:

if node_open_water_detection == 0 and isinstance(objects, ConnectionNodes):
  if line.kcu != -9999:
      is_closed = (line.kcu == LINE_1D2D_SINGLE_CONNECTED_CLOSED or line.kcu == INE_1D2D_DOUBLE_CONNECTED_CLOSED)
  else:
      is_closed = is_channel()

np.isin(self.id, channels.connection_node_end_id),
)
return has_channel[content_pk]

def get_1d2d_exchange_levels(self, content_pk, channels, locations, **kwargs):
"""Compute the exchange level (dpumax) for 1D-2D flowlines.

Expand All @@ -109,17 +115,16 @@ def get_1d2d_exchange_levels(self, content_pk, channels, locations, **kwargs):
"""
# get the corresponding connection_node ids and indexes
connection_node_idx = self.id_to_index(content_pk)
is_manhole = self.manhole_id[connection_node_idx] != -9999
is_manhole = ~np.isnan(self.bottom_level[connection_node_idx])
is_manhole_idx = connection_node_idx[is_manhole]

# Check if manhole has drain_level below bottom_level
has_lower_drn_lvl = (
self.drain_level[is_manhole_idx] < self.bottom_level[is_manhole_idx]
)
if np.any(has_lower_drn_lvl):
ids = self.manhole_id[is_manhole_idx[has_lower_drn_lvl]]
ids = self.id[is_manhole_idx[has_lower_drn_lvl]]
logger.warning(
f"Manholes {sorted(ids.tolist())} have a "
f"ConnectionNode {sorted(ids.tolist())} have a "
f"bottom_level that is above drain_level."
)

Expand All @@ -143,7 +148,6 @@ def get_1d2d_exchange_levels(self, content_pk, channels, locations, **kwargs):
_put_if_less(dpumax, cn_idx_with_channel, drain_level)
# filter out connection nodes that were not in node_idx (non-connected ones)
dpumax = dpumax[connection_node_idx]

# for manholes: put in the drain level
dpumax[is_manhole] = self.drain_level[is_manhole_idx]
return dpumax
Expand Down Expand Up @@ -270,12 +274,13 @@ def set_bottom_levels(nodes: Nodes, lines: Lines):
dmax = np.fmin(nodes.dmax[node_idx], dmax_per_node)

# Check if the new node dmax is below the original manhole dmax
is_manhole = nodes.manhole_id[node_idx] != -9999
is_manhole = nodes.is_manhole[node_idx]

has_lower_dmax = dmax[is_manhole] < nodes.dmax[node_idx[is_manhole]]
if np.any(has_lower_dmax):
ids = nodes.manhole_id[node_idx[is_manhole][has_lower_dmax]]
ids = nodes.id[node_idx[is_manhole][has_lower_dmax]]
logger.warning(
f"Manholes {sorted(ids.tolist())} have a "
f"Nodes {sorted(ids.tolist())} have a "
f"bottom_level that is above one ore more of the following connected "
f"objects: channel reference level, pipe/culvert invert level, "
f"weir/orifice crest level."
Expand Down
Loading
Loading