28#include "Grid/grid_dist_id.hpp"
29#include "Vector/vector_dist.hpp"
30#include "FiniteDifference/FD_op.hpp"
33#include "interpolation/interpolation.hpp"
34#include "interpolation/mp4_kernel.hpp"
38#include "spatial_discretization/finite_difference/derivative.hpp"
39#include "interp_kernel/m4_kernel.hpp"
45int main(
int argc,
char * argv[]) {
47 openfpm_init(&argc,&argv);
50 timer ttotal, tcp, tExtQ, tExtRHS, tLap, tAll;
51 const size_t mpiSize{v_cl.
size()};
57 const int ANALYTLB{3};
60 const int TMP_EXT_SCAL{6};
62 const int NUMLB_PART{0};
63 const int ANALYTLB_PART{1};
64 const int ABSERR_PART{2};
67 std::string cwd{boost::filesystem::current_path().string()};
68 std::string output_dir{cwd +
"/output_sphereR1_CartLap"};
71 std::ofstream norms_file, normsParticles_file, timesCPU_file, timesWCT_file;
72 if (v_cl.
rank() == 0) {
73 norms_file.open(output_dir +
"/norms_EucLap_mpiSize_" + std::to_string(mpiSize) +
".csv", std::ios_base::app);
74 normsParticles_file.open(output_dir +
"/normsParticles_EucLap_mpiSize_" + std::to_string(mpiSize) +
".csv", std::ios_base::app);
75 timesCPU_file.open(output_dir +
"/timesCPU_EucLap_mpiSize_" + std::to_string(mpiSize) +
".csv", std::ios_base::app);
76 timesWCT_file.open(output_dir +
"/timesWCT_EucLap_mpiSize_" + std::to_string(mpiSize) +
".csv", std::ios_base::app);
77 if (norms_file.is_open() ==
false or normsParticles_file.is_open() ==
false or timesCPU_file.is_open() ==
false or timesWCT_file.is_open() ==
false) {
78 std::cout <<
"ERROR: File(s) is(are) not open.\n";
81 norms_file <<
"#N L2 Linf" << std::endl;
82 normsParticles_file <<
"#N L2 Linf" << std::endl;
83 timesCPU_file <<
"#N tcp tExtQ tAll tExtRHS tLap ttotal" << std::endl;
84 timesWCT_file <<
"#N tcp tExtQ tAll tExtRHS tLap ttotal" << std::endl;
88 const double radius{1.0};
89 const std::array<double,DIM> center{0.0,0.0,0.0};
90 const int nb_width{10};
91 const int nb_half_width{nb_width/2};
93 const int POLYORD_EXT{3};
97 double boxP1{-2.0}, boxP2{2.0};
98 double boxSize{boxP2-boxP1};
111 std::vector<grid_dist_key_dx<grid_type::dims,grid_key_dx<grid_type::dims>>> nb_keys, nb_keys_error;
113 int n[7] = {73,87,110,140,178,211,250};
114 int n_part[7] = {3600,6000,12000,24000,48000,80000,128000};
120 for (
int i = 6; i < 7; ++i) {
129 g_output = {output_dir +
"/sphereR1_SurfLap_" + std::to_string(n[i]) +
"_mpiSize_" + std::to_string(mpiSize)};
132 size_t sz[DIM] = {n[i],n[i],n[i]};
134 grid.setPropNames(GpropNames);
138 particlesSurf.setPropNames(PpropNames);
140 std::array<double,DIM> coord;
142 if (v_cl.
rank() == 0) {
145 const double pi{3.14159265358979323846};
146 const double golden_ang = pi*(3.0 - std::sqrt(5.0));
147 const double prefactor{3.0/16.0 * std::sqrt(1.0/pi)};
148 double rad, theta, arg, thetaB, cos2;
150 for (
int j = 0; j < n_part[i]; ++j) {
152 coord[1] = 1.0 - 2.0*(j/double(n_part[i]-1));
153 rad = std::sqrt(1.0 - (coord[1]-center[1])*(coord[1]-center[1]));
154 theta = golden_ang * j;
155 coord[0] = std::cos(theta) * rad;
156 coord[2] = std::sin(theta) * rad;
158 arg = (coord[0]-center[0]) * (coord[0]-center[0]) + (coord[1]-center[1]) * (coord[1]-center[1]);
159 thetaB = std::atan2(std::sqrt(arg),(coord[2]-center[2]));
160 cos2 = std::cos(thetaB)*std::cos(thetaB);
163 particlesSurf.getLastPos()[0] = coord[0];
164 particlesSurf.getLastPos()[1] = coord[1];
165 particlesSurf.getLastPos()[2] = coord[2];
166 particlesSurf.getLastProp<ANALYTLB_PART>() = -20.0 * prefactor * (cos2*(35.0*cos2 - 30.0) + 3.0); ;
171 if (v_cl.
rank() == 0)
172 std::cout <<
"n: " << n[i]
173 <<
" dx: " <<
grid.spacing(0)
177 init_surface<grid_type,SDF>(
grid,center,radius);
178 grid.template ghost_get<SDF>();
182 nb_keys_error.clear();
183 get_NB_indices<grid_type,SDF>(
grid,7*
grid.spacing(0),nb_keys);
184 get_NB_indices<grid_type,SDF>(
grid,2*
grid.spacing(0),nb_keys_error);
187 init_analytSol<grid_type,QTY,ANALYTLB>(
grid,center,radius);
197 estimateClosestPoint<SDF,CP,POLYORD>(
grid,4*
grid.spacing(0));
198 grid.template ghost_get<CP>();
203 init_qty<grid_type,QTY>(
grid,center,nb_keys);
204 grid.template ghost_get<QTY>();
206 extendLSField<SDF,CP,QTY,TMP_EXT_SCAL,3>(
grid,4*
grid.spacing(0));
207 grid.template ghost_get<QTY>();
214 auto it =
grid.getDomainIterator();
217 grid.template get<NUMLB>(key) = second_order_deriv2<grid_type,QTY>(
grid,key,0) + second_order_deriv2<grid_type,QTY>(
grid,key,1) + second_order_deriv2<grid_type,QTY>(
grid,key,2);
232 grid.template ghost_get<NUMLB>();
233 extendLSField<SDF,CP,NUMLB,TMP_EXT_SCAL,3>(
grid,4*
grid.spacing(0));
234 grid.template ghost_get<NUMLB>();
242 std::cout <<
"n: " << n[i] <<
" h: " <<
grid.spacing(0) << std::endl;
246 get_absolute_error<grid_type,NUMLB,ANALYTLB,ABSERR>(
grid,nb_keys_error);
247 abs_norm_nb = get_l_norms_NB<grid_type,ABSERR>(
grid,nb_keys_error);
248 write_lnorms_to_file(n[i],abs_norm_nb,
"norms_EucLap_mpiSize_" + std::to_string(mpiSize),output_dir);
252 interp_type interpSurf(particlesSurf,
grid);
253 set_prop2zero<vector_type,0>(particlesSurf);
254 interpSurf.template m2p<NUMLB,NUMLB_PART>(
grid,particlesSurf);
257 double maxError{0}, sumErrorSq{0};
258 auto pit{particlesSurf.getDomainIterator()};
259 while(pit.isNext()) {
262 particlesSurf.template getProp<ABSERR_PART>(key) = std::fabs(particlesSurf.template getProp<ANALYTLB_PART>(key) - particlesSurf.template getProp<NUMLB_PART>(key));
263 sumErrorSq += particlesSurf.template getProp<ABSERR_PART>(key)*particlesSurf.template getProp<ABSERR_PART>(key);
264 maxError = std::max(maxError,particlesSurf.template getProp<ABSERR_PART>(key));
268 v_cl.
sum(sumErrorSq);
271 abs_norm_nb.l2 = {std::sqrt(sumErrorSq / (
double)n_part[i])};
272 abs_norm_nb.linf = maxError;
273 write_lnorms_to_file(n_part[i],abs_norm_nb,
"normsParticles_EucLap_mpiSize_" + std::to_string(mpiSize),output_dir);
280 v_cl.
sum(tExtRHS_cpu);
285 v_cl.
sum(tExtRHS_wct);
288 v_cl.
sum(ttotal_cpu);
289 v_cl.
sum(ttotal_wct);
294 if (v_cl.
rank() == 0) {
295 timesCPU_file << n[i] <<
"," << std::setprecision(6) << std::scientific << tcp_cpu/v_cl.
size() <<
"," << tExtQ_cpu/v_cl.
size() <<
"," << tAll_cpu/v_cl.
size() <<
"," << tExtRHS_cpu/v_cl.
size() <<
"," << tLap_cpu/v_cl.
size() <<
"," << ttotal_cpu/v_cl.
size() << std::endl;
296 timesWCT_file << n[i] <<
"," << std::setprecision(6) << std::scientific << tcp_wct/v_cl.
size() <<
"," << tExtQ_wct/v_cl.
size() <<
"," << tAll_wct/v_cl.
size() <<
"," << tExtRHS_wct/v_cl.
size() <<
"," << tLap_wct/v_cl.
size() <<
"," << ttotal_wct/v_cl.
size() << std::endl;
Header file containing functions for creating files and folders.
static void create_directory_if_not_exist(std::string path, bool silent=0)
Creates a directory if not already existent.
This class represent an N-dimensional box.
void execute()
Execute all the requests.
size_t rank()
Get the process unit id.
size_t size()
Get the total number of processors.
void sum(T &num)
Sum the numbers across all processors and get the result.
void max(T &num)
Get the maximum number across all processors (or reduction with infinity norm)
Implementation of VCluster class.
This is a distributed grid.
Main class for interpolation Particle to mest p2m and Mesh to particle m2p.
Implementation of 1-D std::vector like structure.
Class for cpu time benchmarking.
void stop()
Stop the timer.
double getcputime()
Return the cpu time.
void reset()
Reset the timer.
void start()
Start the timer.
double getwct()
Return the elapsed real time.
Functions for level set reinitialization and extension on OpenFPM grids based on closest point method...
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...