PEM Electrolyzer Modeling

Hi everyone!
I am working on a problem to model a hydrogen system with a PEM electrolyzer, storage and fuel synthesis unit in Oemof. I want to model the part-load behavior of an electrolyzer using an offset transformer or a Piece-wise linear Transformer? My goal is also to determine the optimal capacity using the investment mode. Which kind of Transformer is better suited for this application?
Currently, I am using piece-wise linear transformer to model this electrolyzer. I am confused on how to model the in-break points and conversion factor so that for input electricity at each corresponding load point and efficiency, the output hydrogen is produced.
After defining sources, sinks, max. capacity for electrolyzer (testing without investment mode), is the following approach correct? (I found it in SMOOTH, that is based on oemof):

# Define the maximum capacity of the electrolyzer
max_capacity = 100e6  # 100 MW
 # Define the load points and corresponding efficiencies
bp_load_h2_prod = [0, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1]
bp_eff_h2_prod = [0, 0.10, 0.50, 0.66, 0.71, 0.67, 0.63, 0.585, 0.545, 0.52, 0.51]
lower_heating_value = 33.3  # lower heating value in kWh/kg

bp_elec_consumed_h2_prod = [this_bp * max_capacity
                            for this_bp in bp_load_h2_prod]

bp_h2_production = []
for i_bp in range(len(bp_load_h2_prod)):
    this_hydrogen_production = \
         * bp_eff_h2_prod[i_bp]) / (lower_heating_value)

def get_h2_production_by_electricity(electricity_consumption):
        """Gets the hydrogen produced by the according electricity consumption
        :param electricity_consumption: electrcity consumption value [kWh]
        :return: according hydrogen production value [kg]
        # Check the index of this load point.
        this_index = bp_elec_consumed_h2_prod.index(electricity_consumption)
        return bp_h2_production[this_index]

# Create and add PiecewiseLinearTransformer

pem_ely = solph.components.experimental.PiecewiseLinearTransformer(
    inputs={b_el: solph.flows.Flow(nominal_value=100000, variable_costs=1)},
    outputs={b_h2: Flow()},

@pschoen I see that you are currently active on oemof posts. May be you can comment on this!

Thanks in advance!

Hi @nomi,

Thanks for reaching out. Honestly, I find it hard to read your code example, as you did not format it as code. Also, I am not the most experienced person on mixed-integer formulations. Thus, I’ll stay at a rather abstract level: As an experimental component, the PiecewiseLinearTransformer is poorly documented. So, if the OffsetTransformer is sufficiently detailed, I’d recommend to use that one. However, currently the size of both cannot be optimised. There is Pull Request #895, Upgrade OffsetConverter by sasa821 to change that. So, either you use this in-development feature or you will have to try different sizes until you find the optimal one.


@nomi: on the question of code formatting, you can surround your code block in triple backslashes and optionally add the word python (or whichever language you are using) following the first set of backslashes to make your information more readable. But you still have to indent your code correctly for yourself. More here:

And the relevant example is here (although adding javascript would normally be better practice):

It is considered good netiquette to make your code snippets clean and readable (as @pschoen indicated). Also, you are more likely to get sensible answers if people can more easily see and understand what you are trying to convey. R

Hi @robbie.morrison Thanks for the input. I have corrected my code snippet and made it more readable.

@pschoen Thanks for your input. I hope the code is more readable now.

The concept behind the code is similar to that described here: Link

I want to implement the following curve for electrolyzer:

Do you have any other input with edited code and this curve?

I will give a try to in-development feature for offset transformer to implement this part-load efficiency curve and will comment further on this matter.

best regards,

1 Like

The code you posted seems to implement the desired curve for a constant size. I think, SMOOTH does the sizing, as this kind of optimisation is not implemented yet for the PiecewiseLinearConverter.

It might not the most elegant or efficient way to model this, but I see the following approach to solve you problem using only existing functionality of solph:

  • Add several OffsetConverters with invest optimisation (from the upcoming v0.5.1 feature that is already implemented in the aforementioned PR). If you are willing to sacrifice accuracy for performance, you could e.g. have one slope from 0 % to 20 % part load, one for 20 % to 35 % and one from 35 % to 100 %.
  • Use oemof.solph.constraints.equate_variables to set all the optimised sizes to be equal.
  • Use oemof.solph.constraints.limit_active_flow_count to make sure just one of the OffsetConverters is active.

PS: Please note that I already use the new naming scheme, as Transformer will be renamed to Converter soon.

1 Like