flixopt 2.2.0rc2__py3-none-any.whl → 3.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of flixopt might be problematic. Click here for more details.

Files changed (58) hide show
  1. flixopt/__init__.py +33 -4
  2. flixopt/aggregation.py +60 -80
  3. flixopt/calculation.py +395 -178
  4. flixopt/commons.py +1 -10
  5. flixopt/components.py +939 -448
  6. flixopt/config.py +553 -191
  7. flixopt/core.py +513 -846
  8. flixopt/effects.py +644 -178
  9. flixopt/elements.py +610 -355
  10. flixopt/features.py +394 -966
  11. flixopt/flow_system.py +736 -219
  12. flixopt/interface.py +1104 -302
  13. flixopt/io.py +103 -79
  14. flixopt/linear_converters.py +387 -95
  15. flixopt/modeling.py +759 -0
  16. flixopt/network_app.py +73 -39
  17. flixopt/plotting.py +294 -138
  18. flixopt/results.py +1253 -299
  19. flixopt/solvers.py +25 -21
  20. flixopt/structure.py +938 -396
  21. flixopt/utils.py +38 -12
  22. flixopt-3.0.0.dist-info/METADATA +209 -0
  23. flixopt-3.0.0.dist-info/RECORD +26 -0
  24. flixopt-3.0.0.dist-info/top_level.txt +1 -0
  25. docs/examples/00-Minimal Example.md +0 -5
  26. docs/examples/01-Basic Example.md +0 -5
  27. docs/examples/02-Complex Example.md +0 -10
  28. docs/examples/03-Calculation Modes.md +0 -5
  29. docs/examples/index.md +0 -5
  30. docs/faq/contribute.md +0 -61
  31. docs/faq/index.md +0 -3
  32. docs/images/architecture_flixOpt-pre2.0.0.png +0 -0
  33. docs/images/architecture_flixOpt.png +0 -0
  34. docs/images/flixopt-icon.svg +0 -1
  35. docs/javascripts/mathjax.js +0 -18
  36. docs/user-guide/Mathematical Notation/Bus.md +0 -33
  37. docs/user-guide/Mathematical Notation/Effects, Penalty & Objective.md +0 -132
  38. docs/user-guide/Mathematical Notation/Flow.md +0 -26
  39. docs/user-guide/Mathematical Notation/LinearConverter.md +0 -21
  40. docs/user-guide/Mathematical Notation/Piecewise.md +0 -49
  41. docs/user-guide/Mathematical Notation/Storage.md +0 -44
  42. docs/user-guide/Mathematical Notation/index.md +0 -22
  43. docs/user-guide/Mathematical Notation/others.md +0 -3
  44. docs/user-guide/index.md +0 -124
  45. flixopt/config.yaml +0 -10
  46. flixopt-2.2.0rc2.dist-info/METADATA +0 -167
  47. flixopt-2.2.0rc2.dist-info/RECORD +0 -54
  48. flixopt-2.2.0rc2.dist-info/top_level.txt +0 -5
  49. pics/architecture_flixOpt-pre2.0.0.png +0 -0
  50. pics/architecture_flixOpt.png +0 -0
  51. pics/flixOpt_plotting.jpg +0 -0
  52. pics/flixopt-icon.svg +0 -1
  53. pics/pics.pptx +0 -0
  54. scripts/extract_release_notes.py +0 -45
  55. scripts/gen_ref_pages.py +0 -54
  56. tests/ressources/Zeitreihen2020.csv +0 -35137
  57. {flixopt-2.2.0rc2.dist-info → flixopt-3.0.0.dist-info}/WHEEL +0 -0
  58. {flixopt-2.2.0rc2.dist-info → flixopt-3.0.0.dist-info}/licenses/LICENSE +0 -0
flixopt/network_app.py CHANGED
@@ -1,13 +1,14 @@
1
- import json
1
+ from __future__ import annotations
2
+
2
3
  import logging
3
4
  import socket
4
5
  import threading
5
- from typing import Any, Dict, List
6
+ from typing import TYPE_CHECKING, Any
6
7
 
7
8
  try:
8
9
  import dash_cytoscape as cyto
9
10
  import dash_daq as daq
10
- import networkx
11
+ import networkx as nx
11
12
  from dash import Dash, Input, Output, State, callback_context, dcc, html, no_update
12
13
  from werkzeug.serving import make_server
13
14
 
@@ -18,8 +19,10 @@ except ImportError as e:
18
19
  VISUALIZATION_ERROR = str(e)
19
20
 
20
21
  from .components import LinearConverter, Sink, Source, SourceAndSink, Storage
