summaryrefslogtreecommitdiff
path: root/src/functors/lattice/blockLatticeLocalF2D.hh
diff options
context:
space:
mode:
authorAdrian Kummerlaender2019-06-24 14:43:36 +0200
committerAdrian Kummerlaender2019-06-24 14:43:36 +0200
commit94d3e79a8617f88dc0219cfdeedfa3147833719d (patch)
treec1a6894679563e271f5c6ea7a17fa3462f7212a3 /src/functors/lattice/blockLatticeLocalF2D.hh
downloadgrid_refinement_openlb-94d3e79a8617f88dc0219cfdeedfa3147833719d.tar
grid_refinement_openlb-94d3e79a8617f88dc0219cfdeedfa3147833719d.tar.gz
grid_refinement_openlb-94d3e79a8617f88dc0219cfdeedfa3147833719d.tar.bz2
grid_refinement_openlb-94d3e79a8617f88dc0219cfdeedfa3147833719d.tar.lz
grid_refinement_openlb-94d3e79a8617f88dc0219cfdeedfa3147833719d.tar.xz
grid_refinement_openlb-94d3e79a8617f88dc0219cfdeedfa3147833719d.tar.zst
grid_refinement_openlb-94d3e79a8617f88dc0219cfdeedfa3147833719d.zip
Initialize at openlb-1-3
Diffstat (limited to 'src/functors/lattice/blockLatticeLocalF2D.hh')
-rw-r--r--src/functors/lattice/blockLatticeLocalF2D.hh1229
1 files changed, 1229 insertions, 0 deletions
diff --git a/src/functors/lattice/blockLatticeLocalF2D.hh b/src/functors/lattice/blockLatticeLocalF2D.hh
new file mode 100644
index 0000000..2dbcfed
--- /dev/null
+++ b/src/functors/lattice/blockLatticeLocalF2D.hh
@@ -0,0 +1,1229 @@
+/* This file is part of the OpenLB library
+ *
+ * Copyright (C) 2012 Lukas Baron, Mathias J. Krause, Albert Mink
+ * E-mail contact: info@openlb.net
+ * The most recent release of OpenLB can be downloaded at
+ * <http://www.openlb.net/>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#ifndef BLOCK_LATTICE_LOCAL_F_2D_HH
+#define BLOCK_LATTICE_LOCAL_F_2D_HH
+
+#include<vector>
+#include<cmath>
+
+#include "blockLatticeLocalF2D.h"
+#include "blockBaseF2D.h"
+#include "functors/genericF.h"
+#include "functors/analytical/analyticalF.h"
+#include "functors/analytical/indicator/indicatorF2D.h"
+#include "core/blockLattice2D.h"
+#include "communication/mpiManager.h"
+#include "core/blockLatticeStructure2D.h"
+#include "dynamics/lbHelpers.h" // for computation of lattice rho and velocity
+
+namespace olb {
+
+
+template <typename T, typename DESCRIPTOR>
+BlockLatticeDissipation2D<T,DESCRIPTOR>::BlockLatticeDissipation2D
+(BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice, const UnitConverter<T,DESCRIPTOR>& converter)
+ : BlockLatticeF2D<T,DESCRIPTOR>(blockLattice,1), _converter(converter)
+{
+ this->getName() = "dissipation";
+}
+
+// todo: get functor working
+template <typename T, typename DESCRIPTOR>
+bool BlockLatticeDissipation2D<T,DESCRIPTOR>::operator() (T output[], const int input[])
+{
+ // int globIC = input[0];
+ // int locix= input[1];
+ // int lociy= input[2];
+ // int lociz= input[3];
+ // if ( this->_blockLattice.get_load().rank(globIC) == singleton::mpi().getRank() ) {
+ // // local coords are given, fetch local cell and compute value(s)
+ // T rho, uTemp[DESCRIPTOR::d], pi[util::TensorVal<DESCRIPTOR >::n];
+ // int overlap = this->_blockLattice.getOverlap();
+ // this->_blockLattice.getExtendedBlockLattice(this->_blockLattice.get_load().loc(globIC)).get(locix+overlap, lociy+overlap, lociz+overlap).computeAllMomenta(rho, uTemp, pi);
+
+ // T PiNeqNormSqr = pi[0]*pi[0] + 2.*pi[1]*pi[1] + pi[2]*pi[2];
+ // if (util::TensorVal<DESCRIPTOR >::n == 6)
+ // PiNeqNormSqr += pi[2]*pi[2] + pi[3]*pi[3] + 2.*pi[4]*pi[4] +pi[5]*pi[5];
+
+ // T nuLattice = converter.getLatticeNu();
+ // T omega = converter.getOmega();
+ // T finalResult = PiNeqNormSqr*nuLattice*pow(omega*descriptors::invCs2<T,DESCRIPTOR>(),2)/rho/2.;
+
+ // return std::vector<T>(1,finalResult);
+ // } else {
+ // return std::vector<T>(); // empty vector
+ // }
+
+ return false;
+}
+
+template <typename T, typename DESCRIPTOR>
+BlockLatticePhysDissipation2D<T,DESCRIPTOR>::BlockLatticePhysDissipation2D
+(BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice, const UnitConverter<T,DESCRIPTOR>& converter)
+ : BlockLatticePhysF2D<T,DESCRIPTOR>(blockLattice,converter,1)
+{
+ this->getName() = "physDissipation";
+}
+
+template <typename T, typename DESCRIPTOR>
+bool BlockLatticePhysDissipation2D<T,DESCRIPTOR>::operator() (T output[], const int input[])
+{
+ T rho, uTemp[DESCRIPTOR::d], pi[util::TensorVal<DESCRIPTOR >::n];
+ this->_blockLattice.get( input[0], input[1] ).computeAllMomenta(rho, uTemp, pi);
+
+ T PiNeqNormSqr = pi[0]*pi[0] + 2.*pi[1]*pi[1] + pi[2]*pi[2];
+ if (util::TensorVal<DESCRIPTOR >::n == 6) {
+ PiNeqNormSqr += pi[2]*pi[2] + pi[3]*pi[3] + 2.*pi[4]*pi[4] + pi[5]*pi[5];
+ }
+
+ T nuLattice = this->_converter.getLatticeViscosity();
+ T omega = 1. / this->_converter.getLatticeRelaxationTime();
+ T dt = this->_converter.getConversionFactorTime();
+ output[0] = PiNeqNormSqr*nuLattice*pow(omega*descriptors::invCs2<T,DESCRIPTOR>()/rho,2)/2.*this->_converter.getPhysViscosity()/this->_converter.getLatticeViscosity()/dt/dt;
+
+ return true;
+}
+
+template <typename T, typename DESCRIPTOR>
+BlockLatticeDensity2D<T,DESCRIPTOR>::BlockLatticeDensity2D
+(BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice)
+ : BlockLatticeF2D<T,DESCRIPTOR>(blockLattice,1)
+{
+ this->getName() = "density";
+}
+
+
+template <typename T, typename DESCRIPTOR>
+bool BlockLatticeDensity2D<T,DESCRIPTOR>::operator() (T output[], const int input[])
+{
+ output[0] = this->_blockLattice.get( input[0], input[1] ).computeRho();
+ return true;
+}
+
+
+template <typename T, typename DESCRIPTOR>
+BlockLatticeVelocity2D<T,DESCRIPTOR>::BlockLatticeVelocity2D
+(BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice)
+ : BlockLatticeF2D<T,DESCRIPTOR>(blockLattice,2)
+{
+ this->getName() = "velocity";
+}
+
+template <typename T, typename DESCRIPTOR>
+bool BlockLatticeVelocity2D<T,DESCRIPTOR>::operator() (T output[], const int input[])
+{
+ T rho;
+ this->_blockLattice.get(input[0], input[1]).computeRhoU(rho,output);
+ return true;
+}
+
+/*template <typename T, typename DESCRIPTOR>
+BlockLatticeStrainRate2D<T,DESCRIPTOR>::BlockLatticeStrainRate2D
+ (BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice, const UnitConverter<T>& converter)
+ : BlockLatticePhysF2D<T,DESCRIPTOR>(blockLattice,converter,4)
+{ this->getName() = "strainRate"; }
+
+template <typename T, typename DESCRIPTOR>
+std::vector<T> BlockLatticeStrainRate2D<T,DESCRIPTOR>::operator() (std::vector<int> input) {
+
+ T strainRate[4];
+ T rho, uTemp[DESCRIPTOR::d], pi[util::TensorVal<DESCRIPTOR >::n];
+ this->_blockLattice.get( input[0], input[1] ).computeAllMomenta(rho, uTemp, pi);
+
+ T omega = this->_converter.getOmega();
+
+ strainRate[0] = -pi[0]*omega*descriptors::invCs2<T,DESCRIPTOR>()/rho/2.;
+ strainRate[1] = -pi[1]*omega*descriptors::invCs2<T,DESCRIPTOR>()/rho/2.;
+ strainRate[2] = -pi[1]*omega*descriptors::invCs2<T,DESCRIPTOR>()/rho/2.;
+ strainRate[3] = -pi[2]*omega*descriptors::invCs2<T,DESCRIPTOR>()/rho/2.;
+
+ //cout << pi[0] << " " << pi[1] << " " << pi[2] << " " << descriptors::invCs2<T,DESCRIPTOR>() << endl;
+
+ std::vector<T> output(strainRate, strainRate+4); // first adress, last adress
+ return output;
+}*/
+
+template <typename T, typename DESCRIPTOR>
+BlockLatticePhysStrainRate2D<T,DESCRIPTOR>::BlockLatticePhysStrainRate2D
+(BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice, const UnitConverter<T,DESCRIPTOR>& converter)
+ : BlockLatticePhysF2D<T,DESCRIPTOR>(blockLattice,converter,4)
+{
+ this->getName() = "strainRate";
+}
+
+template <typename T, typename DESCRIPTOR>
+bool BlockLatticePhysStrainRate2D<T,DESCRIPTOR>::operator() (T output[], const int input[])
+{
+ T rho, uTemp[DESCRIPTOR::d], pi[util::TensorVal<DESCRIPTOR >::n];
+ this->_blockLattice.get( input[0], input[1] ).computeAllMomenta(rho, uTemp, pi);
+
+ T omega = 1. / this->_converter.getLatticeRelaxationTime();
+ T dt = this->_converter.getConversionFactorTime();
+
+ output[0] = -pi[0]*omega*descriptors::invCs2<T,DESCRIPTOR>()/rho/2./dt;
+ output[1] = -pi[1]*omega*descriptors::invCs2<T,DESCRIPTOR>()/rho/2./dt;
+ output[2] = -pi[1]*omega*descriptors::invCs2<T,DESCRIPTOR>()/rho/2./dt;
+ output[3] = -pi[2]*omega*descriptors::invCs2<T,DESCRIPTOR>()/rho/2./dt;
+
+ return true;
+}
+
+template <typename T, typename DESCRIPTOR>
+BlockLatticeGeometry2D<T,DESCRIPTOR>::BlockLatticeGeometry2D
+(BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice, BlockGeometryStructure2D<T>& blockGeometry, int material)
+ : BlockLatticeF2D<T,DESCRIPTOR>(blockLattice,1), _blockGeometry(blockGeometry), _material(material)
+{
+ this->getName() = "geometry";
+}
+
+template <typename T, typename DESCRIPTOR>
+bool BlockLatticeGeometry2D<T,DESCRIPTOR>::operator() (T output[], const int input[])
+{
+ int materialTmp = _blockGeometry.getMaterial( input[0], input[1] );
+
+ if (_material != -1) {
+ if (_material == materialTmp) {
+ output[0] = T(1);
+ return true;
+ }
+ else {
+ output[0] = T();
+ return true;
+ }
+ }
+ output[0]=T(materialTmp);
+ return false;
+}
+
+
+template <typename T, typename DESCRIPTOR>
+BlockLatticeRank2D<T,DESCRIPTOR>::BlockLatticeRank2D
+(BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice)
+ : BlockLatticeF2D<T,DESCRIPTOR>(blockLattice,1)
+{
+ this->getName() = "rank";
+}
+
+template <typename T, typename DESCRIPTOR>
+bool BlockLatticeRank2D<T,DESCRIPTOR>::operator() (T output[], const int input[])
+{
+ output[0] = singleton::mpi().getRank() + 1;
+ return false;
+}
+
+
+template <typename T, typename DESCRIPTOR>
+BlockLatticeCuboid2D<T,DESCRIPTOR>::BlockLatticeCuboid2D
+(BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice, const int iC)
+ : BlockLatticeF2D<T,DESCRIPTOR>(blockLattice,1), _iC(iC)
+{
+ this->getName() = "cuboid";
+}
+
+template <typename T, typename DESCRIPTOR>
+bool BlockLatticeCuboid2D<T,DESCRIPTOR>::operator() (T output[], const int input[])
+{
+ output[0] = _iC + 1;
+ return false;
+}
+
+
+template <typename T, typename DESCRIPTOR>
+BlockLatticePhysPressure2D<T,DESCRIPTOR>::BlockLatticePhysPressure2D
+(BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice, const UnitConverter<T,DESCRIPTOR>& converter)
+ : BlockLatticePhysF2D<T,DESCRIPTOR>(blockLattice,converter,1)
+{
+ this->getName() = "physPressure";
+}
+
+
+template <typename T, typename DESCRIPTOR>
+bool BlockLatticePhysPressure2D<T,DESCRIPTOR>::operator() (T output[], const int input[])
+{
+ // lattice pressure = c_s^2 ( rho -1 )
+ T latticePressure = ( this->_blockLattice.get( input[0], input[1] ).computeRho() - 1.0 ) / descriptors::invCs2<T,DESCRIPTOR>();
+ output[0] = this->_converter.getPhysPressure(latticePressure);
+
+ return true;
+}
+
+
+template <typename T, typename DESCRIPTOR>
+BlockLatticePhysVelocity2D<T,DESCRIPTOR>::BlockLatticePhysVelocity2D
+(BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice, const UnitConverter<T,DESCRIPTOR>& converter)
+ : BlockLatticePhysF2D<T,DESCRIPTOR>(blockLattice,converter,2)
+{
+ this->getName() = "physVelocity";
+}
+
+template <typename T, typename DESCRIPTOR>
+bool BlockLatticePhysVelocity2D<T,DESCRIPTOR>::operator() (T output[], const int input[])
+{
+ T rho;
+ this->_blockLattice.get( input[0], input[1] ).computeRhoU(rho,output);
+ output[0]=this->_converter.getPhysVelocity(output[0]);
+ output[1]=this->_converter.getPhysVelocity(output[1]);
+ return true;
+}
+
+
+template<typename T, typename DESCRIPTOR, typename FIELD>
+BlockLatticeField2D<T,DESCRIPTOR,FIELD>::BlockLatticeField2D(
+ BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice)
+ : BlockLatticeF2D<T, DESCRIPTOR>(blockLattice, DESCRIPTOR::template size<FIELD>())
+{
+ this->getName() = "extField";
+}
+
+template<typename T, typename DESCRIPTOR, typename FIELD>
+bool BlockLatticeField2D<T,DESCRIPTOR,FIELD>::operator()(
+ T output[], const int input[])
+{
+ this->_blockLattice.get(input[0], input[1]).template computeField<FIELD>(output);
+ return true;
+}
+
+
+template <typename T, typename DESCRIPTOR>
+BlockLatticePhysExternalPorosity2D<T,DESCRIPTOR>::BlockLatticePhysExternalPorosity2D(
+ BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice,
+ int overlap,
+ const UnitConverter<T,DESCRIPTOR>& converter)
+ : BlockLatticePhysF2D<T,DESCRIPTOR>(blockLattice, converter, 2),
+ _overlap(overlap)
+{
+ this->getName() = "ExtPorosityField";
+}
+
+template <typename T, typename DESCRIPTOR>
+bool BlockLatticePhysExternalPorosity2D<T,DESCRIPTOR>::operator() (T output[], const int input[])
+{
+ this->_blockLattice.get(
+ input[0]+_overlap, input[1]+_overlap
+ ).template computeField<descriptors::POROSITY>(output);
+ return true;
+}
+
+template <typename T, typename DESCRIPTOR>
+BlockLatticePhysExternalVelocity2D<T,DESCRIPTOR>::BlockLatticePhysExternalVelocity2D(
+ BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice,
+ int overlap,
+ const UnitConverter<T,DESCRIPTOR>& converter)
+ : BlockLatticePhysF2D<T,DESCRIPTOR>(blockLattice, converter, 2),
+ _overlap(overlap)
+{
+ this->getName() = "ExtVelocityField";
+}
+
+template <typename T, typename DESCRIPTOR>
+bool BlockLatticePhysExternalVelocity2D<T,DESCRIPTOR>::operator() (T output[], const int input[])
+{
+ this->_blockLattice.get(
+ input[0]+_overlap, input[1]+_overlap
+ ).template computeField<descriptors::VELOCITY>(output);
+ output[0] = this->_converter.getPhysVelocity(output[0]);
+ output[1] = this->_converter.getPhysVelocity(output[1]);
+ return true;
+}
+
+template <typename T, typename DESCRIPTOR>
+BlockLatticePhysExternalParticleVelocity2D<T,DESCRIPTOR>::BlockLatticePhysExternalParticleVelocity2D
+(BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice, const UnitConverter<T,DESCRIPTOR>& converter)
+ : BlockLatticePhysF2D<T,DESCRIPTOR>(blockLattice,converter,2)
+{
+ this->getName() = "ExtParticleVelocityField";
+}
+
+template <typename T, typename DESCRIPTOR>
+bool BlockLatticePhysExternalParticleVelocity2D<T,DESCRIPTOR>::operator() (T output[], const int input[])
+{
+ const T* velocity_numerator = this->blockLattice.get(input).template getFieldPointer<descriptors::VELOCITY_NUMERATOR>();
+ const T* velocity_denominator = this->blockLattice.get(input).template getFieldPointer<descriptors::VELOCITY_DENOMINATOR>();
+
+ if (velocity_denominator[0] > std::numeric_limits<T>::epsilon()) {
+ output[0]=this->_converter.getPhysVelocity(velocity_numerator[0]/velocity_denominator[0]);
+ output[1]=this->_converter.getPhysVelocity(velocity_numerator[1]/velocity_denominator[0]);
+ return true;
+ }
+ output[0]=this->_converter.getPhysVelocity(velocity_numerator[0]);
+ output[1]=this->_converter.getPhysVelocity(velocity_numerator[1]);
+ return true;
+}
+
+template <typename T, typename DESCRIPTOR>
+BlockLatticePhysWallShearStress2D<T,DESCRIPTOR>::BlockLatticePhysWallShearStress2D(
+ BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice,
+ BlockGeometryStructure2D<T>& blockGeometry,
+ int overlap,
+ int material,
+ const UnitConverter<T,DESCRIPTOR>& converter,
+ IndicatorF2D<T>& indicator)
+ : BlockLatticePhysF2D<T,DESCRIPTOR>(blockLattice,converter,1),
+ _blockGeometry(blockGeometry), _overlap(overlap), _material(material)
+{
+ this->getName() = "physWallShearStress";
+ const T scaling = this->_converter.getConversionFactorLength() * 0.1;
+ const T omega = 1. / this->_converter.getLatticeRelaxationTime();
+ const T dt = this->_converter.getConversionFactorTime();
+ _physFactor = -omega * descriptors::invCs2<T,DESCRIPTOR>() / dt * this->_converter.getPhysDensity() * this->_converter.getPhysViscosity();
+ std::vector<int> discreteNormalOutwards(3, 0);
+
+ for (int iX = 1; iX < _blockGeometry.getNx() - 1; iX++) {
+ _discreteNormal.resize(_blockGeometry.getNx() - 2);
+ _normal.resize(_blockGeometry.getNx() - 2);
+
+ for (int iY = 1; iY < _blockGeometry.getNy() - 1; iY++) {
+ _discreteNormal[iX-1].resize(_blockGeometry.getNy() - 2);
+ _normal[iX-1].resize(_blockGeometry.getNy() - 2);
+
+ if (_blockGeometry.get(iX, iY) == _material) {
+ discreteNormalOutwards = _blockGeometry.getStatistics().getType(iX, iY);
+ _discreteNormal[iX-1][iY-1].resize(2);
+ _normal[iX-1][iY-1].resize(2);
+
+ _discreteNormal[iX-1][iY-1][0] = -discreteNormalOutwards[1];
+ _discreteNormal[iX-1][iY-1][1] = -discreteNormalOutwards[2];
+
+ T physR[2];
+ _blockGeometry.getPhysR(physR, iX, iY);
+ Vector<T,2> origin(physR[0],physR[1]);
+ Vector<T,2> direction(-_discreteNormal[iX-1][iY-1][0] * scaling,
+ -_discreteNormal[iX-1][iY-1][1] * scaling);
+ Vector<T,2> normal(0.,0.);
+ origin[0] = physR[0];
+ origin[1] = physR[1];
+
+ indicator.normal(normal, origin, direction);
+ normal.normalize();
+
+ _normal[iX-1][iY-1][0] = normal[0];
+ _normal[iX-1][iY-1][1] = normal[0];
+ }
+ }
+ }
+}
+
+template <typename T, typename DESCRIPTOR>
+bool BlockLatticePhysWallShearStress2D<T,DESCRIPTOR>::operator() (T output[], const int input[])
+{
+ output[0] = T();
+
+ if (input[0] + _overlap < 1 ||
+ input[1] + _overlap < 1 ||
+ input[0] + _overlap >= _blockGeometry.getNx()-1 ||
+ input[1] + _overlap >= _blockGeometry.getNy()-1){
+#ifdef OLB_DEBUG
+ std::cout << "Input address not mapped by _discreteNormal, overlap too small" << std::endl;
+#endif
+ return true;
+ }
+
+ if (this->_blockGeometry.get(input[0]+_overlap,input[1]+_overlap)==_material) {
+
+ T traction[2];
+ T stress[3];
+ T rho = this->_blockLattice.get(input[0] + _overlap + _discreteNormal[input[0]+_overlap-1][input[1]+_overlap-1][0],
+ input[1] + _overlap + _discreteNormal[input[0]+_overlap-1][input[1]+_overlap-1][1]).computeRho();
+
+ this->_blockLattice.get(input[0] + _overlap + _discreteNormal[input[0]+_overlap-1][input[1]+_overlap-1][0],
+ input[1] + _overlap + _discreteNormal[input[0]+_overlap-1][input[1]+_overlap-1][1]).computeStress(stress);
+
+ traction[0] = stress[0]*_physFactor/rho*_normal[input[0]+_overlap-1][input[1]+_overlap-1][0] +
+ stress[1]*_physFactor/rho*_normal[input[0]+_overlap-1][input[1]+_overlap-1][1];
+ traction[1] = stress[1]*_physFactor/rho*_normal[input[0]+_overlap-1][input[1]+_overlap-1][0] +
+ stress[2]*_physFactor/rho*_normal[input[0]+_overlap-1][input[1]+_overlap-1][1];
+
+ T traction_normal_SP;
+ T tractionNormalComponent[2];
+ // scalar product of traction and normal vector
+ traction_normal_SP = traction[0] * _normal[input[0]+_overlap-1][input[1]+_overlap-1][0] +
+ traction[1] * _normal[input[0]+_overlap-1][input[1]+_overlap-1][1];
+ tractionNormalComponent[0] = traction_normal_SP * _normal[input[0]+_overlap-1][input[1]+_overlap-1][0];
+ tractionNormalComponent[1] = traction_normal_SP * _normal[input[0]+_overlap-1][input[1]+_overlap-1][1];
+
+ T WSS[2];
+ WSS[0] = traction[0] - tractionNormalComponent[0];
+ WSS[1] = traction[1] - tractionNormalComponent[1];
+ // magnitude of the wall shear stress vector
+ output[0] = sqrt(WSS[0]*WSS[0] + WSS[1]*WSS[1]);
+ return true;
+ }
+ else {
+ return true;
+ }
+}
+
+template <typename T, typename DESCRIPTOR>
+BlockLatticePhysBoundaryForce2D<T,DESCRIPTOR>::BlockLatticePhysBoundaryForce2D(
+ BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice,
+ BlockIndicatorF2D<T>& indicatorF,
+ const UnitConverter<T,DESCRIPTOR>& converter)
+ : BlockLatticePhysF2D<T,DESCRIPTOR>(blockLattice, converter, 2),
+ _indicatorF(indicatorF),
+ _blockGeometry(indicatorF.getBlockGeometryStructure())
+{
+ this->getName() = "physBoundaryForce";
+}
+
+template <typename T, typename DESCRIPTOR>
+bool BlockLatticePhysBoundaryForce2D<T,DESCRIPTOR>::operator() (T output[], const int input[])
+{
+ for (int i = 0; i < this->getTargetDim(); ++i) {
+ output[i] = T();
+ }
+
+ if (_indicatorF(input)) {
+ for (int iPop = 1; iPop < DESCRIPTOR::q; ++iPop) {
+ // Get direction
+ // Get next cell located in the current direction
+ // Check if the next cell is a fluid node
+ if (_blockGeometry.get(input[0] + descriptors::c<DESCRIPTOR >(iPop,0), input[1] + descriptors::c<DESCRIPTOR >(iPop,1)) == 1) {
+ // Get f_q of next fluid cell where l = opposite(q)
+ T f = this->_blockLattice.get(input[0] + descriptors::c<DESCRIPTOR >(iPop,0), input[1] + descriptors::c<DESCRIPTOR >(iPop,1))[iPop];
+ // Get f_l of the boundary cell
+ // Add f_q and f_opp
+ f += this->_blockLattice.get(input[0], input[1])[util::opposite<DESCRIPTOR >(iPop)];
+ // Update force
+ for (int i = 0; i < this->getTargetDim(); ++i) {
+ output[i] -= descriptors::c<DESCRIPTOR >(iPop,i) * f;
+ }
+ }
+ }
+ for (int i = 0; i < this->getTargetDim(); ++i) {
+ output[i] = this->_converter.getPhysForce(output[i]);
+ }
+ }
+ return true;
+}
+
+template <typename T, typename DESCRIPTOR>
+BlockLatticePSMPhysForce2D<T,DESCRIPTOR>::BlockLatticePSMPhysForce2D(
+ BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice,
+ const UnitConverter<T,DESCRIPTOR>& converter,
+ int mode_)
+ : BlockLatticePhysF2D<T,DESCRIPTOR>(blockLattice, converter, 2)
+{
+ this->getName() = "physPSMForce";
+ mode = (Mode) mode_;
+}
+
+template<typename T, typename DESCRIPTOR>
+bool BlockLatticePSMPhysForce2D<T, DESCRIPTOR>::operator()(T output[], const int input[])
+{
+ for (int i = 0; i < this->getTargetDim(); ++i) {
+ output[i] = T();
+ }
+
+ T epsilon = 1. - *(this->_blockLattice.get(input[0], input[1]).template getFieldPointer<descriptors::POROSITY>());
+
+ //if ((epsilon > 1e-5 && epsilon < 1 - 1e-5)) {
+ if ((epsilon > 1e-5)) {
+ T rho, u[DESCRIPTOR::d], u_s[DESCRIPTOR::d];
+
+ for (int i = 0; i < DESCRIPTOR::d; i++) {
+ u_s[i] = (this->_blockLattice.get(input[0], input[1]).template getFieldPointer<descriptors::VELOCITY_SOLID>())[i];
+ }
+ T paramA = this->_converter.getLatticeRelaxationTime() - 0.5;
+ // speed up paramB
+ T paramB = (epsilon * paramA) / ((1. - epsilon) + paramA);
+
+ T omega_s;
+ T omega = 1. / this->_converter.getLatticeRelaxationTime();
+
+ this->_blockLattice.get(input[0], input[1]).computeRhoU(rho, u);
+
+ const T uSqr_s = util::normSqr<T,DESCRIPTOR::d>(u_s);
+ T uSqr = util::normSqr<T,DESCRIPTOR::d>(u);
+ for (int iPop=0; iPop < DESCRIPTOR::q; ++iPop) {
+ switch (mode) {
+ case M2:
+ omega_s = (lbDynamicsHelpers<T, DESCRIPTOR>::equilibrium(iPop, rho, u_s, uSqr_s)
+ - this->_blockLattice.get(input[0], input[1])[iPop])
+ + (1 - omega)
+ * (this->_blockLattice.get(input[0], input[1])[iPop]
+ - lbDynamicsHelpers<T, DESCRIPTOR>::equilibrium(iPop, rho, u, uSqr));
+ break;
+ case M3:
+ omega_s =
+ (this->_blockLattice.get(input[0], input[1])[descriptors::opposite<DESCRIPTOR>(iPop)]
+ - lbDynamicsHelpers<T, DESCRIPTOR>::equilibrium(
+ descriptors::opposite<DESCRIPTOR>(iPop), rho, u_s, uSqr_s))
+ - (this->_blockLattice.get(input[0], input[1])[iPop]
+ - lbDynamicsHelpers<T, DESCRIPTOR>::equilibrium(iPop, rho, u_s, uSqr_s));
+ }
+
+ for (int i = 0; i < this->getTargetDim(); ++i) {
+ output[i] -= descriptors::c<DESCRIPTOR>(iPop,i) * omega_s;
+ }
+ }
+
+ for (int i = 0; i < this->getTargetDim(); ++i) {
+ output[i] = this->_converter.getPhysForce(output[i] * paramB);
+ }
+ }
+ return true;
+}
+
+template <typename T, typename DESCRIPTOR>
+BlockLatticePhysCorrBoundaryForce2D<T,DESCRIPTOR>::BlockLatticePhysCorrBoundaryForce2D
+(BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice,BlockGeometry2D<T>& blockGeometry,
+ int material, const UnitConverter<T,DESCRIPTOR>& converter)
+ : BlockLatticePhysF2D<T,DESCRIPTOR>(blockLattice,converter,2),
+ _blockGeometry(blockGeometry), _material(material)
+{
+ this->getName() = "physCorrBoundaryForce";
+}
+
+template <typename T, typename DESCRIPTOR>
+bool BlockLatticePhysCorrBoundaryForce2D<T,DESCRIPTOR>::operator() (T output[], const int input[])
+{
+ // int globIC = input[0];
+ // int locix= input[1];
+ // int lociy= input[2];
+ // int lociz= input[3];
+
+ // std::vector<T> force(3, T());
+ // if ( this->_blockLattice.get_load().rank(globIC) == singleton::mpi().getRank() ) {
+ // int globX = (int)this->_blockLattice.get_cGeometry().get(globIC).get_globPosX() + locix;
+ // int globY = (int)this->_blockLattice.get_cGeometry().get(globIC).get_globPosY() + lociy;
+ // int globZ = (int)this->_blockLattice.get_cGeometry().get(globIC).get_globPosZ() + lociz;
+ // if(BlockGeometry.getMaterial(globX, globY, globZ) == material) {
+ // for (int iPop = 1; iPop < DESCRIPTOR::q ; ++iPop) {
+ // // Get direction
+ // const int* c = DESCRIPTOR::c[iPop];
+ // // Get next cell located in the current direction
+ // // Check if the next cell is a fluid node
+ // if (BlockGeometry.getMaterial(globX + c[0], globY + c[1], globZ + c[2]) == 1) {
+ // int overlap = this->_blockLattice.getOverlap();
+ // // Get f_q of next fluid cell where l = opposite(q)
+ // T f = this->_blockLattice.getExtendedBlockLattice(this->_blockLattice.get_load().loc(globIC)).get(locix+overlap + c[0], lociy+overlap + c[1], lociz+overlap + c[2])[iPop];
+ // // Get f_l of the boundary cell
+ // // Add f_q and f_opp
+ // f += this->_blockLattice.getExtendedBlockLattice(this->_blockLattice.get_load().loc(globIC)).get(locix+overlap, lociy+overlap, lociz+overlap)[util::opposite<DESCRIPTOR >(iPop)];
+ // // Update force
+ // force[0] -= c[0]*(f-2.*descriptors::t<T,DESCRIPTOR>(iPop));
+ // force[1] -= c[1]*(f-2.*descriptors::t<T,DESCRIPTOR>(iPop));
+ // force[2] -= c[2]*(f-2.*descriptors::t<T,DESCRIPTOR>(iPop));
+ // }
+ // }
+ // force[0]=this->_converter.physForce(force[0]);
+ // force[1]=this->_converter.physForce(force[1]);
+ // force[2]=this->_converter.physForce(force[2]);
+ // return force;
+ // }
+ // else {
+ // return force;
+ // }
+ // }
+ // else {
+ // return force;
+ // }
+ return false;
+}
+
+
+template <typename T, typename DESCRIPTOR>
+BlockLatticePorosity2D<T,DESCRIPTOR>::BlockLatticePorosity2D
+(BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice, BlockGeometryStructure2D<T>& blockGeometry,
+ int material, const UnitConverter<T,DESCRIPTOR>& converter)
+ : BlockLatticePhysF2D<T,DESCRIPTOR>(blockLattice,converter,1), _blockGeometry(blockGeometry), _material(material)
+{
+ this->getName() = "porosity";
+}
+
+// under construction
+template <typename T, typename DESCRIPTOR>
+bool BlockLatticePorosity2D<T,DESCRIPTOR>::operator()(T output[], const int input[])
+{
+ return false;
+}
+
+template<typename T, typename DESCRIPTOR>
+BlockLatticeVolumeFractionApproximation2D<T, DESCRIPTOR>::BlockLatticeVolumeFractionApproximation2D(BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice,
+ BlockGeometryStructure2D<T>& blockGeometry,
+ IndicatorF2D<T>& indicator,
+ int refinementLevel,
+ const UnitConverter<T,DESCRIPTOR>& converter,
+ bool insideOut)
+ : BlockLatticeF2D<T, DESCRIPTOR>(blockLattice, 1),
+ _blockGeometry(blockGeometry), _indicator(indicator), _refinementLevel(refinementLevel), _converter(converter), _insideOut(insideOut),
+ _physSubGridMinPhysRshift((1./ T(_refinementLevel * 2.) - 0.5) * _converter.getPhysDeltaX()),
+ _physSubGridDeltaX(1. / T(_refinementLevel) * _converter.getPhysDeltaX()),
+ _latticeSubGridVolume(1. / (_refinementLevel * _refinementLevel))
+{
+ this->getName() = "volumeFractionApproximation";
+}
+
+template<typename T, typename DESCRIPTOR>
+bool BlockLatticeVolumeFractionApproximation2D<T, DESCRIPTOR>::operator()(T output[], const int input[])
+{
+ output[0] = 0.;
+ T physR[2];
+ bool inside[1];
+ _blockGeometry.getPhysR(physR, input[0], input[1]);
+
+ T subGridMinPhysR[2];
+ subGridMinPhysR[0] = physR[0] + _physSubGridMinPhysRshift;
+ subGridMinPhysR[1] = physR[1] + _physSubGridMinPhysRshift;
+
+ for (int x = 0; x < _refinementLevel; x++) {
+ for (int y = 0; y < _refinementLevel; y++) {
+ physR[0] = subGridMinPhysR[0] + x * _physSubGridDeltaX;
+ physR[1] = subGridMinPhysR[1] + y * _physSubGridDeltaX;
+ _indicator(inside, physR);
+ if (!_insideOut) {
+ if (inside[0]) {
+ output[0] += _latticeSubGridVolume;
+ }
+ }
+ else {
+ if (!inside[0]) {
+ output[0] += _latticeSubGridVolume;
+ }
+ }
+ }
+ }
+ return true;
+}
+
+
+
+template<typename T, typename DESCRIPTOR>
+BlockLatticeVolumeFractionPolygonApproximation2D<T, DESCRIPTOR>::BlockLatticeVolumeFractionPolygonApproximation2D(BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice,
+ BlockGeometryStructure2D<T>& blockGeometry,
+ IndicatorF2D<T>& indicator,
+ const UnitConverter<T,DESCRIPTOR>& converter,
+ bool insideOut)
+ : BlockLatticeF2D<T, DESCRIPTOR>(blockLattice, 1),
+ _blockGeometry(blockGeometry), _indicator(indicator), _converter(converter), _insideOut(insideOut)
+{
+ this->getName() = "volumeFractionPolygonApproximation";
+}
+
+template<typename T, typename DESCRIPTOR>
+bool BlockLatticeVolumeFractionPolygonApproximation2D<T, DESCRIPTOR>::operator()(T output[], const int input[])
+{
+ output[0] = 0.;
+ T physR[2];
+
+ bool cornerXMYM_inside[1];
+ bool cornerXMYP_inside[1];
+ bool cornerXPYM_inside[1];
+ bool cornerXPYP_inside[1];
+ _blockGeometry.getPhysR(physR, input[0], input[1]);
+
+ T cornerXMYM[2];
+ T cornerXMYP[2];
+ T cornerXPYM[2];
+ T cornerXPYP[2];
+
+ cornerXMYM[0] = physR[0] - 0.5*_converter.getPhysDeltaX();
+ cornerXMYM[1] = physR[1] - 0.5*_converter.getPhysDeltaX();
+
+ cornerXMYP[0] = physR[0] - 0.5*_converter.getPhysDeltaX();
+ cornerXMYP[1] = physR[1] + 0.5*_converter.getPhysDeltaX();
+
+ cornerXPYM[0] = physR[0] + 0.5*_converter.getPhysDeltaX();
+ cornerXPYM[1] = physR[1] - 0.5*_converter.getPhysDeltaX();
+
+ cornerXPYP[0] = physR[0] + 0.5*_converter.getPhysDeltaX();
+ cornerXPYP[1] = physR[1] + 0.5*_converter.getPhysDeltaX();
+
+ _indicator(cornerXMYM_inside, cornerXMYM);
+ _indicator(cornerXMYP_inside, cornerXMYP);
+ _indicator(cornerXPYM_inside, cornerXPYM);
+ _indicator(cornerXPYP_inside, cornerXPYP);
+
+ if ((cornerXMYM_inside[0] && cornerXMYP_inside[0] && cornerXPYM_inside[0] && cornerXPYP_inside[0]) ||
+ (!cornerXMYM_inside[0] && !cornerXMYP_inside[0] && !cornerXPYM_inside[0] && !cornerXPYP_inside[0]) ) {
+ if (!_insideOut) {
+ if (cornerXMYM_inside[0]) {
+ output[0] = 1.0;
+ }
+ }
+ else {
+ if (!cornerXMYM_inside[0]) {
+ output[0] = 1.0;
+ }
+ }
+ } else {
+ Vector<T,2> cornerXMYM_vec(physR[0] - 0.5*_converter.getPhysDeltaX(), physR[1] - 0.5*_converter.getPhysDeltaX());
+ Vector<T,2> cornerXPYP_vec(physR[0] + 0.5*_converter.getPhysDeltaX(), physR[1] + 0.5*_converter.getPhysDeltaX());
+
+ Vector<T,2> directionXP(_converter.getPhysDeltaX(), 0);
+ Vector<T,2> directionXM(-_converter.getPhysDeltaX(), 0);
+ Vector<T,2> directionYP(0, _converter.getPhysDeltaX());
+ Vector<T,2> directionYM(0, -_converter.getPhysDeltaX());
+
+ T distanceXP = 1.01 * _converter.getPhysDeltaX();
+ T distanceXM = 1.01 * _converter.getPhysDeltaX();
+ T distanceYP = 1.01 * _converter.getPhysDeltaX();
+ T distanceYM = 1.01 * _converter.getPhysDeltaX();
+
+ if ((cornerXMYM_inside[0] && !cornerXMYP_inside[0]) ||
+ (!cornerXMYM_inside[0] && cornerXMYP_inside[0]) ) {
+ _indicator.distance(distanceYP, cornerXMYM, directionYP);
+ }
+
+ if ((cornerXMYM_inside[0] && !cornerXPYM_inside[0]) ||
+ (!cornerXMYM_inside[0] && cornerXPYM_inside[0]) ) {
+ _indicator.distance(distanceXP, cornerXMYM, directionXP);
+ }
+
+ if ((cornerXPYP_inside[0] && !cornerXMYP_inside[0]) ||
+ (!cornerXPYP_inside[0] && cornerXMYP_inside[0]) ) {
+ _indicator.distance(distanceXM, cornerXPYP, directionXM);
+ }
+
+ if ((cornerXPYP_inside[0] && !cornerXPYM_inside[0]) ||
+ (!cornerXPYP_inside[0] && cornerXPYM_inside[0]) ) {
+ _indicator.distance(distanceYM, cornerXPYP, directionYM);
+ }
+
+ T volumeFraction = 0.0;
+
+ if (distanceXP < _converter.getPhysDeltaX() && distanceXM < _converter.getPhysDeltaX()) {
+ volumeFraction = distanceXP * _converter.getPhysDeltaX();
+ volumeFraction += 0.5 * (_converter.getPhysDeltaX() - distanceXM - distanceXP) * _converter.getPhysDeltaX();
+ volumeFraction /= _converter.getPhysDeltaX() * _converter.getPhysDeltaX();
+ if (!cornerXMYM_inside[0]) {
+ volumeFraction = 1.0 - volumeFraction;
+ }
+ }
+
+ if (distanceYP < _converter.getPhysDeltaX() && distanceYM < _converter.getPhysDeltaX()) {
+ volumeFraction = distanceYP * _converter.getPhysDeltaX();
+ volumeFraction += 0.5 * (_converter.getPhysDeltaX() - distanceYM - distanceYP) * _converter.getPhysDeltaX();
+ volumeFraction /= _converter.getPhysDeltaX() * _converter.getPhysDeltaX();
+ if (!cornerXMYM_inside[0]) {
+ volumeFraction = 1.0 - volumeFraction;
+ }
+ }
+
+ if (distanceXP < _converter.getPhysDeltaX() && distanceYP < _converter.getPhysDeltaX()) {
+ volumeFraction = 0.5 * distanceXP * distanceYP;
+ volumeFraction /= _converter.getPhysDeltaX() * _converter.getPhysDeltaX();
+ if (!cornerXMYM_inside[0]) {
+ volumeFraction = 1.0 - volumeFraction;
+ }
+ }
+
+ if (distanceXM < _converter.getPhysDeltaX() && distanceYM < _converter.getPhysDeltaX()) {
+ volumeFraction = 0.5 * distanceXM * distanceYM;
+ volumeFraction /= _converter.getPhysDeltaX() * _converter.getPhysDeltaX();
+ if (!cornerXPYP_inside[0]) {
+ volumeFraction = 1.0 - volumeFraction;
+ }
+ }
+
+ if (distanceXM < _converter.getPhysDeltaX() && distanceYP < _converter.getPhysDeltaX()) {
+ volumeFraction = 0.5 * (_converter.getPhysDeltaX() - distanceXM) * (_converter.getPhysDeltaX() - distanceYP);
+ volumeFraction /= _converter.getPhysDeltaX() * _converter.getPhysDeltaX();
+ if (!cornerXMYP_inside[0]) {
+ volumeFraction = 1.0 - volumeFraction;
+ }
+ }
+
+ if (distanceYM < _converter.getPhysDeltaX() && distanceXP < _converter.getPhysDeltaX()) {
+ volumeFraction = 0.5 * (_converter.getPhysDeltaX() - distanceXP) * (_converter.getPhysDeltaX() - distanceYM);
+ volumeFraction /= _converter.getPhysDeltaX() * _converter.getPhysDeltaX();
+ if (!cornerXPYM_inside[0]) {
+ volumeFraction = 1.0 - volumeFraction;
+ }
+ }
+
+ if (!_insideOut) {
+ output[0] = volumeFraction;
+ }
+ else {
+ output[0] = 1.0 - volumeFraction;
+ }
+
+ }
+ return true;
+}
+
+
+
+template <typename T, typename DESCRIPTOR>
+BlockLatticePhysPermeability2D<T,DESCRIPTOR>::BlockLatticePhysPermeability2D
+(BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice, BlockGeometryStructure2D<T>& blockGeometry,
+ int material, const UnitConverter<T,DESCRIPTOR>& converter)
+ : BlockLatticePhysF2D<T,DESCRIPTOR>(blockLattice,converter,1), _blockGeometry(blockGeometry), _material(material)
+{
+ this->getName() = "permeability";
+}
+
+template <typename T, typename DESCRIPTOR>
+bool BlockLatticePhysPermeability2D<T,DESCRIPTOR>::operator()(T output[], const int input[])
+{
+ return false;
+}
+
+
+template <typename T, typename DESCRIPTOR>
+BlockLatticePhysDarcyForce2D<T,DESCRIPTOR>::BlockLatticePhysDarcyForce2D
+(BlockLatticeStructure2D<T,DESCRIPTOR>& blockLattice, BlockGeometry2D<T>& blockGeometry,
+ int material, const UnitConverter<T,DESCRIPTOR>& converter)
+ : BlockLatticePhysF2D&