Line | Branch | Exec | Source |
---|---|---|---|
1 | // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- | ||
2 | // vi: set et ts=4 sw=4 sts=4: | ||
3 | // | ||
4 | // SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder | ||
5 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
6 | // | ||
7 | /*! | ||
8 | * \file | ||
9 | * \ingroup Chemistry | ||
10 | * \brief Electrochemical model for a fuel cell application. | ||
11 | */ | ||
12 | #ifndef DUMUX_ELECTROCHEMISTRY_NI_HH | ||
13 | #define DUMUX_ELECTROCHEMISTRY_NI_HH | ||
14 | |||
15 | #include <dumux/material/constants.hh> | ||
16 | #include <dumux/material/chemistry/electrochemistry/electrochemistry.hh> | ||
17 | |||
18 | namespace Dumux { | ||
19 | |||
20 | /*! | ||
21 | * \ingroup Chemistry | ||
22 | * \brief Class calculating source terms and current densities for fuel cells | ||
23 | * with the electrochemical models suggested by Ochs (2008) \cite ochs2008 or Acosta (2006) \cite A3:acosta:2006 | ||
24 | * for the non-isothermal case. | ||
25 | * \todo TODO: Scalar type should be extracted from VolumeVariables! | ||
26 | * \todo TODO: This shouldn't depend on discretization and grid!! | ||
27 | */ | ||
28 | template <class Scalar, class Indices, class FluidSystem, class GridGeometry, ElectroChemistryModel electroChemistryModel> | ||
29 | class ElectroChemistryNI : public ElectroChemistry<Scalar, Indices, FluidSystem, GridGeometry, electroChemistryModel> | ||
30 | { | ||
31 | using ParentType = ElectroChemistry<Scalar, Indices, FluidSystem, GridGeometry, electroChemistryModel>; | ||
32 | using Constant = Constants<Scalar>; | ||
33 | |||
34 | enum { | ||
35 | //equation indices | ||
36 | contiH2OEqIdx = Indices::conti0EqIdx + FluidSystem::H2OIdx, | ||
37 | contiO2EqIdx = Indices::conti0EqIdx + FluidSystem::O2Idx, | ||
38 | energyEqIdx = Indices::energyEqIdx, //energy equation | ||
39 | }; | ||
40 | |||
41 | using GridView = typename GridGeometry::GridView; | ||
42 | static constexpr bool isBox = GridGeometry::discMethod == DiscretizationMethods::box; | ||
43 | using GlobalPosition = typename Dune::FieldVector<typename GridView::ctype, GridView::dimensionworld>; | ||
44 | using CellVector = typename Dune::FieldVector<typename GridView::ctype, GridView::dimension>; | ||
45 | |||
46 | public: | ||
47 | /*! | ||
48 | * \brief Calculates reaction sources with an electrochemical model approach. | ||
49 | * | ||
50 | * \param values The primary variable vector | ||
51 | * \param currentDensity The current density | ||
52 | * \param paramGroup The group containing the needed parameters | ||
53 | * | ||
54 | * For this method, the \a values parameter stores source values | ||
55 | */ | ||
56 | template<class SourceValues> | ||
57 | 48384 | static void reactionSource(SourceValues &values, Scalar currentDensity, | |
58 | const std::string& paramGroup = "") | ||
59 | { | ||
60 | //correction to account for actually relevant reaction area | ||
61 | //current density has to be divided by the half length of the box | ||
62 | //\todo Do we have multiply with the electrochemically active surface area (ECSA) here instead? | ||
63 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 24190 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
|
48384 | static Scalar gridYMax = getParamFromGroup<GlobalPosition>(paramGroup, "Grid.UpperRight")[1]; |
64 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 24190 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
|
48384 | static Scalar nCellsY = getParamFromGroup<GlobalPosition>(paramGroup, "Grid.Cells")[1]; |
65 | |||
66 | // Warning: This assumes the reaction layer is always just one cell (cell-centered) or half a box (box) thick | ||
67 | 48384 | const auto lengthBox = gridYMax/nCellsY; | |
68 | if (isBox) | ||
69 | 48384 | currentDensity *= 2.0/lengthBox; | |
70 | else | ||
71 | currentDensity *= 1.0/lengthBox; | ||
72 | |||
73 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 24190 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
|
48384 | static Scalar transportNumberH2O = getParam<Scalar>("ElectroChemistry.TransportNumberH20"); |
74 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 24190 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
|
48384 | static Scalar thermoneutralVoltage = getParam<Scalar>("ElectroChemistry.ThermoneutralVoltage"); |
75 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 24190 times.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
|
48384 | static Scalar cellVoltage = getParam<Scalar>("ElectroChemistry.CellVoltage"); |
76 | |||
77 | //calculation of flux terms with faraday equation | ||
78 | 48384 | values[contiH2OEqIdx] = currentDensity/(2*Constant::F); //reaction term in reaction layer | |
79 | 48384 | values[contiH2OEqIdx] += currentDensity/Constant::F*transportNumberH2O; //osmotic term in membrane | |
80 | 48384 | values[contiO2EqIdx] = -currentDensity/(4*Constant::F); //O2-equation | |
81 | 48384 | values[energyEqIdx] = (thermoneutralVoltage - cellVoltage)*currentDensity; //energy equation | |
82 | 48384 | } | |
83 | }; | ||
84 | |||
85 | } // end namespace Dumux | ||
86 | |||
87 | #endif | ||
88 |