21
- from .elements import Bus, Component, Flow
22
- from .flow_system import FlowSystem
22
+ from .elements import Bus
23
+
24
+ if TYPE_CHECKING:
25
+ from .flow_system import FlowSystem
23
26
 
24
27
  logger = logging.getLogger('flixopt')
25
28
 
@@ -110,8 +113,16 @@ class VisualizationConfig:
110
113
  ]
111
114
 
112
115
 
113
- def flow_graph(flow_system: FlowSystem) -> networkx.DiGraph:
116
+ def flow_graph(flow_system: FlowSystem) -> nx.DiGraph:
114
117
  """Convert FlowSystem to NetworkX graph - simplified and more robust"""
118
+ if not DASH_CYTOSCAPE_AVAILABLE:
119
+ raise ImportError(
120
+ 'Network visualization requires optional dependencies. '
121
+ 'Install with: pip install flixopt[viz] or '
122
+ 'pip install dash dash-cytoscape networkx werkzeug. '
123
+ f'Original error: {VISUALIZATION_ERROR}'
124
+ )
125
+
115
126
  nodes = list(flow_system.components.values()) + list(flow_system.buses.values())
116
127
  edges = list(flow_system.flows.values())
117
128
 
@@ -141,7 +152,7 @@ def flow_graph(flow_system: FlowSystem) -> networkx.DiGraph:
141
152
  else:
142
153
  return 'rectangle'
143
154
 
144
- graph = networkx.DiGraph()
155
+ graph = nx.DiGraph()
145
156
 
146
157
  # Add nodes with attributes
147
158
  for node in nodes:
@@ -168,7 +179,7 @@ def flow_graph(flow_system: FlowSystem) -> networkx.DiGraph:
168
179
  return graph
169
180
 
170
181
 
171
- def make_cytoscape_elements(graph: networkx.DiGraph) -> List[Dict[str, Any]]:
182
+ def make_cytoscape_elements(graph: nx.DiGraph) -> list[dict[str, Any]]:
172
183
  """Convert NetworkX graph to Cytoscape elements"""
173
184
  elements = []
174
185
 
@@ -225,7 +236,7 @@ def create_color_picker_input(label: str, input_id: str, default_color: str):
225
236
  )
226
237
 
227
238
 
228
- def create_style_section(title: str, children: List):
239
+ def create_style_section(title: str, children: list):
229
240
  """Create a collapsible section for organizing controls"""
