Skip to content

ZBT-Tools/DPMFuelCellChannel

Repository files navigation

DPMFuelCellChannel

Mechanistic Discrete Particle Model (DPM) used to estimate the two-phase flow regimes in straight fuel cell channels. Used to estimate how the properties of the interface between the gas channel and the gas diffusion layer in terms of wettability and flow rates influences the amount of water covering the GDL surface and the saturation of the channels. To run you need to download the additional files for vtk writing and surface visualisation (only relevant for Matlab version under matlab-files; for the python version, no visualization has been implemented yet). Commented code is there for potential work in progress and so some sections may not work. This code was used to generate the results in the publication: Niblett, Daniel, Stuart Martin Holmes, and Vahid Niasar. "Discrete-particle model to optimize operational conditions of proton-exchange membrane fuel-cell gas channels." ACS Applied Energy Materials 4.10 (2021): 10514-10533.

Table of Contents

  • Quickstart
  • Requirements
  • Structure of the Programm
  • Known Bugs
  • TODOs
  • Contact

Quickstart

The python files necessary to run this project are located in the folder python-files. The first translation of the matlab code is contained in the file DPMFuelCellChannel-original-config.py. It is a literal translation of the matlab code and hardly readable as the variable naming does not meet good software engineering standards and one monolithic chunk of code. A second translation which split up the code was done in the file DPM-FuellCellChannel.py. It contains functions which split up the code, but the variables are not renamed. The functions are contained in util.py. However both files produce the same values as the original matlab implementation which can be found in the folder matlab-files.

The file main_DPM.py is the main file of the new implementation which shall be used in the future. However it contains bugs (see below). This implementation is more object-oriented than the previous implementations and has a improved variable naming and is split into multiple files.

Requirements

  • numpy
  • scipy

Modules used for debugging:

  • h5py to store data in the HDF5 format
  • pyperclip for copy-pasting arrays directly to the clip board
  • matplotlib for visualization (only used of prototyping in python-files/3dPlots.ipynb

The requirements can also be found in the dependency graph (mostly numpy).

Dependecy graph: Dependcies

Structure of the Programm

The main file is main_DPM.py and imports the necessary functions. It contains comments inside the file, which explain the structure.

The folder tests contains first unit tests for some functions. But this can be improved.

The most important class are Droplets in Droplet.py (TODO: lower case naming). It contains all information about the droplets in the channel. The attributes are derived from the columns of the Droplet array (D) in the Matlab implementation. Furthermore it containns methods to select droplets. It is a container with numpy arrays and each entry in the numpy arrays corresponds to the attribute of a single droplet. The attribute state describes the topology (isolated, emerging, corner droplet, etc.) (TODO: describe all states)

The geometry of the channel is defined in the class Channel in channel.py.

The pores are defined in the class Poresin pores.py. It is necessary to intialize the pores with an additional method call, like create_randomly_spaced_pores.

The file constants.py contain program constants (especially the coding of the topologies) and physical constants. Those are all written in capital letters.

Known Bugs

Those are listed with descending priority:

  • There are several bugs in the updating step of the coalescence algorithm and it needs to be compared to a previous implementation. Currently they occur in iteration 1 (starting with iteration 0). After every step it is necessary to check it. Especially the annex of the paper is helpful to understand the variable naming, as these are inspired by the original implementation.

# BUG
# Currently it does not yield the same results as the reference implementation
# in the file DPM-FuellCellChannel.py. It starts diverging in iteration
# `iteration == 1` It seems there are MULTIPLE Bugs as in mutliple topologies
# show a different behaviour.
if droplets_emerging.get_number_droplets() > 0:
droplets_emerging = property_update.update_emerging_droplets(droplets_emerging, channel, theta_GDL)
if droplets_isolated.get_number_droplets() > 0:
droplets_isolated = property_update.update_isolated_droplets(droplets_isolated, channel, theta_GDL)
if droplets_sidewall.get_number_droplets() > 0:
droplets_sidewall = property_update.update_side_wall_droplets(droplets_sidewall, channel, theta_GDL, theta_wall)
# store_droplet_array("test_droplets", droplets_emerging.to_array(), "new")
if droplets_corner.get_number_droplets() > 0:
droplets_corner = property_update.update_corner_droplets(droplets, channel, theta_wall)
if droplets_capillary_bridge.get_number_droplets() > 0:
droplets_capillary_bridge = property_update.update_capillary_bridge_droplets(droplets, channel, theta_wall)
if droplets_film_flow.get_number_droplets() > 0 and film_formation:
droplets_film_flow = property_update.update_filmflow_droplets(droplets, channel, theta_wall, velocity_air_inlet, viscosity_air)
if droplets_plug_flow.get_number_droplets() > 0 and plug_formation:
droplets_plug_flow = property_update.update_plugflow_droplets(droplets, channel, theta_wall)

  • The collision and emerging algorithm is written completely new and it needs to be tested. Currently it has only limited coverage, since it worked only for emerging droplets and isolated droplets in the first two iterations.

if coalescence:
if droplets.get_number_droplets() > 1:
d1, d2 = collission.mark_coalescence_pairs_droplets(droplets)
droplets = collission.collide_droplets(droplets, d1, d2, pores.radius_max, channel)
droplets = emerge_droplets.emerge_droplets(droplets, pores, radius_emerging_droplet=pore_radius, initial_height_droplets=initial_height, h_limit=h_limit)

  • The time function does not work, if there are no droplets in the channel.

time_step = time_functions.calc_time_step(courant_number, droplets.velocity_droplets, time_step_fallback,

TODOs

Those are improvements which can be used in later stages of the development. It can be implemented but in this list, I noted everything which came into my mind.

  • Move the calculation of the height limit for the slug to the constructor of the droplets and remove it from other parts. Currently this is also implemented in the emergence function for new droplets

  • Check throughly the emergence algorithm and collision algorithm as both are reimplementations of the original algorithm. They use a vectorization to make the code more readable and remove unnecessary calculations.

  • Check throughly the update properties step. Each function is not tested and surely contains bugs which are unknown

  • Move the configuration from the code to a seperate file.

  • Improve the initialisation module and write it in a consistent way. The original implementation was a mess in the initilization and introduced variables which were never used again.

  • Check the post processing step in the module force which computes the force balances.

  • Implement a visualization tool

  • Write unit tests for all function after there is a working implementation of the algorithm

  • Use type hints consistently throughout the code

  • Improve the water flow calculation, as currenlty several ways are supported. It should be more intuitive and clear what happens.

  • Add the transportation process of the gas in the channel.

  • Minor impprovements marked as TODO in the code

  • Enforcing the line breaks at 80 characters

Contact

The programmer Niclas can be contacted under niclas.richter[at]posteo.de.

About

Department 6

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors