OpenLB 1.8.1
Loading...
Searching...
No Matches
freeEnergyDynamics.h
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2018 Robin Trunk, Sam Avis
4 * 2021 Adrian Kummerlaender
5 * OpenLB e-mail contact: info@openlb.net
6 * The most recent release of OpenLB can be downloaded at
7 * <http://www.openlb.net/>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public
20 * License along with this program; if not, write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23*/
24
25#ifndef FREE_ENERGY_DYNAMICS_H
26#define FREE_ENERGY_DYNAMICS_H
27
28#include "lbm.h"
29#include "interface.h"
30#include "momenta/aliases.h"
31
37namespace olb {
38
39namespace equilibria {
40
41struct FreeEnergy {
43
44 static std::string getName() {
45 return "FreeEnergy";
46 }
47
48 template <typename DESCRIPTOR, typename MOMENTA>
49 struct type {
50 using MomentaF = typename MOMENTA::template type<DESCRIPTOR>;
51
52 template <typename CELL, typename RHO, typename U, typename FEQ, typename V=typename CELL::value_t>
53 CellStatistic<V> compute(CELL& cell, RHO& rho, U& u, FEQ& fEq) any_platform {
54 const V uSqr = util::normSqr<V,DESCRIPTOR::d>(u);
55 for (int iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
56 fEq[iPop] = equilibrium<DESCRIPTOR>::secondOrder(iPop, rho, u, uSqr);
57 }
58 return {rho, uSqr};
59 };
60
61 template <typename CELL, typename PARAMETERS, typename FEQ, typename V=typename CELL::value_t>
62 CellStatistic<V> compute(CELL& cell, PARAMETERS& parameters, FEQ& fEq) any_platform {
63 auto u = cell.template getField<descriptors::FORCE>();
64 V rho = MomentaF().computeRho(cell);
65 return compute(cell, rho, u, fEq);
66 };
67 };
68};
69
70}
71
72namespace collision {
73
74struct FreeEnergy {
75 struct GAMMA : public descriptors::FIELD_BASE<1> { };
76
78
79 static std::string getName() {
80 return "FreeEnergy";
81 }
82
83 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM>
84 struct type {
85 using EquilibriumF = typename EQUILIBRIUM::template type<DESCRIPTOR,MOMENTA>;
86
87 template <typename CELL, typename PARAMETERS, typename V=typename CELL::value_t>
88 CellStatistic<V> apply(CELL& cell, PARAMETERS& parameters) any_platform {
89 V fEq[DESCRIPTOR::q] { };
90 const auto statistic = EquilibriumF().compute(cell, parameters, fEq);
91 const V omega = parameters.template get<descriptors::OMEGA>();
92 const V gamma = parameters.template get<GAMMA>();
93 for (int iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
94 cell[iPop] *= V{1} - omega;
95 cell[iPop] += omega * fEq[iPop];
96 }
97 const V tmp = gamma * descriptors::invCs2<V,DESCRIPTOR>()
98 * cell.template getField<descriptors::CHEM_POTENTIAL>();
99 for (int iPop=1; iPop < DESCRIPTOR::q; ++iPop) {
100 cell[iPop] -= omega * descriptors::t<V,DESCRIPTOR>(iPop) * (statistic.rho - tmp);
101 }
102 cell[0] += omega * (V{1} - descriptors::t<V,DESCRIPTOR>(0)) * (statistic.rho - tmp);
103 return statistic;
104 };
105 };
106};
107
108template <int direction, int orientation>
111
112 static std::string getName() {
113 return "FreeEnergyInletOutlet<"
114 + std::to_string(direction) + "," + std::to_string(orientation) +
115 ">";
116 }
117
118 template <typename DESCRIPTOR, typename MOMENTA, typename EQUILIBRIUM>
119 struct type {
120 using MomentaF = typename MOMENTA::template type<DESCRIPTOR>;
121
122 template <typename CELL, typename PARAMETERS, typename V=typename CELL::value_t>
124 // Do a standard collision neglecting the chemical potential term.
125 V rho, u[DESCRIPTOR::d];
126 MomentaF().computeRhoU(cell, rho, u);
127 const V omega = parameters.template get<descriptors::OMEGA>();
128 V uSqr = lbm<DESCRIPTOR>::bgkCollision(cell, rho, u, omega);
129 for (int iPop=1; iPop < DESCRIPTOR::q; ++iPop) {
130 cell[iPop] -= omega * descriptors::t<V,DESCRIPTOR>(iPop) * rho;
131 }
132 cell[0] += omega * (V{1} - descriptors::t<V,DESCRIPTOR>(0)) * rho;
133 // Distribute the missing density to the unknown distribution functions.
134 constexpr auto missingIndices = util::subIndexOutgoing<DESCRIPTOR,direction,orientation>();
135 V missingRho = rho - V{1};
136 V missingWeightSum = 0;
137 for (int iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
138
139 // std::find can conflict with CUDA
140 /*if (std::find(missingIndices.begin(), missingIndices.end(), iPop) != missingIndices.end()) {
141 missingWeightSum += descriptors::t<V,DESCRIPTOR>(iPop);
142 } else {
143 missingRho -= cell[iPop];
144 }*/
145
146 bool contains = false;
147 for(long unsigned int i=0; i < missingIndices.size(); i++){
148 if(missingIndices[i] == (long unsigned int)iPop){
149 contains = true;
150 }
151 }
152
153 if(contains){
154 missingWeightSum += descriptors::t<V,DESCRIPTOR>(iPop);
155 } else {
156 missingRho -= cell[iPop];
157 }
158
159 }
160
161 for (unsigned iPop=0; iPop < missingIndices.size(); ++iPop) {
162 cell[missingIndices[iPop]] = missingRho * descriptors::t<V,DESCRIPTOR>(missingIndices[iPop]) / missingWeightSum;
163 }
164 return {rho, uSqr};
165 };
166 };
167};
168
169}
170
171template <typename T, typename DESCRIPTOR, typename MOMENTA=momenta::FreeEnergyBulkTuple>
173 T, DESCRIPTOR,
174 MOMENTA,
177>;
178
179template <typename T, typename DESCRIPTOR>
181 T, DESCRIPTOR,
187 >,
190>;
191
192template <typename T, typename DESCRIPTOR, int direction, int orientation>
194 T, DESCRIPTOR,
200 >,
203>;
204
205}
206
207#endif
Instantiation of Momenta tuples which define the computation and definition of momenta in a specific ...
constexpr T invCs2() any_platform
Definition functions.h:107
constexpr T t(unsigned iPop, tag::CUM) any_platform
Definition cum.h:108
constexpr auto subIndexOutgoing() any_platform
Compute opposites of wall-incoming population indices.
Definition util.h:262
auto normSqr(const ARRAY_LIKE &u) any_platform
Compute norm square of a d-dimensional vector.
Definition util.h:145
Top level namespace for all of OpenLB.
#define any_platform
Define preprocessor macros for device-side functions, constant storage.
Definition platform.h:77
Return value of any collision.
Definition interface.h:45
typename MOMENTA::template type< DESCRIPTOR > MomentaF
CellStatistic< V > apply(CELL &cell, PARAMETERS &parameters) any_platform
typename meta::list< descriptors::OMEGA > parameters
CellStatistic< V > apply(CELL &cell, PARAMETERS &parameters) any_platform
typename EQUILIBRIUM::template type< DESCRIPTOR, MOMENTA > EquilibriumF
static std::string getName()
typename meta::list< descriptors::OMEGA, GAMMA > parameters
Base of a field whose size is defined by [C_0,C_1,C_2]^T * [1,D,Q].
Definition fields.h:52
Dynamics constructed as a tuple of momenta, equilibrium and collision.
Definition interface.h:308
CellStatistic< V > compute(CELL &cell, RHO &rho, U &u, FEQ &fEq) any_platform
CellStatistic< V > compute(CELL &cell, PARAMETERS &parameters, FEQ &fEq) any_platform
typename MOMENTA::template type< DESCRIPTOR > MomentaF
static V secondOrder(int iPop, const RHO &rho, const U &u, const USQR &uSqr) any_platform
Computation of equilibrium distribution, second order in u.
Definition lbm.h:51
static V bgkCollision(CELL &cell, const RHO &rho, const VELOCITY &u, const OMEGA &omega) any_platform
BGK collision step.
Definition lbm.h:372
Plain wrapper for list of types.
Definition meta.h:276
Standard computation for density in the bulk as zeroth moment of the population.
Definition elements.h:150
The momenta are defined one after the other.
The density is stored in descriptors::FORCE[0] (TODO: absurd, to be changed)
Definition elements.h:267
Computation of the stress tensor for regularized boundary nodes.
Definition elements.h:1669
Momentum is zero at solid material.
Definition elements.h:1442
The stress is always zero.
Definition elements.h:1779