230
241
  return html.Div(
231
242
  [
@@ -378,7 +389,7 @@ def create_sidebar():
378
389
  )
379
390
 
380
391
 
381
- def shownetwork(graph: networkx.DiGraph):
392
+ def shownetwork(graph: nx.DiGraph):
382
393
  """Main function to create and run the network visualization"""
383
394
  if not DASH_CYTOSCAPE_AVAILABLE:
384
395
  raise ImportError(f'Required packages not available: {VISUALIZATION_ERROR}')
@@ -535,10 +546,46 @@ def shownetwork(graph: networkx.DiGraph):
535
546
 
536
547
  return sidebar_style, main_style
537
548
 
549
+ # Combined callback to handle both color scheme changes and reset
550
+ @app.callback(
551
+ [
552
+ Output('bus-color-picker', 'value'),
553
+ Output('source-color-picker', 'value'),
554
+ Output('sink-color-picker', 'value'),
555
+ Output('storage-color-picker', 'value'),
556
+ Output('converter-color-picker', 'value'),
557
+ ],
558
+ [Input('color-scheme-dropdown', 'value'), Input('reset-btn', 'n_clicks')],
559
+ )
560
+ def update_color_pickers(color_scheme, reset_clicks):
561
+ """Update color pickers when color scheme changes or reset is clicked"""
562
+ ctx = callback_context
563
+
564
+ # Determine which input triggered the callback
565
+ if ctx.triggered:
566
+ trigger_id = ctx.triggered[0]['prop_id'].split('.')[0]
567
+ if trigger_id == 'reset-btn' and reset_clicks and reset_clicks > 0:
568
+ # Reset was clicked, use default colors
569
+ colors = VisualizationConfig.DEFAULT_COLORS
570
+ else:
571
+ # Color scheme changed
572
+ colors = VisualizationConfig.COLOR_PRESETS.get(color_scheme, VisualizationConfig.DEFAULT_COLORS)
573
+ else:
574
+ # Initial load
575
+ colors = VisualizationConfig.COLOR_PRESETS.get(color_scheme, VisualizationConfig.DEFAULT_COLORS)
576
+
577
+ return (
578
+ {'hex': colors['Bus']},
579
+ {'hex': colors['Source']},
580
+ {'hex': colors['Sink']},
581
+ {'hex': colors['Storage']},
582
+ {'hex': colors['Converter']},
583
+ )
584
+
585
+ # Updated main visualization callback - simplified logic
538
586
  @app.callback(
539
587
  [Output('cytoscape', 'elements'), Output('cytoscape', 'stylesheet')],
540
588
  [
541
- Input('color-scheme-dropdown', 'value'),
542
589
  Input('bus-color-picker', 'value'),
543
590
  Input('source-color-picker', 'value'),
544
591
  Input('sink-color-picker', 'value'),
@@ -551,7 +598,6 @@ def shownetwork(graph: networkx.DiGraph):
551
598
  [State('elements-store', 'data')],
552
599
  )
553
600
  def update_visualization(
554
- color_scheme,
555
601
  bus_color,
556
602
  source_color,
557
603
  sink_color,
@@ -562,23 +608,20 @@ def shownetwork(graph: networkx.DiGraph):
562
608
  font_size,
563
609
  stored_elements,
564
610
  ):
611
+ """Update visualization based on current color picker values"""
565
612
  if not stored_elements:
566
613
  return no_update, no_update
567
614
 
568
- # Determine colors to use
569
- if any(picker for picker in [bus_color, source_color, sink_color, storage_color, converter_color, edge_color]):
570
- # Use custom colors from pickers
571
- colors = {
572
- 'Bus': bus_color.get('hex') if bus_color else '#7F8C8D',
573
- 'Source': source_color.get('hex') if source_color else '#F1C40F',
574
- 'Sink': sink_color.get('hex') if sink_color else '#F1C40F',
575
- 'Storage': storage_color.get('hex') if storage_color else '#2980B9',
576
- 'Converter': converter_color.get('hex') if converter_color else '#D35400',
577
- 'Other': '#27AE60',
578
- }
579
- else:
580
- # Use preset scheme
581
- colors = VisualizationConfig.COLOR_PRESETS.get(color_scheme, VisualizationConfig.DEFAULT_COLORS)
615
+ # Use colors from pickers (which are now synced with scheme selection)
616
+ default_colors = VisualizationConfig.DEFAULT_COLORS
617
+ colors = {
618
+ 'Bus': bus_color.get('hex') if bus_color else default_colors['Bus'],
619
+ 'Source': source_color.get('hex') if source_color else default_colors['Source'],
620
+ 'Sink': sink_color.get('hex') if sink_color else default_colors['Sink'],
621
+ 'Storage': storage_color.get('hex') if storage_color else default_colors['Storage'],
622
+ 'Converter': converter_color.get('hex') if converter_color else default_colors['Converter'],
623
+ 'Other': default_colors['Other'],
624
+ }
582
625
 
583
626
  # Update element colors
584
627
  updated_elements = []
@@ -681,15 +724,10 @@ def shownetwork(graph: networkx.DiGraph):
681
724
  def update_layout(selected_layout):
682
725
  return {'name': selected_layout}
683
726
 
684
- # Reset callback
727
+ # Reset callback for non-color-picker controls
685
728
  @app.callback(
686
729
  [
687
730
  Output('color-scheme-dropdown', 'value'),
688
- Output('bus-color-picker', 'value'),
689
- Output('source-color-picker', 'value'),
690
- Output('sink-color-picker', 'value'),
691
- Output('storage-color-picker', 'value'),
692
- Output('converter-color-picker', 'value'),
693
731
  Output('edge-color-picker', 'value'),
694
732
  Output('node-size-slider', 'value'),
695
733
  Output('font-size-slider', 'value'),
@@ -698,15 +736,11 @@ def shownetwork(graph: networkx.DiGraph):
698
736
  [Input('reset-btn', 'n_clicks')],
699
737
  )
700
738
  def reset_controls(n_clicks):
739
+ """Reset all controls to defaults (color pickers handled separately)"""
701
740
  if n_clicks and n_clicks > 0:
702
741
  return (
703
- 'Default', # color scheme
704
- {'hex': '#7F8C8D'}, # bus
705
- {'hex': '#F1C40F'}, # source
706
- {'hex': '#F1C40F'}, # sink
707
- {'hex': '#2980B9'}, # storage
708
- {'hex': '#D35400'}, # converter
709
- {'hex': '#808080'}, # edge
742
+ 'Default', # color scheme (will trigger color picker updates)
743
+ {'hex': '#808080'}, # edge color
710
744
  90, # node size
711
745
  10, # font size
712
746
  'klay', # layout