RunFeemsSim 0.4.4__tar.gz → 0.5.0__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: RunFeemsSim
3
- Version: 0.4.4
3
+ Version: 0.5.0
4
4
  Summary: A library for running feems simulation
5
5
  Author-email: Kevin Koosup Yum <kevinkoosup.yum@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: RunFeemsSim
3
- Version: 0.4.4
3
+ Version: 0.5.0
4
4
  Summary: A library for running feems simulation
5
5
  Author-email: Kevin Koosup Yum <kevinkoosup.yum@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "RunFeemsSim"
7
- version = "0.4.4"
7
+ version = "0.5.0"
8
8
  description = "A library for running feems simulation"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -3,14 +3,20 @@ import random
3
3
 
4
4
  import numpy as np
5
5
  import pandas as pd
6
- from feems.components_model.component_electric import Genset
6
+ from feems.components_model.component_electric import (
7
+ COGES,
8
+ ElectricComponent,
9
+ ElectricMachine,
10
+ Genset,
11
+ )
7
12
  from feems.components_model.component_mechanical import (
13
+ COGAS,
8
14
  EngineMultiFuel,
9
15
  FuelCharacteristics,
10
16
  )
11
17
  from feems.fuel import FuelOrigin, FuelSpecifiedBy, TypeFuel
12
- from feems.system_model import FuelOption
13
- from feems.types_for_feems import EngineCycleType, TypeComponent
18
+ from feems.system_model import ElectricPowerSystem, FuelOption
19
+ from feems.types_for_feems import EngineCycleType, TypeComponent, TypePower
14
20
  from MachSysS.convert_to_feems import convert_proto_propulsion_system_to_feems
15
21
  from MachSysS.gymir_result_pb2 import (
16
22
  GymirResult,
@@ -343,3 +349,115 @@ def test_machinery_calculation_multifuel():
343
349
  < 1e-2
344
350
  )
345
351
 
352
+
353
+ def _build_coges_electric_system(eff_curve: np.ndarray) -> ElectricPowerSystem:
354
+ """Build a minimal ElectricPowerSystem with a multi-fuel COGES (LNG + H2) and an other_load."""
355
+ generator = ElectricMachine(
356
+ type_=TypeComponent.GENERATOR,
357
+ name="COGES Gen",
358
+ rated_power=1000,
359
+ rated_speed=3000,
360
+ power_type=TypePower.POWER_SOURCE,
361
+ switchboard_id=1,
362
+ )
363
+ cogas = COGAS(
364
+ name="COGAS",
365
+ rated_power=1000,
366
+ rated_speed=3000,
367
+ eff_curve=eff_curve,
368
+ fuel_type=TypeFuel.NATURAL_GAS,
369
+ fuel_origin=FuelOrigin.FOSSIL,
370
+ multi_fuel_characteristics=[
371
+ FuelCharacteristics(
372
+ main_fuel_type=TypeFuel.NATURAL_GAS,
373
+ main_fuel_origin=FuelOrigin.FOSSIL,
374
+ eff_curve=eff_curve,
375
+ engine_cycle_type=EngineCycleType.BRAYTON,
376
+ ),
377
+ FuelCharacteristics(
378
+ main_fuel_type=TypeFuel.HYDROGEN,
379
+ main_fuel_origin=FuelOrigin.RENEWABLE_NON_BIO,
380
+ eff_curve=eff_curve,
381
+ engine_cycle_type=EngineCycleType.BRAYTON,
382
+ ),
383
+ ],
384
+ )
385
+ coges_component = COGES(name="COGES unit", cogas=cogas, generator=generator)
386
+
387
+ other_load = ElectricComponent(
388
+ type_=TypeComponent.OTHER_LOAD,
389
+ name="Aux load",
390
+ rated_power=500,
391
+ power_type=TypePower.POWER_CONSUMER,
392
+ switchboard_id=1,
393
+ eff_curve=np.array([[0.0, 1.0], [1.0, 1.0]]),
394
+ )
395
+ return ElectricPowerSystem(
396
+ name="COGES test system",
397
+ power_plant_components=[coges_component, other_load],
398
+ bus_tie_connections=[],
399
+ )
400
+
401
+
402
+ def test_machinery_calculation_multifuel_coges():
403
+ eff_curve = np.array([[0.0, 0.30], [0.5, 0.40], [1.0, 0.44]])
404
+ system = _build_coges_electric_system(eff_curve)
405
+
406
+ machinery_calculation = MachineryCalculation(feems_system=system)
407
+
408
+ run_kwargs = dict(
409
+ propulsion_power=np.array([0.0]),
410
+ frequency=np.array([3600.0]),
411
+ auxiliary_power_kw=500.0,
412
+ fuel_specified_by=FuelSpecifiedBy.IMO,
413
+ )
414
+
415
+ # Default (no fuel_option) → first mode = LNG
416
+ res_default = machinery_calculation.calculate_machinery_system_output_from_statistics(
417
+ **run_kwargs
418
+ )
419
+
420
+ # Force H2
421
+ res_h2 = machinery_calculation.calculate_machinery_system_output_from_statistics(
422
+ **run_kwargs,
423
+ fuel_option=FuelOption(
424
+ fuel_type=TypeFuel.HYDROGEN,
425
+ fuel_origin=FuelOrigin.RENEWABLE_NON_BIO,
426
+ for_pilot=False,
427
+ primary=False,
428
+ ),
429
+ )
430
+
431
+ # Force LNG explicitly
432
+ res_lng = machinery_calculation.calculate_machinery_system_output_from_statistics(
433
+ **run_kwargs,
434
+ fuel_option=FuelOption(
435
+ fuel_type=TypeFuel.NATURAL_GAS,
436
+ fuel_origin=FuelOrigin.FOSSIL,
437
+ for_pilot=False,
438
+ primary=True,
439
+ ),
440
+ )
441
+
442
+ fuels_default = res_default.multi_fuel_consumption_total_kg.fuels
443
+ fuels_h2 = res_h2.multi_fuel_consumption_total_kg.fuels
444
+
445
+ # Default = LNG: natural_gas consumed, no hydrogen
446
+ assert any(f.fuel_type == TypeFuel.NATURAL_GAS and f.mass_or_mass_fraction > 0
447
+ for f in fuels_default), "Default mode should consume natural gas"
448
+ assert not any(f.fuel_type == TypeFuel.HYDROGEN and f.mass_or_mass_fraction > 0
449
+ for f in fuels_default), "Default mode should not consume hydrogen"
450
+
451
+ # H2 forced: hydrogen consumed, no natural_gas
452
+ assert any(f.fuel_type == TypeFuel.HYDROGEN and f.mass_or_mass_fraction > 0
453
+ for f in fuels_h2), "H2 mode should consume hydrogen"
454
+ assert not any(f.fuel_type == TypeFuel.NATURAL_GAS and f.mass_or_mass_fraction > 0
455
+ for f in fuels_h2), "H2 mode should not consume natural gas"
456
+
457
+ # LNG forced matches default
458
+ assert np.isclose(
459
+ res_default.fuel_consumption_total_kg,
460
+ res_lng.fuel_consumption_total_kg,
461
+ rtol=1e-6,
462
+ ), "Explicit LNG option should match default"
463
+
File without changes
File without changes
File without changes