OpenLB 1.7
Loading...
Searching...
No Matches
batteryCouplingPostProcessor2D.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2021 Paul Neugebauer, Lukas Richter, Kevin Schuelein
4 * E-mail contact: info@openlb.net
5 * The most recent release of OpenLB can be downloaded at
6 * <http://www.openlb.net/>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22*/
23
24#ifndef BATTERY_COUPLING_POST_PROCESSOR_2D_H
25#define BATTERY_COUPLING_POST_PROCESSOR_2D_H
26
27#include "core/blockStructure.h"
28#include "core/postProcessing.h"
29#include "core/util.h"
30#include "latticeDescriptors.h"
31#include "utilities/omath.h"
32
33
34namespace olb {
35
36
41//======================================================================
42// ======== AD coupling with Concentration 2D ====================//
43//======================================================================
44template<typename T, typename DESCRIPTOR>
46 : public LocalPostProcessor2D<T,DESCRIPTOR> {
47 private:
48 mutable OstreamManager clout {std::cout, "Reaction2dSolver"};
49
50public:
52 int x0_, int x1_, int y0_, int y1_,
53 const T conversionDiffusivity_,
54 const T diffusion_S_,
55 const T kappa_S_,
56 const T factor1_,
57 const T factor2_,
58 const T fac_sep_,
59 std::vector<BlockStructureD<2>* > partners_)
60 : x0(x0_), x1(x1_), y0(y0_), y1(y1_),
61 conversionDiffusivity(conversionDiffusivity_), diffusion_S(diffusion_S_),
62 kappa_S(kappa_S_), factor1(factor1_), factor2(factor2_), fac_sep(fac_sep_),
63 partners(partners_) {
64 this->getName() = "batteryCouplingPostProcessor2D";
65 component_number = static_cast<int>(partners.size())+1;
66 for (int i = 0; i<component_number;i++){
67 tpartners.emplace_back(
68 static_cast<BlockLattice<T,DESCRIPTOR> *>(partners[i]));
69 }
70 }
71
72 int extent() const override {
73 return 0;
74 }
75
76 int extent(int whichDirection) const override {
77 return 0;
78 }
79
80 void process(BlockLattice<T,DESCRIPTOR>& blockLattice) override {
81 processSubDomain(blockLattice, x0, x1, y0, y1);
82 }
83
85 int x0_, int x1_, int y0_, int y1_) override {
86
87 int newX0, newX1, newY0, newY1;
88 if ( util::intersect (
89 x0, x1, y0, y1,
90 x0_, x1_, y0_, y1_,
91 newX0, newX1, newY0, newY1 ) ) {
92
93 for (int iX=newX0; iX<=newX1; ++iX) {
94 for (int iY=newY0; iY<=newY1; ++iY) {
95 T materialNumber = blockLattice.get(iX,iY).template getField<descriptors::CELL_TYPE>();
96
97
98 //if ((int) materialNumber == 6 ||(int) materialNumber == 7 || (int) materialNumber == 1 || (int) materialNumber == 3)
99 //{
100
101 T physDiffusion_c;
102 T tmp_source_c;
103 T physDiffusion_phi;
104 T tmp_source_phi;
105
106 std::vector<T> conc;
107 std::vector<T> conc_plusX;
108 std::vector<T> conc_minusX;
109 std::vector<T> conc_plusY;
110 std::vector<T> conc_minusY;
111
112 conc.emplace_back(blockLattice.get(iX,iY).computeRho());
113 for (int iter_component = 0; iter_component<component_number-1; ++ iter_component){
114 conc.emplace_back(tpartners[iter_component]->get(iX,iY).computeRho());
115 }
116
117 T tmp_Diffusion_E = 1.2e-21*util::pow(conc[0],4)- 6.5e-18*util::pow(conc[0],3)+ 1.14e-14*util::pow(conc[0],2)-8.06e-12*conc[0]+2.24e-9;
118 T kappa_E = -2.39e-11*util::pow(conc[0],4)+1.21e-7*util::pow(conc[0],3)-2.89e-4*util::pow(conc[0],2)+0.32*conc[0]-2.789;
119
120 if ((int) materialNumber == 6 || (int) materialNumber == 7 || (int) materialNumber == 1 || (int) materialNumber == 3 || (int) materialNumber == 4 || (int) materialNumber == 5){
121
122 if (iX== newX0 ){
123 conc_minusX.emplace_back(0.0);
124 conc_minusX.emplace_back(0.0);
125 }
126 else {
127 conc_minusX.emplace_back(blockLattice.get(iX-1,iY).computeRho());
128 conc_minusX.emplace_back(tpartners[0]->get(iX-1,iY).computeRho());
129 }
130
131 if (iX== newX1){
132 conc_plusX.emplace_back(0.0);
133 conc_plusX.emplace_back(0.0);
134 }
135 else {
136 conc_plusX.emplace_back(blockLattice.get(iX+1,iY).computeRho());
137 conc_plusX.emplace_back(tpartners[0]->get(iX+1,iY).computeRho());
138 }
139
140 if (iY== newY0){
141 conc_minusY.emplace_back(blockLattice.get(iX, newY1).computeRho());
142 conc_minusY.emplace_back(tpartners[0]->get(iX, newY1).computeRho());
143 }
144 else {
145 conc_minusY.emplace_back(blockLattice.get(iX,iY-1).computeRho());
146 conc_minusY.emplace_back(tpartners[0]->get(iX,iY-1).computeRho());
147 }
148
149 if (iY == newY1){
150 conc_plusY.emplace_back(blockLattice.get(iX,newY0).computeRho());
151 conc_plusY.emplace_back(tpartners[0]->get(iX,newY0).computeRho());
152 }
153 else {
154 conc_plusY.emplace_back(blockLattice.get(iX,iY+1).computeRho());
155 conc_plusY.emplace_back(tpartners[0]->get(iX,iY+1).computeRho());
156 }
157
158 T kappa_E_minusX = -2.39e-11*util::pow(conc_minusX[0],4)+1.21e-7*util::pow(conc_minusX[0],3)-2.89e-4*util::pow(conc_minusX[0],2)+0.32*conc_minusX[0]-2.789;
159 T kappa_E_plusX = -2.39e-11*util::pow(conc_plusX[0],4)+1.21e-7*util::pow(conc_plusX[0],3)-2.89e-4*util::pow(conc_plusX[0],2)+0.32*conc_plusX[0]-2.789;
160 T kappa_E_minusY = -2.39e-11*util::pow(conc_minusY[0],4)+1.21e-7*util::pow(conc_minusY[0],3)-2.89e-4*util::pow(conc_minusY[0],2)+0.32*conc_minusY[0]-2.789;
161 T kappa_E_plusY = -2.39e-11*util::pow(conc_plusY[0],4)+1.21e-7*util::pow(conc_plusY[0],3)-2.89e-4*util::pow(conc_plusY[0],2)+0.32*conc_plusY[0]-2.789;
162
163 if ((int) materialNumber == 6 || (int)materialNumber == 5){ //Solid
164 physDiffusion_c = diffusion_S;
165 physDiffusion_phi = kappa_S;
166 tmp_source_c = 0.0;
167 tmp_source_phi= 0.0;
168 }
169 else if ((int) materialNumber == 7 || (int) materialNumber == 3){ //Separator
170 physDiffusion_c = fac_sep*(tmp_Diffusion_E- factor1*factor2*(kappa_E/conc[0]));
171 physDiffusion_phi = kappa_E;
172 tmp_source_c = fac_sep*(factor1* (1./4.)*((kappa_E_plusX-kappa_E_minusX)*(conc_plusX[1]-conc_minusX[1])+
173 + (kappa_E_plusY-kappa_E_minusY)*(conc_plusY[1]-conc_minusY[1]))
174 -kappa_E*(conc_minusX[1]+conc_plusX[1]+ conc_minusY[1]+conc_plusY[1]-4*conc[1]));
175 tmp_source_phi = factor2*((1./4.)*((kappa_E_plusX/conc_plusX[0]-kappa_E_minusX/conc_minusX[0])*(conc_plusX[0]-conc_minusX[0])
176 + (kappa_E_plusY/conc_plusY[0]-kappa_E_minusY/conc_minusY[0])*(conc_plusY[0]-conc_minusY[0]))
177 -(kappa_E/conc[0])*(conc_minusX[0]+conc_plusX[0]+conc_minusY[0]+conc_plusY[0]-4*conc[0]));
178 }
179 else if((int) materialNumber == 1 || (int) materialNumber == 4) { //Electrolyte
180 physDiffusion_c = tmp_Diffusion_E- factor1*factor2*(kappa_E/conc[0]);
181 physDiffusion_phi = kappa_E;
182 tmp_source_c = (factor1* (1./4.)*((kappa_E_plusX-kappa_E_minusX)*(conc_plusX[1]-conc_minusX[1])+
183 + (kappa_E_plusY-kappa_E_minusY)*(conc_plusY[1]-conc_minusY[1]))
184 -kappa_E*(conc_minusX[1]+conc_plusX[1]+ conc_minusY[1]+conc_plusY[1]-4*conc[1]));
185 tmp_source_phi = factor2*((1./4.)*((kappa_E_plusX/conc_plusX[0]-kappa_E_minusX/conc_minusX[0])*(conc_plusX[0]-conc_minusX[0])
186 + (kappa_E_plusY/conc_plusY[0]-kappa_E_minusY/conc_minusY[0])*(conc_plusY[0]-conc_minusY[0]))
187 -(kappa_E/conc[0])*(conc_minusX[0]+conc_plusX[0]+conc_minusY[0]+conc_plusY[0]-4*conc[0]));
188
189 }
190
191
192 T tau_c = (physDiffusion_c/ conversionDiffusivity * descriptors::invCs2<T,DESCRIPTOR>())+0.5;
193 T tmp_omega_c = 1.0/tau_c;
194
195 T tau_phi = (physDiffusion_phi/ conversionDiffusivity * descriptors::invCs2<T,DESCRIPTOR>())+0.5;
196 T tmp_omega_phi = 1.0/tau_phi;
197
198
199 blockLattice.get(iX,iY).template setField<descriptors::SOURCE>(tmp_source_c*2.5e-13);
200 blockLattice.get(iX,iY).template setField<descriptors::OMEGA>(tmp_omega_c);
201 blockLattice.get(iX,iY).template setField<collision::TRT::MAGIC>(0.1*physDiffusion_c);
202
203 tpartners[0]->get(iX,iY).template setField<descriptors::SOURCE>(tmp_source_phi*2.5e-13);
204 tpartners[0]->get(iX,iY).template setField<descriptors::OMEGA>(tmp_omega_phi);
205 tpartners[0]->get(iX,iY).template setField<collision::TRT::MAGIC>(0.1*physDiffusion_phi);
206
207 }
208
209 //Berechnung von BOUNDARY für MN 3 für BlockLattices
210 else{
211 T boundaryInflow = factor1/tmp_Diffusion_E*(kappa_E*(tpartners[0]->get(iX+1,iY).computeRho()-conc[1])
212 +kappa_S/conc[0]*(blockLattice.get(iX+1,iY).computeRho()-conc[0]));
213 blockLattice.get(iX,iY).template setField<descriptors::BOUNDARY> (boundaryInflow);
214 }
215
216 //}
217 }
218 }
219 }
220 }
221
222private:
223 int x0, x1, y0, y1;
224 int component_number;
225 T conversionDiffusivity;
226 T diffusion_S;
227 T kappa_S;
228 T factor1;
229 T factor2;
230 T fac_sep;
231 std::vector<BlockLattice<T,DESCRIPTOR>*> tpartners;
232 std::vector<BlockStructureD<2>* > partners;
233};
234
235template<typename T, typename DESCRIPTOR>
237 : public LatticeCouplingGenerator2D<T,DESCRIPTOR> {
238
239public:
241 int x0_, int x1_, int y0_, int y1_,
242 T conversionDiffusivity_, T diffusion_S_, T kappa_S_, T factor1_, T factor2_, T fac_sep_)
243 : LatticeCouplingGenerator2D<T,DESCRIPTOR>(x0_, x1_, y0_, y1_),
244 conversionDiffusivity(conversionDiffusivity_), diffusion_S(diffusion_S_),
245 kappa_S(kappa_S_), factor1(factor1_), factor2(factor2_), fac_sep(fac_sep_)
246 { }
247
249 std::vector<BlockStructureD<2>* > partners) const override {
251 this->x0,this->x1,this->y0,this->y1, conversionDiffusivity, diffusion_S,
252 kappa_S, factor1, factor2, fac_sep, partners);
253 }
254
258
259private:
260 T conversionDiffusivity;
261 T diffusion_S;
262 T kappa_S;
263 T factor1;
264 T factor2;
265 T fac_sep;
266};
267
268
269
270
271}
272
273#endif
Platform-abstracted block lattice for external access and inter-block interaction.
Cell< T, DESCRIPTOR > get(CellID iCell)
Get Cell interface for index iCell.
Base of a regular block.
class for marking output with some text
Interface of 2D post-processing steps.
std::string & getName()
read and write access to name
PostProcessor2D< T, DESCRIPTOR > * generate(std::vector< BlockStructureD< 2 > * > partners) const override
batteryCouplingGenerator2D(int x0_, int x1_, int y0_, int y1_, T conversionDiffusivity_, T diffusion_S_, T kappa_S_, T factor1_, T factor2_, T fac_sep_)
LatticeCouplingGenerator2D< T, DESCRIPTOR > * clone() const override
Coupling of ADlattice[0] with the other AD lattices (tpartners)
int extent(int whichDirection) const override
Extent of application area along a direction (0 or 1)
batteryCouplingPostProcessor2D(int x0_, int x1_, int y0_, int y1_, const T conversionDiffusivity_, const T diffusion_S_, const T kappa_S_, const T factor1_, const T factor2_, const T fac_sep_, std::vector< BlockStructureD< 2 > * > partners_)
int extent() const override
Extent of application area (0 for purely local operations)
void process(BlockLattice< T, DESCRIPTOR > &blockLattice) override
Execute post-processing step.
void processSubDomain(BlockLattice< T, DESCRIPTOR > &blockLattice, int x0_, int x1_, int y0_, int y1_) override
Execute post-processing step on a sublattice.
Descriptor for all types of 2D and 3D lattices.
cpu::simd::Pack< T > pow(cpu::simd::Pack< T > base, cpu::simd::Pack< T > exp)
Definition pack.h:112
bool intersect(int x0, int x1, int y0, int y1, int x0_, int x1_, int y0_, int y1_, int &newX0, int &newX1, int &newY0, int &newY1)
Definition util.h:89
Top level namespace for all of OpenLB.
Interface for post-processing steps – header file.
Set of functions commonly used in LB computations – header file.