Issue with Implementing New Features in .h and .hh Files
OpenLB – Open Source Lattice Boltzmann Code › Forums › on OpenLB › General Topics › Issue with Implementing New Features in .h and .hh Files
- This topic has 7 replies, 2 voices, and was last updated 1 week, 5 days ago by mmp22squ@uea.ac.uk.
-
AuthorPosts
-
January 31, 2025 at 1:15 pm #9821mmp22squ@uea.ac.ukBlocked
I am trying to implement a new feature by modifying .h and .hh files, but I am encountering an error that is not clear regarding its origin.
Are there any additional steps required when modifying these files? Has anyone encountered similar issues? Any guidance would be appreciated!January 31, 2025 at 1:46 pm #9822AdrianKeymasterSorry, but it is basically impossible to tell you anything without you sharing at least the error message and what you changed.
January 31, 2025 at 1:56 pm #9823mmp22squ@uea.ac.ukBlockedHi Adrian
Thanks alot for replying
I’m working on modifying the Free Energy Wall Boundary implementation, and I want to introduce an indicator to distinguish between three different boundary condition models. My idea is to add an integer or an enumeration to specify which model is being used and then apply the corresponding boundary condition logic accordingly.Here is the Error
rm -f tmp/*.* tmp/vtkData/*.* tmp/vtkData/data/*.* tmp/imageData/*.* tmp/imageData/data/*.* tmp/gnuplotData/*.* tmp/gnuplotData/data/*.*
rm -f contactAngle3d.o contactAngle3d.d contactAngle3d
make -C ../../../external
make[1]: Entering directory ‘/local/mmp22squ/Downloads/olb-1.7r0/olb-1.7r0/external’
make -C zlib
make[2]: Entering directory ‘/local/mmp22squ/Downloads/olb-1.7r0/olb-1.7r0/external/zlib’
make[2]: Nothing to be done for ‘all’.
make[2]: Leaving directory ‘/local/mmp22squ/Downloads/olb-1.7r0/olb-1.7r0/external/zlib’
cp zlib/build/libz.a lib/
make -C tinyxml
make[2]: Entering directory ‘/local/mmp22squ/Downloads/olb-1.7r0/olb-1.7r0/external/tinyxml’
make[2]: Nothing to be done for ‘all’.
make[2]: Leaving directory ‘/local/mmp22squ/Downloads/olb-1.7r0/olb-1.7r0/external/tinyxml’
cp tinyxml/build/libtinyxml.a lib/
make[1]: Leaving directory ‘/local/mmp22squ/Downloads/olb-1.7r0/olb-1.7r0/external’
make -C ../../.. core
make[1]: Entering directory ‘/local/mmp22squ/Downloads/olb-1.7r0/olb-1.7r0’
make[1]: Nothing to be done for ‘core’.
make[1]: Leaving directory ‘/local/mmp22squ/Downloads/olb-1.7r0/olb-1.7r0′
g++ -O3 -Wall -march=native -mtune=native -std=c++17 -pthread -DPLATFORM_CPU_SISD -DDEFAULT_FLOATING_POINT_TYPE=double -I../../../src -I../../../external/zlib -I../../../external/tinyxml -c -o contactAngle3d.o contactAngle3d.cpp
In file included from ../../../src/dynamics/dynamics3D.h:35,
from ../../../src/olb3D.h:5,
from contactAngle3d.cpp:36:
../../../src/dynamics/freeEnergyCoupling3D.h: In instantiation of ‘void olb::ChemicalPotentialCoupling3D::apply(CELLS&, PARAMETERS&) [with CELLS = olb::utilities::TypeIndexedTuple<olb::meta::plain_map<olb::meta::list<olb::names::A, olb::names::B>, olb::meta::list<olb::cpu::Cell<double, olb::descriptors::D3Q19<olb::descriptors::CHEM_POTENTIAL, olb::descriptors::FORCE>, olb::Platform::CPU_SISD>, olb::cpu::Cell<double, olb::descriptors::D3Q19<olb::descriptors::CHEM_POTENTIAL, olb::descriptors::FORCE>, olb::Platform::CPU_SISD> > > >; PARAMETERS = olb::ParametersD<double, olb::descriptors::D3Q19<olb::descriptors::CHEM_POTENTIAL, olb::descriptors::FORCE>, olb::ChemicalPotentialCoupling3D::ALPHA, olb::ChemicalPotentialCoupling3D::KAPPA1, olb::ChemicalPotentialCoupling3D::KAPPA2, olb::ChemicalPotentialCoupling3D::KAPPA3>]’:
../../../src/core/superLatticeCoupling.h:158:5: required from ‘void olb::ConcreteBlockCouplingO<COUPLEES, PLATFORM, COUPLER, olb::OperatorScope::PerCellWithParameters>::execute(typename olb::AbstractCouplingO<COUPLEES>::LatticeR) [with COUPLER = olb::ChemicalPotentialCoupling3D; COUPLEES = olb::meta::plain_map<olb::meta::list<olb::names::A, olb::names::B>, olb::meta::list<olb::descriptors::VALUED_DESCRIPTOR<double, olb::descriptors::D3Q19<olb::descriptors::CHEM_POTENTIAL, olb::descriptors::FORCE> >, olb::descriptors::VALUED_DESCRIPTOR<double, olb::descriptors::D3Q19<olb::descriptors::CHEM_POTENTIAL, olb::descriptors::FORCE> > > >; olb::Platform PLATFORM = olb::Platform::CPU_SISD; typename olb::AbstractCouplingO<COUPLEES>::LatticeR = olb::Vector<int, 3>]’
../../../src/core/superLatticeCoupling.h:199:17: required from ‘void olb::ConcreteBlockCouplingO<COUPLEES, PLATFORM, COUPLER, olb::OperatorScope::PerCellWithParameters>::execute() [with COUPLER = olb::ChemicalPotentialCoupling3D; COUPLEES = olb::meta::plain_map<olb::meta::list<olb::names::A, olb::names::B>, olb::meta::list<olb::descriptors::VALUED_DESCRIPTOR<double, olb::descriptors::D3Q19<olb::descriptors::CHEM_POTENTIAL, olb::descriptors::FORCE> >, olb::descriptors::VALUED_DESCRIPTOR<double, olb::descriptors::D3Q19<olb::descriptors::CHEM_POTENTIAL, olb::descriptors::FORCE> > > >; olb::Platform PLATFORM = olb::Platform::CPU_SISD]’
../../../src/core/superLatticeCoupling.h:186:8: required from here
../../../src/dynamics/freeEnergyCoupling3D.h:69:7: warning: unused variable ‘term3’ [-Wunused-variable]
69 | V term3 = 0.;
| ^~~~~
g++ contactAngle3d.o -o contactAngle3d -lolbcore -L../../../external/lib -lpthread -lz -ltinyxml -L../../../build/lib
/usr/bin/ld: contactAngle3d.o: in function `prepareLattice(olb::SuperLattice<double, olb::descriptors::D3Q19<olb::descriptors::CHEM_POTENTIAL, olb::descriptors::FORCE> >&, olb::SuperLattice<double, olb::descriptors::D3Q19<olb::descriptors::CHEM_POTENTIAL, olb::descriptors::FORCE> >&, olb::UnitConverter<double, olb::descriptors::D3Q19<olb::descriptors::CHEM_POTENTIAL, olb::descriptors::FORCE> >&, olb::SuperGeometry<double, 3u>&)’:
contactAngle3d.cpp:(.text+0x154d1): undefined reference to `void olb::setFreeEnergyWallBoundary<double, olb::descriptors::D3Q19<olb::descriptors::CHEM_POTENTIAL, olb::descriptors::FORCE> >(olb::SuperLattice<double, olb::descriptors::D3Q19<olb::descriptors::CHEM_POTENTIAL, olb::descriptors::FORCE> >&, olb::SuperGeometry<double, 3u>&, int, double, double, double, double, double, int, int)’
/usr/bin/ld: contactAngle3d.cpp:(.text+0x15521): undefined reference to `void olb::setFreeEnergyWallBoundary<double, olb::descriptors::D3Q19<olb::descriptors::CHEM_POTENTIAL, olb::descriptors::FORCE> >(olb::SuperLattice<double, olb::descriptors::D3Q19<olb::descriptors::CHEM_POTENTIAL, olb::descriptors::FORCE> >&, olb::SuperGeometry<double, 3u>&, int, double, double, double, double, double, int, int)’
collect2: error: ld returned 1 exit status
make: *** [../../../default.single.mk:38: contactAngle3d] Error 1Here is .h
namespace olb {
/// Implementation of a wetting boundary condition for the ternary free energy model, consisting of a BounceBack
/// dynamics and an FreeEnergyWall PostProcessor.
/// \param[in] alpha_ – Parameter related to the interface width. [lattice units]
/// \param[in] kappa1_ – Parameter related to surface tension. [lattice units]
/// \param[in] kappa2_ – Parameter related to surface tension. [lattice units]
/// \param[in] h1_ – Parameter related to resulting contact angle of the boundary. [lattice units]
/// \param[in] h2_ – Parameter related to resulting contact angle of the boundary. [lattice units]
/// \param[in] latticeNumber – determines the number of the free energy lattice to set the boundary accordingly
/// \param[in] ModelNumber///Initialising the Free Energy Wall Boundary on the superLattice domain
template<typename T, typename DESCRIPTOR>
void setFreeEnergyWallBoundary(SuperLattice<T, DESCRIPTOR>& sLattice, SuperGeometry<T,3>& superGeometry, int material,
T alpha, T kappa1, T kappa2, T h1, T h2, int latticeNumber,int ModelNumber);///Initialising the Free Energy Wall Boundary on the superLattice domain
template<typename T, typename DESCRIPTOR>
void setFreeEnergyWallBoundary(SuperLattice<T, DESCRIPTOR>& sLattice, FunctorPtr<SuperIndicatorF3D<T>>&& indicator,
T alpha, T kappa1, T kappa2, T h1, T h2, int latticeNumber, int ModelNumber);/// Implementation of a wetting boundary condition for the ternary free energy model, consisting of a BounceBack
/// dynamics and an FreeEnergyWall PostProcessor.
/// \param[in] alpha_ – Parameter related to the interface width. [lattice units]
/// \param[in] kappa1_ – Parameter related to surface tension. [lattice units]
/// \param[in] kappa2_ – Parameter related to surface tension. [lattice units]
/// \param[in] kappa3_ – Parameter related to surface tension. [lattice units]
/// \param[in] h1_ – Parameter related to resulting contact angle of the boundary. [lattice units]
/// \param[in] h2_ – Parameter related to resulting contact angle of the boundary. [lattice units]
/// \param[in] h3_ – Parameter related to resulting contact angle of the boundary. [lattice units]
/// \param[in] latticeNumber – determines the number of the free energy lattice to set the boundary accordingly
/// \param[in] ModelNumber
///Initialising the Free Energy Wall Boundary on the superLattice domain
template<typename T, typename DESCRIPTOR>
void setFreeEnergyWallBoundary(SuperLattice<T, DESCRIPTOR>& sLattice, SuperGeometry<T,3>& superGeometry, int material,
T alpha, T kappa1, T kappa2, T kappa3, T h1, T h2,T h3, int latticeNumber, int ModelNumber);///Initialising the Free Energy Wall Boundary on the superLattice domain
template<typename T, typename DESCRIPTOR>
void setFreeEnergyWallBoundary(SuperLattice<T, DESCRIPTOR>& sLattice, FunctorPtr<SuperIndicatorF3D<T>>&& indicator,
T alpha, T kappa1, T kappa2, T kappa3, T h1, T h2, T h3, int latticeNumber, int ModelNumber);//set FreeEnergyWallBoundary on block domain.
//This function works for the setFreeEnergyWallBoundary with h1,h2,h3 Parameters and h1,h2 Parameters
template<typename T, typename DESCRIPTOR>
void setFreeEnergyWallBoundary(BlockLattice<T,DESCRIPTOR>& _block, BlockIndicatorF3D<T>& indicator,
T addend, int latticeNumber,int ModelNumber,bool includeOuterCells=false);}//namespace olb
#endif
Here is .hh
namespace olb {/// Implementation of a wetting boundary condition for the ternary free energy model, consisting of a BounceBack
/// dynamics and an FreeEnergyWall PostProcessor.
/// \param[in] alpha_ – Parameter related to the interface width. [lattice units]
/// \param[in] kappa1_ – Parameter related to surface tension. [lattice units]
/// \param[in] kappa2_ – Parameter related to surface tension. [lattice units]
/// \param[in] kappa3_ – Parameter related to surface tension. [lattice units]
/// \param[in] h1_ – Parameter related to resulting contact angle of the boundary. [lattice units]
/// \param[in] h2_ – Parameter related to resulting contact angle of the boundary. [lattice units]
/// \param[in] h3_ – Parameter related to resulting contact angle of the boundary. [lattice units]
/// \param[in] latticeNumber – determines the number of the free energy lattice to set the boundary accordingly
/// \param[in] ModelNumber
////////// SuperLattice Domain ////////////////////////////////////////////Initialising the Free Energy Wall Boundary on the superLattice domain
template<typename T, typename DESCRIPTOR>
void setFreeEnergyWallBoundary(SuperLattice<T, DESCRIPTOR>& sLattice, SuperGeometry<T,3>& superGeometry, int material,
T alpha, T kappa1, T kappa2, T kappa3, T h1, T h2,T h3, int latticeNumber,int ModelNumber)
{
setFreeEnergyWallBoundary<T,DESCRIPTOR>(sLattice, superGeometry.getMaterialIndicator(material),
alpha, kappa1, kappa2, kappa3, h1, h2, h3, latticeNumber,ModelNumber);
}///Initialising the Free Energy Wall Boundary on the superLattice domain
template<typename T, typename DESCRIPTOR>
void setFreeEnergyWallBoundary(SuperLattice<T, DESCRIPTOR>& sLattice, FunctorPtr<SuperIndicatorF3D<T>>&& indicator,
T alpha, T kappa1, T kappa2, T kappa3, T h1, T h2, T h3, int latticeNumber,int ModelNumber)
{
OstreamManager clout(std::cout, “setFreeEnergyWallBoundary”);
bool includeOuterCells = false;
int _overlap = indicator->getSuperGeometry().getOverlap();
if (indicator->getSuperGeometry().getOverlap() == 1) {
includeOuterCells = true;
clout << “WARNING: overlap == 1, boundary conditions set on overlap despite unknown neighbor materials” << std::endl;
}
T addend = 0;
if (latticeNumber==1) {
if (ModelNumber==1){
addend = 1./(alpha*alpha) * ( (h1/kappa1) + (h2/kappa2) + (h3/kappa3) );
}
}
else if (latticeNumber==2) {
if (ModelNumber==1){
addend = 1./(alpha*alpha) * ( (h1/kappa1) + (-h2/kappa2) );
}
}
else if (latticeNumber==3) {
if (ModelNumber==1){
addend = 1./(alpha*alpha) * ( (h3/kappa3) );
}
}
for (int iCloc = 0; iCloc < sLattice.getLoadBalancer().size(); ++iCloc) {
setFreeEnergyWallBoundary<T,DESCRIPTOR>(sLattice.getBlock(iCloc),
indicator->getBlockIndicatorF(iCloc), addend, latticeNumber,includeOuterCells,ModelNumber);
}
/// Adds needed Cells to the Communicator _commBC in SuperLattice
addPoints2CommBC(sLattice, std::forward<decltype(indicator)>(indicator), _overlap);
}////////// BlockLattice Domain /////////////////////////////////////////
//set FreeEnergyWallBoundary on block domain.
//This function works for the setFreeEnergyWallBoundary with h1,h2,h3 Parameters and h1,h2 Parameters
template<typename T, typename DESCRIPTOR>
void setFreeEnergyWallBoundary(BlockLattice<T,DESCRIPTOR>& _block, BlockIndicatorF3D<T>& indicator,
T addend, int latticeNumber, bool includeOuterCells,int ModelNumber)
{
using namespace boundaryhelper;
OstreamManager clout(std::cout, “setFreeEnergyWallBoundary”);
const auto& blockGeometryStructure = indicator.getBlockGeometry();
const int margin = includeOuterCells ? 0 : 1;
std::vector<int> discreteNormal(4, 0);
blockGeometryStructure.forSpatialLocations([&](auto iX, auto iY, auto iZ) {
if (blockGeometryStructure.getNeighborhoodRadius({iX, iY, iZ}) >= margin
&& indicator(iX, iY, iZ)) {
discreteNormal = blockGeometryStructure.getStatistics().getType(iX, iY, iZ, true);
if (discreteNormal[1]!=0 || discreteNormal[2]!=0 || discreteNormal[3]!=0) {
if (latticeNumber == 1) {
_block.template defineDynamics<BounceBackBulkDensity>({iX,iY,iZ});
}
else {
_block.template defineDynamics<FreeEnergyWallDynamics>({iX,iY,iZ});
}_block.addPostProcessor(
typeid(stage::PostStream), {iX, iY, iZ},
olb::boundaryhelper::promisePostProcessorForNormal<T,DESCRIPTOR,FreeEnergyWallProcessor3D>(
Vector<int,3>(discreteNormal.data() + 1)));
_block.get(iX, iY, iZ).template setField<olb::descriptors::ADDEND>(addend);if(latticeNumber == 1){
_block.addPostProcessor(
typeid(stage::PostStream), {iX, iY, iZ},
promisePostProcessorForNormal<T,DESCRIPTOR,FreeEnergyChemPotBoundaryProcessor3DA>(
Vector<int,3>(discreteNormal.data() + 1)));
} else {
_block.addPostProcessor(
typeid(stage::PostStream), {iX, iY, iZ},
promisePostProcessorForNormal<T,DESCRIPTOR,FreeEnergyChemPotBoundaryProcessor3DB>(
Vector<int,3>(discreteNormal.data() + 1)));
}}
}
});
}
}//namespace olb#endif
Here is the main
// Add wall boundary
setFreeEnergyWallBoundary<T,DESCRIPTOR>(sLattice1, superGeometry, 2, alpha, kappa1, kappa2, h1, h2, 1,1);
setFreeEnergyWallBoundary<T,DESCRIPTOR>(sLattice2, superGeometry, 2, alpha, kappa1, kappa2, h1, h2, 2,1);January 31, 2025 at 4:56 pm #9824mmp22squ@uea.ac.ukBlockedHi Adrian, I think the mistake was deleting the parts that occur twice. I can do it now, it has no error. However, I cannot see why parts of the code are repeated. Can you help me understand why?
January 31, 2025 at 8:05 pm #9827AdrianKeymasterBy appears twice you mean the separation of class / method declarations and definitions? This is what the h/hh split commonly does. The *.h file declares a class and its methods while the *.hh file actually implements it. This is a common approach in C++ – due to the growing templatization in OpenLB this becomes less necessary / helpful but it is still followed in large parts of the codebase.
I think it would be helpful for you to first learn some C++ basics before trying to use OpenLB (this is not meant to discourage you, learning C++ and OpenLB details at the same time would be a challenge for anyone).
January 31, 2025 at 8:40 pm #9828mmp22squ@uea.ac.ukBlockedDear Adrian
I totally agree with you We are learn and we will be learning fron birth to death.
However, I meant in same.hh addend along other parts are declared twice . I was not the develloper to know why and how the code works . But it seems declared twice .FYI I use c++ since 2010 .
Kind regards
MOKHTARI AhlemJanuary 31, 2025 at 8:49 pm #9829AdrianKeymasterOk, can you point out the part that is declared twice? I don’t really want to go through the entire listing you posted line by line 🙂
In general you do not need to follow the structure of the existing setter function for the modification you described. Boundary conditions in OpenLB are the dynamics and post processors at the boundary cells, the setter functions just “set them up”. If I understand you goal correctly, having separate setters per model seems to be a better approach then adding more complexity to the existing setter. I may be able to give more concrete recommendations if you describe in more detail what you want to do.
February 1, 2025 at 1:40 pm #9832mmp22squ@uea.ac.ukBlockedHi Adrian
I truly appreciate your help.
I am working on modifying the wetting boundary conditions in my free energy model by replacing the linear potentials (Eq. 24/25/26 from PhysRevE.93.033305) with cubic and quartic potential. the cubic quartic potential include c1 and c2 concentration fractions of fluids 1, 2 ,and 3 .so C1 and C2 are defined in the file olb-1.7r0/examples/multiComponent/contactAngle3d/contactAngle3d.cpp as follows:
SuperLatticeVelocity3D<T, DESCRIPTOR> velocity(sLattice1);
SuperLatticeDensity3D<T, DESCRIPTOR> rho(sLattice1);
rho.getName() = “rho”;
SuperLatticeDensity3D<T, DESCRIPTOR> phi(sLattice2);
phi.getName() = “phi”;
SuperIdentity3D<T,T> c1 (half*(rho+phi));
c1.getName() = “density-fluid-1”;
SuperIdentity3D<T,T> c2 (half*(rho-phi));
c2.getName() = “density-fluid-2”;I need to use C1 and C2 inside the : olb-1.7r0/src/boundary/setFreeEnergyWallBoundary3D.hh file, but I’m unsure how to properly set them up there. Do you have any suggestions on how to structure this so I can access them correctly in the .hh?
For the Duplicate issue:
in the src/boundary/setFreeEnergyWallBoundary3D.hhI noticed some duplicate code, and out of curiosity, I tried deleting one of the identical parts. Surprisingly, this caused an error. I understand it’s not a major issue, but it triggered my curiosity—why would removing an exact duplicate make a difference?
namespace olb {
/// Implementation of a wetting boundary condition for the ternary free energy model, consisting of a BounceBack
/// dynamics and an FreeEnergyWall PostProcessor.
/// \param[in] alpha_ – Parameter related to the interface width. [lattice units]
/// \param[in] kappa1_ – Parameter related to surface tension. [lattice units]
/// \param[in] kappa2_ – Parameter related to surface tension. [lattice units]
/// \param[in] h1_ – Parameter related to resulting contact angle of the boundary. [lattice units]
/// \param[in] h2_ – Parameter related to resulting contact angle of the boundary. [lattice units]
/// \param[in] latticeNumber – determines the number of the free energy lattice to set the boundary accordingly
/// \param[in] modelNumber
////////// SuperLattice Domain ////////////////////////////////////////////Initialising the Free Energy Wall Boundary on the superLattice domain
template<typename T, typename DESCRIPTOR>
void setFreeEnergyWallBoundary(SuperLattice<T, DESCRIPTOR>& sLattice, SuperGeometry<T,3>& superGeometry, int material,
T alpha, T kappa1, T kappa2, T h1, T h2, int latticeNumber, int modelNumber)
{
setFreeEnergyWallBoundary<T,DESCRIPTOR>(sLattice, superGeometry.getMaterialIndicator(material),
alpha, kappa1, kappa2, h1, h2, latticeNumber,modelNumber);}
//////////////
///Initialising the Free Energy Wall Boundary on the superLattice domain
template<typename T, typename DESCRIPTOR>
void setFreeEnergyWallBoundary(SuperLattice<T, DESCRIPTOR>& sLattice, FunctorPtr<SuperIndicatorF3D<T>>&& indicator,
T alpha, T kappa1, T kappa2, T h1, T h2, int latticeNumber,int modelNumber)
{
OstreamManager clout(std::cout, “setFreeEnergyWallBoundary”);
bool includeOuterCells = false;
int _overlap = 1;
if (indicator->getSuperGeometry().getOverlap() == 1) {
includeOuterCells = true;
clout << “WARNING: overlap == 1, boundary conditions set on overlap despite unknown neighbor materials” << std::endl;
}
T addend = 0;
if (latticeNumber==1) {
if (modelNumber==1) {addend = 1./(alpha*alpha) *( (h1/kappa1) + (h2/kappa2));
}
}
else if (latticeNumber==2) {
if (modelNumber==1) {
addend = 1./(alpha*alpha) * ( (h1/kappa1) + (-h2/kappa2) );
}
}
else if (latticeNumber==3) {
if (modelNumber==1) {
addend = 1./(alpha*alpha) * ( (h1/kappa1) + (h2/kappa2) );
}
}
for (int iCloc = 0; iCloc < sLattice.getLoadBalancer().size(); ++iCloc) {
setFreeEnergyWallBoundary<T,DESCRIPTOR>(sLattice.getBlock(iCloc),
indicator->getBlockIndicatorF(iCloc), addend, latticeNumber,modelNumber ,includeOuterCells);
}
/// Adds needed Cells to the Communicator _commBC in SuperLattice
addPoints2CommBC(sLattice, std::forward<decltype(indicator)>(indicator), _overlap);
}/// Implementation of a wetting boundary condition for the ternary free energy model, consisting of a BounceBack
/// dynamics and an FreeEnergyWall PostProcessor.
/// \param[in] alpha_ – Parameter related to the interface width. [lattice units]
/// \param[in] kappa1_ – Parameter related to surface tension. [lattice units]
/// \param[in] kappa2_ – Parameter related to surface tension. [lattice units]
/// \param[in] kappa3_ – Parameter related to surface tension. [lattice units]
/// \param[in] h1_ – Parameter related to resulting contact angle of the boundary. [lattice units]
/// \param[in] h2_ – Parameter related to resulting contact angle of the boundary. [lattice units]
/// \param[in] h3_ – Parameter related to resulting contact angle of the boundary. [lattice units]
/// \param[in] latticeNumber – determines the number of the free energy lattice to set the boundary accordingly////////// SuperLattice Domain /////////////////////////////////////////
///Initialising the Free Energy Wall Boundary on the superLattice domain
template<typename T, typename DESCRIPTOR>
void setFreeEnergyWallBoundary(SuperLattice<T, DESCRIPTOR>& sLattice, SuperGeometry<T,3>& superGeometry, int material,
T alpha, T kappa1, T kappa2, T kappa3, T h1, T h2,T h3, int latticeNumber,int modelNumber)
{
setFreeEnergyWallBoundary<T,DESCRIPTOR>(sLattice, superGeometry.getMaterialIndicator(material),
alpha, kappa1, kappa2, kappa3, h1, h2, h3, latticeNumber,modelNumber);
}///Initialising the Free Energy Wall Boundary on the superLattice domain
template<typename T, typename DESCRIPTOR>
void setFreeEnergyWallBoundary(SuperLattice<T, DESCRIPTOR>& sLattice, FunctorPtr<SuperIndicatorF3D<T>>&& indicator,
T alpha, T kappa1, T kappa2, T kappa3, T h1, T h2, T h3, int latticeNumber,int modelNumber)
{
OstreamManager clout(std::cout, “setFreeEnergyWallBoundary”);
bool includeOuterCells = false;
int _overlap = indicator->getSuperGeometry().getOverlap();
if (indicator->getSuperGeometry().getOverlap() == 1) {
includeOuterCells = true;
clout << “WARNING: overlap == 1, boundary conditions set on overlap despite unknown neighbor materials” << std::endl;
}
T addend = 0;
if (latticeNumber==1) {
if (modelNumber==1) {
addend = 1./(alpha*alpha) * ( (h1/kappa1) + (h2/kappa2) );
}
}
else if (latticeNumber==2) {
if (modelNumber==1) {
addend = 1./(alpha*alpha) * ( (h1/kappa1) + (-h2/kappa2) );
}
}
else if (latticeNumber==3) {
if (modelNumber==1) {
addend = 1./(alpha*alpha) * ( (h1/kappa1) + (h2/kappa2) );
}
}
for (int iCloc = 0; iCloc < sLattice.getLoadBalancer().size(); ++iCloc) {
setFreeEnergyWallBoundary<T,DESCRIPTOR>(sLattice.getBlock(iCloc),
indicator->getBlockIndicatorF(iCloc), addend, latticeNumber, modelNumber, includeOuterCells);
}
/// Adds needed Cells to the Communicator _commBC in SuperLattice
addPoints2CommBC(sLattice, std::forward<decltype(indicator)>(indicator), _overlap);
}////////// BlockLattice Domain /////////////////////////////////////////
-
AuthorPosts
- You must be logged in to reply to this topic.