Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,17 @@ PyADM1/

See [Installation](docs/user_guide/installation.md).


## Google Colab Examples

To get started quickly without local installation, you can run the following examples directly in Google Colab:

- **Basic Digester**: Single-stage digester with substrate feed and integrated gas storage.
[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/dgaida/PyADM1ODE/blob/master/examples/colab_01_basic_digester.ipynb)

- **Complex Plant**: Two-stage biogas plant with hydrolysis, digester, CHP, and sensors.
[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/dgaida/PyADM1ODE/blob/master/examples/colab_02_complex_plant.ipynb)

## Quick Start

See [Quickstart](docs/user_guide/quickstart.md).
Expand Down
8 changes: 4 additions & 4 deletions docs/de/examples/basic_digester.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Basis-Fermenter Beispiel
n<div align="center">
<a href="https://colab.research.google.com/github/dgaida/PyADM1ODE/blob/master/examples/colab_01_basic_digester.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="In Google Colab öffnen (Basis)"></a>
<a href="https://colab.research.google.com/github/dgaida/PyADM1ODE/blob/master/examples/colab_02_complex_plant.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="In Google Colab öffnen (Komplex)"></a>
</div>

[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/dgaida/PyADM1ODE/blob/master/examples/colab_01_basic_digester.ipynb)



