Loading...
Searching...
No Matches
PABLO_bubbles_3D.cpp

3D dynamic adaptive mesh refinement (AMR) using PABLO

3D dynamic adaptive mesh refinement (AMR) using PABLOThis example creates a 3D Octree mesh on the cube domain [0,1]x[0,1]x[0,1]. The domain is adapted to track a set of moving bubbles with random initialization.

To run: ./PABLO_bubbles_3D
To see the result visit: PABLO website

/*---------------------------------------------------------------------------*\
*
* bitpit
*
* Copyright (C) 2015-2021 OPTIMAD engineering Srl
*
* -------------------------------------------------------------------------
* License
* This file is part of bitpit.
*
* bitpit is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License v3 (LGPL)
* as published by the Free Software Foundation.
*
* bitpit 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 Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with bitpit. If not, see <http://www.gnu.org/licenses/>.
*
\*---------------------------------------------------------------------------*/
#include "bitpit_PABLO.hpp"
#if BITPIT_ENABLE_MPI==1
#include "PABLO_userDataComm.hpp"
#include "PABLO_userDataLB.hpp"
#include <mpi.h>
#endif
using namespace std;
using namespace bitpit;
// =================================================================================== //
class bubble{
public:
double c[3];
double r;
};
void run()
{
int iter = 0;
PabloUniform pabloBB(3);
pabloBB.setBalanceCodimension(1);
int idx = 0;
pabloBB.setBalance(idx,true);
for (iter=1; iter<4; iter++){
pabloBB.adaptGlobalRefine();
}
#if BITPIT_ENABLE_MPI==1
pabloBB.loadBalance();
#endif
uint32_t nocts = pabloBB.getNumOctants();
srand(0);
#if BITPIT_ENABLE_MPI==1
int nb = 50;
#else
int nb = 10;
#endif
vector<bubble> BB;
vector<bubble> BB0;
vector<double> DZ;
vector<double> OM;
vector<double> AA;
for (int i=0; i<nb; i++){
double randc[3];
randc[0] = 0.8 * (double) (rand()) / RAND_MAX + 0.1;
randc[1] = 0.8 * (double) (rand()) / RAND_MAX + 0.1;
randc[2] = (double) (rand()) / RAND_MAX - 0.5;
double randr = (0.05 * (double) (rand()) / RAND_MAX + 0.04);
double dz = 0.005 + 0.05 * (double) (rand()) / RAND_MAX;
double omega = 0.5 * (double) (rand()) / RAND_MAX;
double aa = 0.15 * (double) (rand()) / RAND_MAX;
bubble bb;
bb.c[0] = randc[0];
bb.c[1] = randc[1];
bb.c[2] = randc[2];
bb.r = randr;
BB.push_back(bb);
BB0.push_back(bb);
DZ.push_back(dz);
OM.push_back(omega);
AA.push_back(aa);
}
double t0 = 0;
double t = t0;
double Dt = 0.5;
vector<double> oct_data(nocts, 0.0),oct_data_ghost;
vector<double> oct_data_new(nocts, 0.0);
int itstart = 1;
int itend = 200;
for (iter=itstart; iter<itend; iter++){
if(pabloBB.getRank()==0) cout << "iter " << iter << endl;
t += Dt;
for (int i=0; i<nb; i++){
BB[i].c[0] = BB0[i].c[0];// + AA[i]*cos(OM[i]*t);
BB[i].c[1] = BB0[i].c[1];// + AA[i]*cos(OM[i]*t);
BB[i].c[2] = BB[i].c[2]+ Dt*DZ[i];
}
bool adapt = true;
while (adapt){
for (unsigned int i=0; i<nocts; i++){
bool inside = false;
vector<array<double,3> > nodes = pabloBB.getNodes(i);
array<double,3> center = pabloBB.getCenter(i);
int ib = 0;
while (!inside && ib<nb){
double xc = BB[ib].c[0];
double yc = BB[ib].c[1];
double zc = BB[ib].c[2];
double radius = BB[ib].r;
if (((!inside))){
if (((pow((center[0]-xc),2.0)+pow((center[1]-yc),2.0)+pow((center[2]-zc),2.0) <= 1.25*pow(radius,2.0) &&
pow((center[0]-xc),2.0)+pow((center[1]-yc),2.0)+pow((center[2]-zc),2.0) >= 0.75*pow(radius,2.0)))){
if (pabloBB.getLevel(i) < 7){
pabloBB.setMarker(i,1);
oct_data[i] = 1.0;
}
else{
pabloBB.setMarker(i,0);
oct_data[i] = 1.0;
}
inside = true;
}
}
for (int j=0; j<8; j++){
double x = nodes[j][0];
double y = nodes[j][1];
double z = nodes[j][2];
if (((!inside))){
if (((pow((x-xc),2.0)+pow((y-yc),2.0)+pow((z-zc),2.0) <= 1.25*pow(radius,2.0) &&
pow((x-xc),2.0)+pow((y-yc),2.0)+pow((z-zc),2.0) >= 0.75*pow(radius,2.0)))){
if (pabloBB.getLevel(i) < 7){
pabloBB.setMarker(i,1);
oct_data[i] = 1.0;
}
else{
pabloBB.setMarker(i,0);
oct_data[i] = 1.0;
}
inside = true;
}
}
}
ib++;
}
if (!inside){
oct_data[i] = 0.0;
if (pabloBB.getLevel(i) > 3){
pabloBB.setMarker(i,3-pabloBB.getLevel(i));
}
}
}
vector<uint32_t> mapidx;
vector<bool> isghost;
adapt = pabloBB.adapt(true);
nocts = pabloBB.getNumOctants();
oct_data_new.resize(nocts, 0);
for (uint32_t i=0; i<nocts; i++){
pabloBB.getMapping(i, mapidx, isghost);
oct_data_new[i] = oct_data[mapidx[0]];
}
oct_data = oct_data_new;
vector<double>().swap(oct_data_new);
}
#if BITPIT_ENABLE_MPI==1
UserDataLB<vector<double> > data_lb(oct_data,oct_data_ghost);
pabloBB.loadBalance(data_lb);
nocts = pabloBB.getNumOctants();
#endif
pabloBB.updateConnectivity();
pabloBB.writeTest("PabloBubble3D_iter"+to_string(static_cast<unsigned long long>(iter)), oct_data);
}
}
int main(int argc, char *argv[])
{
#if BITPIT_ENABLE_MPI==1
MPI_Init(&argc,&argv);
#else
#endif
int nProcs;
int rank;
#if BITPIT_ENABLE_MPI==1
MPI_Comm_size(MPI_COMM_WORLD, &nProcs);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
#else
nProcs = 1;
rank = 0;
#endif
// Initialize the logger
log::manager().initialize(log::MODE_SEPARATE, false, nProcs, rank);
log::cout() << log::fileVerbosity(log::LEVEL_INFO);
log::cout() << log::disableConsole();
// Run the example
try {
run();
} catch (const std::exception &exception) {
log::cout() << exception.what();
exit(1);
}
#if BITPIT_ENABLE_MPI==1
MPI_Finalize();
#endif
}
PABLO Uniform is an example of user class derived from ParaTree to map ParaTree in a uniform (square/...
std::array< T, d > pow(std::array< T, d > &x, double p)
#define BITPIT_UNUSED(variable)
Definition compiler.hpp:63
Logger & cout(log::Level defaultSeverity, log::Visibility defaultVisibility)
Definition logger.cpp:1705
--- layout: doxygen_footer ---