42#include "CSVReader/CSVReader.hpp"
49#include "RemoveLines.hpp"
51#include "FiniteDifference/FD_simple.hpp"
53#include "DiffusionSpace_sparseGrid.hpp"
54#include "HelpFunctions_diffusion.hpp"
56#include "Decomposition/Distribution/BoxDistribution.hpp"
61const size_t PHI_FULL = 0;
69const size_t PHI_PHASE = 0;
71const size_t U_NPLUS1 = 2;
72const size_t K_SINK = 3;
83constexpr size_t x = 0, y = 1, z = 2;
86const std::string path_to_redistancing_result =
87 "/MY_PATH/porous_ceramics/sussman_with_cuda/build/output_sussman_sparse_grid_porousCeramics_1216x1016x941/";
90const std::string redistancing_filename =
"sparseGrid_initial.hdf5";
92const std::string path_to_size = path_to_redistancing_result;
94const std::string output_name =
"output_heat_conduction_porous_ceramics_1216x1016x941_sparse_grid";
97int main(
int argc,
char* argv[])
100 openfpm_init(&argc, &argv);
101 auto & v_cl = create_vcluster();
104 timer t_iterative_diffusion_total;
105 timer t_iteration_wct;
114 const std::string path_output = cwd +
"/" + output_name +
"/";
117 if(v_cl.rank()==0) std::cout <<
"Redistancing result will be loaded from " << path_to_redistancing_result << redistancing_filename << std::endl;
119 if(v_cl.rank()==0) std::cout <<
"Outputs will be saved to " << path_output << std::endl;
131 read_csv_to_vector(path_to_size +
"/N.csv", v_sz, m, n);
132 read_csv_to_vector(path_to_size +
"/L.csv", v_L, m, n);
134 const float Lx_low = 0.0;
135 const float Lx_up = v_L.get(x);
136 const float Ly_low = 0.0;
137 const float Ly_up = v_L.get(y);
138 const float Lz_low = 0.0;
139 const float Lz_up = v_L.get(z);
142 size_t sz[dims] = {v_sz.get(x), v_sz.get(y), v_sz.get(z)};
149 grid_in_type g_dist(sz, box, ghost);
151 std::cout <<
"Rank " << v_cl.rank() <<
" starts loading redistancing result..." << std::endl;
152 g_dist.load(path_to_redistancing_result +
"/" + redistancing_filename);
153 std::cout <<
"Rank " << v_cl.rank() <<
" finished loading redistancing result." << std::endl;
160 std::cout <<
"Rank " << v_cl.rank() <<
" starts creating sparse grid." << std::endl;
163 typedef sgrid_dist_id_gpu<dims, float, props_sparse, CudaMemory, Dec> sparse_grid_type;
164 sparse_grid_type g_sparse(sz, box, ghost);
165 g_sparse.setPropNames(prop_names_sparse);
168 const float d_low = 0.0, d_up = Lx_up;
169 get_diffusion_domain_sparse_grid<PHI_FULL, PHI_PHASE>(g_dist, g_sparse, d_low, d_up);
174 std::cout <<
"Rank " << v_cl.rank() <<
" finished creating sparse grid." << std::endl;
179 const float u0 = 1.0;
181 const float sink_rate = 0.1;
182 std::cout <<
"Diffusion coefficient in s/(mm^2): " <<
D << std::endl;
183 std::cout <<
"Sink rate in 1/s: " << sink_rate << std::endl;
186 const float center[dims] = {(Lx_up+Lx_low)/(
float)2,
187 (Ly_up+Ly_low)/(
float)2,
188 (Lz_up+Lz_low)/(
float)2};
189 const float R = Lz_up / 4.0;
191 auto dom = g_sparse.getDomainIterator();
194 auto key = dom.get();
199 if(((coords.
get(x) - center[x]) * (coords.
get(x) - center[x])
200 + (coords.
get(y) - center[y]) * (coords.
get(y) - center[y])
201 + (coords.
get(z) - center[z]) * (coords.
get(z) - center[z])) <= R * R)
203 g_sparse.template insertFlush<U_N>(key) = u0;
205 else g_sparse.template insertFlush<U_N>(key) = 0.0;
218 typedef typename GetCpBlockType<
decltype(g_sparse),0,1>::type CpBlockType;
220 const float dx = g_sparse.spacing(x), dy = g_sparse.spacing(y), dz = g_sparse.spacing(z);
222 const float dt = diffusion_time_step(g_sparse,
D);
223 std::cout <<
"dx, dy, dz = " << g_sparse.spacing(x) <<
"," << g_sparse.spacing(y) <<
"," << g_sparse.spacing(z) << std::endl;
224 std::cout <<
"dt = 1/(4D) * 1/(1/dx^2 + 1/dy^2 + 1/dz^2) = " << dt << std::endl;
226 auto func_heatDiffusion_withSink = [dx, dy, dz, dt, d_low,
D, sink_rate] __device__ (
241 float u_c = u(i, j, k);
242 float u_px = u(i+1, j, k);
243 float u_mx = u(i-1, j, k);
244 float u_py = u(i, j+1, k);
245 float u_my = u(i, j-1, k);
246 float u_pz = u(i, j, k+1);
247 float u_mz = u(i, j, k-1);
250 float phi_c = phi(i, j, k);
251 float phi_px = phi(i+1, j, k);
252 float phi_mx = phi(i-1, j, k);
253 float phi_py = phi(i, j+1, k);
254 float phi_my = phi(i, j-1, k);
255 float phi_pz = phi(i, j, k+1);
256 float phi_mz = phi(i, j, k-1);
262 if (phi_px <= d_low + std::numeric_limits<float>::epsilon()) {u_px = u_c; k_sink = sink_rate;}
263 if (phi_mx <= d_low + std::numeric_limits<float>::epsilon()) {u_mx = u_c; k_sink = sink_rate;}
264 if (phi_py <= d_low + std::numeric_limits<float>::epsilon()) {u_py = u_c; k_sink = sink_rate;}
265 if (phi_my <= d_low + std::numeric_limits<float>::epsilon()) {u_my = u_c; k_sink = sink_rate;}
266 if (phi_pz <= d_low + std::numeric_limits<float>::epsilon()) {u_pz = u_c; k_sink = sink_rate;}
267 if (phi_mz <= d_low + std::numeric_limits<float>::epsilon()) {u_mz = u_c; k_sink = sink_rate;}
269 block.template get<K_SINK>()[offset] = k_sink;
272 u_out = u_c + dt * (
D * ((u_px + u_mx - 2 * u_c)/(dx * dx)
273 + (u_py + u_my - 2 * u_c)/(dy * dy)
274 + (u_pz + u_mz - 2 * u_c)/(dz * dz))
287 std::string path_time_filewct = path_output +
"/time_wct_incl_ghostCommunication" + std::to_string(v_cl.rank()) +
".txt";
288 std::ofstream out_wct_file(path_time_filewct, std::ios_base::app);
291 std::string path_time_filegpu = path_output +
"/time_GPU" + std::to_string(v_cl.rank()) +
".txt";
292 std::ofstream out_GPUtime_file(path_time_filegpu, std::ios_base::app);
297 const size_t iterations = 103;
298 const size_t number_write_outs = 10;
299 const size_t interval_write = iterations / number_write_outs;
304 g_sparse.template hostToDevice<U_N, U_NPLUS1, K_SINK, PHI_PHASE>();
305 g_sparse.template ghost_get<PHI_PHASE, K_SINK>(RUN_ON_DEVICE | SKIP_LABELLING);
306 t_iterative_diffusion_total.
start();
307 while(iter <= iterations)
311 t_iteration_wct.
start();
312 g_sparse.template ghost_get<U_N>(RUN_ON_DEVICE | SKIP_LABELLING);
314 g_sparse.template conv2_b<
320 {(
long int) sz[x]-1, (
long int) sz[y]-1, (
long int) sz[z]-1},
321 func_heatDiffusion_withSink);
323 t_iteration_wct.
stop();
326 out_wct_file << t_iteration_wct.
getwct() <<
",";
327 out_GPUtime_file << t_GPU.getwctGPU() <<
",";
329 t_iteration_wct.
reset();
333 t_iteration_wct.
start();
334 g_sparse.template ghost_get<U_NPLUS1>(RUN_ON_DEVICE | SKIP_LABELLING);
336 g_sparse.template conv2_b<
342 {(
long int) sz[x]-1, (
long int) sz[y]-1, (
long int) sz[z]-1},
343 func_heatDiffusion_withSink);
345 t_iteration_wct.
stop();
348 out_wct_file << t_iteration_wct.
getwct() <<
",";
349 out_GPUtime_file << t_GPU.getwctGPU() <<
",";
351 t_iteration_wct.
reset();
355 if (iter % interval_write == 0)
358 g_sparse.template deviceToHost<U_N, U_NPLUS1, K_SINK, PHI_PHASE>();
361 g_sparse.write_frame(path_output +
"g_sparse_diffuse", iter, FORMAT_BINARY);
365 monitor_total_concentration<U_N>(g_sparse, t, iter, path_output,
"total_conc.csv");
369 monitor_total_concentration<U_NPLUS1>(g_sparse, t, iter, path_output,
"total_conc.csv");
376 t_iterative_diffusion_total.
stop();
377 std::cout <<
"Rank " << v_cl.rank() <<
" total time for iterative diffusion incl. write outs: " << t_iterative_diffusion_total.
getwct() << std::endl;
378 std::cout <<
"Rank " << v_cl.rank() <<
" finished diffusion." << std::endl;
385 std::cout <<
"Rank " << v_cl.rank() <<
" total time for the whole programm : " << t_total.
getwct() << std::endl;
Header file containing help-functions that perform on OpenFPM-grids.
Header file containing functions for loading pixel values from 2D image or 3D image stack (volume) st...
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.
static std::string get_cwd()
Gets the current working directory and returns path as string.
Class for reinitializing a level-set function into a signed distance function using Sussman redistanc...
This class represent an N-dimensional box.
This class decompose a space into sub-sub-domains and distribute them across processors.
Derivative second order on h (spacing)
This class implement the point shape in an N-dimensional space.
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
This is a distributed grid.
Implementation of 1-D std::vector like structure.
Class for cpu time benchmarking.
void stop()
Stop the timer.
void reset()
Reset the timer.
void start()
Start the timer.
double getwct()
Return the elapsed real time.
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
get the type of the block
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...