Das Beispiel [examples/01_basic_digester.py](https://github.com/dgaida/PyADM1ODE/blob/master/examples/01_basic_digester.py) zeigt die einfachstmögliche PyADM1-Konfiguration: einen einzelnen Fermenter mit Substratzulauf und integriertem Gasspeicher.

Expand Down
2 changes: 2 additions & 0 deletions docs/de/examples/two_stage_plant.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Zweistufige Biogasanlage Beispiel

[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/dgaida/PyADM1ODE/blob/master/examples/colab_02_complex_plant.ipynb)

Das Beispiel [examples/02_two_stage_plant.py](https://github.com/dgaida/PyADM1ODE/blob/master/examples/02_two_stage_plant.py) zeigt eine komplette zweistufige Biogasanlage mit mechanischen Komponenten, Energieintegration und umfassender Prozessüberwachung.

## Anlagenschema
Expand Down
4 changes: 3 additions & 1 deletion docs/de/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ Willkommen bei PyADM1ODE - Einem Python-Framework zur Modellierung, Simulation u

## 🎯 Quick Links
<div align="center">
<a href="https://colab.research.google.com/github/dgaida/PyADM1ODE/blob/master/examples/colab_01_basic_digester.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"></a>
<a href="https://colab.research.google.com/github/dgaida/PyADM1ODE/blob/master/examples/colab_01_basic_digester.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Basic Digester Example"></a>
&nbsp;
<a href="https://colab.research.google.com/github/dgaida/PyADM1ODE/blob/master/examples/colab_02_complex_plant.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Complex Plant Example"></a>
</div>

<div class="grid cards" markdown>
Expand Down
2 changes: 2 additions & 0 deletions docs/en/examples/basic_digester.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Basic Digester Example

[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/dgaida/PyADM1ODE/blob/master/examples/colab_01_basic_digester.ipynb)

The [examples/basic_digester.py](https://github.com/dgaida/PyADM1ODE/blob/master/examples/01_basic_digester.py) example demonstrates the simplest possible PyADM1 configuration: a single digester with substrate feed and integrated gas storage.

## System Architecture
Expand Down
2 changes: 2 additions & 0 deletions docs/en/examples/two_stage_plant.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Two-Stage Biogas Plant Example

[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/dgaida/PyADM1ODE/blob/master/examples/colab_02_complex_plant.ipynb)

The [examples/two_stage_plant.py](https://github.com/dgaida/PyADM1ODE/blob/master/examples/02_two_stage_plant.py) example demonstrates a complete two-stage biogas plant with mechanical components, energy integration, and comprehensive process monitoring.

## Plant Schematic
Expand Down
4 changes: 3 additions & 1 deletion docs/en/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ Welcome to PyADM1ODE - A Python framework for modeling, simulating, and optimizi

## 🎯 Quick Links
<div align="center">
<a href="https://colab.research.google.com/github/dgaida/PyADM1ODE/blob/master/examples/colab_01_basic_digester.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"></a>
<a href="https://colab.research.google.com/github/dgaida/PyADM1ODE/blob/master/examples/colab_01_basic_digester.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Basic Digester Example"></a>
&nbsp;
<a href="https://colab.research.google.com/github/dgaida/PyADM1ODE/blob/master/examples/colab_02_complex_plant.ipynb"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Complex Plant Example"></a>
</div>

<div class="grid cards" markdown>
Expand Down
12 changes: 5 additions & 7 deletions examples/colab_01_basic_digester.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,7 @@
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"from pathlib import Path\n",
"import numpy as np\n",
"from pyadm1.configurator.plant_builder import BiogasPlant\n",
"from pyadm1.substrates.feedstock import Feedstock\n",
"from pyadm1.core.adm1 import get_state_zero_from_initial_state\n",
Expand Down Expand Up @@ -86,15 +84,15 @@
"plant = BiogasPlant(\"Quickstart Plant\")\n",
"configurator = PlantConfigurator(plant, feedstock)\n",
"\n",
"# 4. Define substrate feed (Corn silage: 15 m³/d, Manure: 10 m³/d)\n",
"# 4. Define substrate feed (Corn silage: 15 m\u00b3/d, Manure: 10 m\u00b3/d)\n",
"Q_substrates = [15, 10, 0, 0, 0, 0, 0, 0, 0, 0]\n",
"\n",
"# 5. Add digester\n",
"configurator.add_digester(\n",
" digester_id=\"main_digester\",\n",
" V_liq=2000.0,\n",
" V_gas=300.0,\n",
" T_ad=308.15, # 35°C\n",
" T_ad=308.15, # 35\u00b0C\n",
" name=\"Main Digester\",\n",
" load_initial_state=True,\n",
" initial_state_file=str(initial_state_file),\n",
Expand Down Expand Up @@ -125,8 +123,8 @@
" time = result[\"time\"]\n",
" comp_results = result[\"components\"][\"main_digester\"]\n",
" print(f\"Day {time:.1f}:\")\n",
" print(f\" Biogas: {comp_results.get('Q_gas', 0):>8.1f} m³/d\")\n",
" print(f\" Methane: {comp_results.get('Q_ch4', 0):>8.1f} m³/d\")\n",
" print(f\" Biogas: {comp_results.get('Q_gas', 0):>8.1f} m\u00b3/d\")\n",
" print(f\" Methane: {comp_results.get('Q_ch4', 0):>8.1f} m\u00b3/d\")\n",
" print(f\" pH: {comp_results.get('pH', 0):>8.2f}\")"
]
}
Expand All @@ -152,4 +150,4 @@
},
"nbformat": 4,
"nbformat_minor": 4
}
}
16 changes: 6 additions & 10 deletions examples/colab_02_complex_plant.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,9 @@
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"from pathlib import Path\n",
"from pyadm1.configurator.plant_builder import BiogasPlant\n",
"from pyadm1.substrates.feedstock import Feedstock\n",
"from pyadm1.configurator.plant_configurator import PlantConfigurator\n",
"from pyadm1.components.mechanical.mixer import Mixer\n",
"from pyadm1.components.mechanical.pump import Pump"
"from pyadm1.configurator.plant_configurator import PlantConfigurator\n"
]
},
{
Expand Down Expand Up @@ -81,7 +77,7 @@
" digester_id=\"digester_1\",\n",
" V_liq=1977.0,\n",
" V_gas=304.0,\n",
" T_ad=318.15, # 45°C\n",
" T_ad=318.15, # 45\u00b0C\n",
" load_initial_state=True,\n",
" initial_state_file=initial_state_file,\n",
" Q_substrates=[15, 10, 0, 0, 0, 0, 0, 0, 0, 0]\n",
Expand All @@ -92,7 +88,7 @@
" digester_id=\"digester_2\",\n",
" V_liq=1000.0,\n",
" V_gas=150.0,\n",
" T_ad=308.15, # 35°C\n",
" T_ad=308.15, # 35\u00b0C\n",
" load_initial_state=True,\n",
" initial_state_file=initial_state_file,\n",
" Q_substrates=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n",
Expand Down Expand Up @@ -131,8 +127,8 @@
"outputs": [],
"source": [
"final = results[-1][\"components\"]\n",
"print(f\"Total Biogas: {final['digester_1']['Q_gas'] + final['digester_2']['Q_gas']:.1f} m³/d\")\n",
"print(f\"Total Methane: {final['digester_1']['Q_ch4'] + final['digester_2']['Q_ch4']:.1f} m³/d\")\n",
"print(f\"Total Biogas: {final['digester_1']['Q_gas'] + final['digester_2']['Q_gas']:.1f} m\u00b3/d\")\n",
"print(f\"Total Methane: {final['digester_1']['Q_ch4'] + final['digester_2']['Q_ch4']:.1f} m\u00b3/d\")\n",
"print(f\"CHP Power: {final['chp_1']['P_el']:.1f} kW\")"
]
}
Expand All @@ -158,4 +154,4 @@
},
"nbformat": 4,
"nbformat_minor": 4
}
}
13 changes: 9 additions & 4 deletions pyadm1/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,18 @@
# package is not installed
__version__ = "unknown"

# Initialize DLL loader before importing other modules
from pyadm1.utils.dll_loader import load_dlls

load_dlls()

# Core imports
from .configurator import BiogasPlant
from .substrates import Feedstock
from .simulation import Simulator
from .configurator import BiogasPlant # noqa: E402
from .substrates import Feedstock # noqa: E402
from .simulation import Simulator # noqa: E402

# Component base classes
from .components import Component, ComponentType
from .components import Component, ComponentType # noqa: E402

__all__ = [
"__version__",
Expand Down
36 changes: 6 additions & 30 deletions pyadm1/components/biological/digester.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,42 +8,18 @@
for anaerobic digestion in a component-based framework.
"""


def try_load_clr():
import platform

if platform.system() == "Darwin":
return None
try:
import clr

return clr
except Exception as e:
print(e)
return None


clr = try_load_clr()


import os # noqa: E402 # type: ignore

from typing import Dict, Any, List, Optional # noqa: E402 # type: ignore
import numpy as np # noqa: E402 # type: ignore

import numpy as np
from typing import Dict, Any, List, Optional
from ..base import Component, ComponentType # noqa: E402 # type: ignore
from ...core import ADM1 # noqa: E402 # type: ignore
from ...substrates import Feedstock # noqa: E402 # type: ignore
from ...simulation import Simulator # noqa: E402 # type: ignore
from ..energy import GasStorage # noqa: E402 # type: ignore

if clr is None:
raise RuntimeError("CLR features unavailable on this platform")
else:
# CLR reference must be added before importing from DLL
dll_path = os.path.join(os.path.dirname(__file__), "..", "..", "dlls")
clr.AddReference(os.path.join(dll_path, "plant"))
from biogas import ADMstate # noqa: E402 # type: ignore
try:
from biogas import ADMstate
except ImportError:
ADMstate = None


class Digester(Component):
Expand Down
33 changes: 6 additions & 27 deletions pyadm1/components/biological/hydrolysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,39 +49,18 @@
... })
"""


def _try_load_clr():
import platform

if platform.system() == "Darwin":
return None
try:
import clr

return clr
except Exception as e:
print(e)
return None


clr = _try_load_clr()

import os # noqa: E402
from typing import Dict, Any, List, Optional # noqa: E402
import numpy as np # noqa: E402

import numpy as np
from typing import Dict, Any, List, Optional
from ..base import Component, ComponentType # noqa: E402
from ...core import ADM1 # noqa: E402
from ...substrates import Feedstock # noqa: E402
from ...simulation import Simulator # noqa: E402
from ..energy import GasStorage # noqa: E402

if clr is None:
raise RuntimeError("CLR features unavailable on this platform")
else:
dll_path = os.path.join(os.path.dirname(__file__), "..", "..", "dlls")
clr.AddReference(os.path.join(dll_path, "plant"))
from biogas import ADMstate # noqa: E402 # type: ignore
try:
from biogas import ADMstate
except ImportError:
ADMstate = None


class Hydrolysis(Component):
Expand Down
23 changes: 4 additions & 19 deletions pyadm1/components/energy/heating.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
Units: UA in kW/K, heat flows in kW, auxiliary energy in kWh.
"""

import os
import platform
from pathlib import Path
from typing import Dict, Any, Optional

Expand All @@ -45,26 +43,13 @@ def _init_heating_dll() -> None:
return
_DLL_INIT_DONE = True

if platform.system() == "Darwin":
return

try:
import clr # type: ignore

dll_path = os.path.join(os.path.dirname(__file__), "..", "..", "dlls")
clr.AddReference(os.path.join(dll_path, "biogas"))
clr.AddReference(os.path.join(dll_path, "substrates"))
clr.AddReference(os.path.join(dll_path, "physchem"))
except Exception:
return

try:
import biogas as _biogas # type: ignore
from physchem import physValue as _phys_value # type: ignore
import biogas as _biogas
from physchem import physValue as _phys_value
except Exception:
try:
import biogas as _biogas # type: ignore
from physchem import PhysValue as _phys_value # type: ignore
import biogas as _biogas
from physchem import PhysValue as _phys_value
except Exception:
return

Expand Down
10 changes: 4 additions & 6 deletions pyadm1/core/adm1.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@
"""

import logging
import os
import clr
import numpy as np
import pandas as pd
from typing import List, Tuple, Optional
Expand All @@ -58,10 +56,10 @@
logger = logging.getLogger(__name__)


# CLR reference must be added before importing from DLL
dll_path = os.path.join(os.path.dirname(__file__), "..", "dlls")
clr.AddReference(os.path.join(dll_path, "plant"))
from biogas import ADMstate # noqa: E402 # type: ignore
try:
from biogas import ADMstate
except ImportError:
ADMstate = None


def get_state_zero_from_initial_state(csv_file: str) -> List[float]:
Expand Down
Loading
Loading