diff --git a/apps/kida/kida.c b/apps/kida/kida.c index da31ead55054e00bf4a6ba449908e87a5fce5844..d327e813e1c5141a8a1e78cbb1c58bb9e6ddda84 100644 --- a/apps/kida/kida.c +++ b/apps/kida/kida.c @@ -92,10 +92,20 @@ int main(int argc, char **argv) { if (prefix != NULL) { printf("output at iter %d\n", it); tensor_field_from_futhark_f32_4d_inplace(f, ctx, lattice); - tensor_field_from_futhark_f32_4d_inplace(d, ctx, distances); + // tensor_field_from_futhark_f32_4d_inplace(d, ctx, distances); lbm_compute_density_inplace(lattice, density); lbm_compute_velocity_inplace(lattice, velocity); + triangle_field tri = triangle_field_polygonise(density, ctx, 1.0); + + char *stl_fname = stl_create_fname(prefix, "iso_surface", it); + stl_file stl = stl_file_create(stl_fname); + stl_file_write_triangle_field(&stl, tri); + stl_file_close(&stl); + free(stl_fname); + triangle_field_deallocate(tri); + + char *fname = vtk_create_fname(prefix, "out", it); box domain = box_create(0, lattice.nx-1, 0, lattice.ny-1, 0, lattice.nz-1); @@ -105,6 +115,7 @@ int main(int argc, char **argv) { vtk_file_write_scalar_field(&vtk, density, domain, "density", base64); vtk_file_write_tensor_field(&vtk, velocity, domain, "velocity", base64); vtk_file_close(&vtk); + free(fname); } diff --git a/meson.build b/meson.build index b5cafe1dbfb4ad5652110ebee4a6a613f9807c78..c1ff24f71ccbff799eb4dad3ba1c3cf0d992e05a 100644 --- a/meson.build +++ b/meson.build @@ -1,6 +1,6 @@ project('palathark', 'c', version : '0.1', - default_options : ['warning_level=3', 'buildtype=debugoptimized', 'b_ndebug=if-release']) + default_options : ['warning_level=3', 'buildtype=debug', 'b_sanitize=address,undefined', 'b_ndebug=if-release']) lattice = get_option('lattice') precision = get_option('precision') @@ -18,6 +18,7 @@ else liblbm = 'liblbm_f64.fut' endif + math_lib = meson.get_compiler('c').find_library('m') math_dep = declare_dependency(dependencies: [math_lib]) diff --git a/src/c_interface/base64.c b/src/c_interface/base64.c index 1c639d16ad2be80956fbe47c70a3f94688445ab4..ef2fc157218cb638908e2a37449404ec83a68085 100644 --- a/src/c_interface/base64.c +++ b/src/c_interface/base64.c @@ -56,11 +56,11 @@ unsigned char * base64_encode(const unsigned char *src, size_t len, /* // Modification: These lines are commented so that paraview // can read the output. + */ // if (line_len >= 72) { // *pos++ = '\n'; // line_len = 0; // } - */ } if (end - in) { @@ -79,10 +79,10 @@ unsigned char * base64_encode(const unsigned char *src, size_t len, /* // Modification: These lines are commented so that paraview - // can read the output. + // can read the output. */ // if (line_len) - // *pos++ = '\n'; - */ + // *pos++ = '\n'; + *pos = '\0'; if (out_len) diff --git a/src/c_interface/globals.h b/src/c_interface/globals.h index 59189189b57d81ad3e786a5db3d9f890db1336f0..0a93e905c172f61f68627078d4005f02a4f52cc4 100644 --- a/src/c_interface/globals.h +++ b/src/c_interface/globals.h @@ -14,21 +14,49 @@ typedef double T; static const T tol = DBL_EPSILON; static const T min_val = DBL_MIN; + +typedef struct futhark_f64_2d futhark_2d; +typedef struct futhark_f64_3d futhark_3d; typedef struct futhark_f64_4d futhark_4d; + #define futhark_shape_4d(a, b) futhark_shape_f64_4d(a, b) #define futhark_free_4d(a, b) futhark_free_f64_4d(a, b) #define futhark_values_4d(a, b, c) futhark_values_f64_4d(a, b, c) #define futhark_new_4d(a, b, c, d, e, f) futhark_new_f64_4d(a, b, c, d, e, f) + +#define futhark_shape_3d(a, b) futhark_shape_f64_3d(a, b) +#define futhark_free_3d(a, b) futhark_free_f64_3d(a, b) +#define futhark_values_3d(a, b, c) futhark_values_f64_3d(a, b, c) +#define futhark_new_3d(a, b, c, d, e) futhark_new_f64_3d(a, b, c, d, e) + +#define futhark_shape_2d(a, b) futhark_shape_f64_2d(a, b) +#define futhark_free_2d(a, b) futhark_free_f64_2d(a, b) +#define futhark_values_2d(a, b, c) futhark_values_f64_2d(a, b, c) +#define futhark_new_2d(a, b, c, d) futhark_new_f64_2d(a, b, c, d) #else typedef float T; static const T tol = FLT_EPSILON; static const T min_val = FLT_MIN; + +typedef struct futhark_f32_2d futhark_2d; +typedef struct futhark_f32_3d futhark_3d; typedef struct futhark_f32_4d futhark_4d; + #define futhark_shape_4d(a, b) futhark_shape_f32_4d(a, b) #define futhark_free_4d(a, b) futhark_free_f32_4d(a, b) #define futhark_values_4d(a, b, c) futhark_values_f32_4d(a, b, c) #define futhark_new_4d(a, b, c, d, e, f) futhark_new_f32_4d(a, b, c, d, e, f) + +#define futhark_shape_3d(a, b) futhark_shape_f32_3d(a, b) +#define futhark_free_3d(a, b) futhark_free_f32_3d(a, b) +#define futhark_values_3d(a, b, c) futhark_values_f32_3d(a, b, c) +#define futhark_new_3d(a, b, c, d, e) futhark_new_f32_3d(a, b, c, d, e) + +#define futhark_shape_2d(a, b) futhark_shape_f32_2d(a, b) +#define futhark_free_2d(a, b) futhark_free_f32_2d(a, b) +#define futhark_values_2d(a, b, c) futhark_values_f32_2d(a, b, c) +#define futhark_new_2d(a, b, c, d) futhark_new_f32_2d(a, b, c, d) #endif static const T pi = M_PI; diff --git a/src/c_interface/includes.h b/src/c_interface/includes.h index 48f471aa26d3dd60b6883749c9cc29c3352f3b9d..c22a711024c1b0203b723ea3088722acbcf8f318 100644 --- a/src/c_interface/includes.h +++ b/src/c_interface/includes.h @@ -10,10 +10,12 @@ #include "point.h" #include "box.h" #include "vtk.h" +#include "stl.h" #include "units.h" #include "utils.h" #include "point.h" #include "triangle.h" +#include "triangle_field.h" #include "base64.h" #endif \ No newline at end of file diff --git a/src/c_interface/lbm_utils.c b/src/c_interface/lbm_utils.c index a3194bc8de4f570486b185d39897a611b79fee30..6c6f7030d8d02fec1c685e1db03cb10ddbb5d397 100644 --- a/src/c_interface/lbm_utils.c +++ b/src/c_interface/lbm_utils.c @@ -17,7 +17,7 @@ tensor_field create_distances(fint nx, fint ny, fint nz, fint q, triangle *t, fi for (fint iq = 0; iq < q; ++iq) { T distance = (T)1; point loc_point = point_create(ix, iy, iz); - point next_vec = point_create_from_array_int(c_t[iq]); + point next_vec = point_from_array_int(c_t[iq]); // printf("iq = %d, ",iq); // point_print(next_vec); // printf("\n"); diff --git a/src/c_interface/meson.build b/src/c_interface/meson.build index 8dbc4cbfa8855cb36f080d63c5c6679156e2e1ab..266a697e7cd0dddf36a6c795a910820191ae401d 100644 --- a/src/c_interface/meson.build +++ b/src/c_interface/meson.build @@ -6,10 +6,12 @@ c_interface_sources = [ 'units.c', 'tensor_field_2d.c', 'tensor_field.c', + 'triangle_field.c', 'box.c', 'triangle.c', 'point.c', 'vtk.c', + 'stl.c', 'scalar_field_2d.c'] c_interface = static_library('c_interface', diff --git a/src/c_interface/point.c b/src/c_interface/point.c index b7ef7e587a9c8b9633b459fb63d2b7a746aaece4..8cbb9161168ab3d6bd5f61b677a34305bba65b2f 100644 --- a/src/c_interface/point.c +++ b/src/c_interface/point.c @@ -16,7 +16,7 @@ point point_create_default() { return point_create((T)0, (T)0, (T)0); } -point point_create_from_array_int(const fint array[3]) { +point point_from_array_int(const fint array[3]) { point p; p.x = (T)array[0]; p.y = (T)array[1]; @@ -25,7 +25,7 @@ point point_create_from_array_int(const fint array[3]) { return p; } -point point_create_from_array(const T array[3]) { +point point_from_array(const T array[3]) { point p; p.x = array[0]; p.y = array[1]; diff --git a/src/c_interface/point.h b/src/c_interface/point.h index c8e994640a7174d6b052abc187b56e41765d1d35..bcd5b3a590ca04f11a97ab4bf741337a7c381e7f 100644 --- a/src/c_interface/point.h +++ b/src/c_interface/point.h @@ -10,8 +10,8 @@ typedef struct { point point_create(T x, T y, T z); point point_create_default(); -point point_create_from_array_int(const fint array[3]); -point point_create_from_array(const T array[3]); +point point_from_array_int(const fint array[3]); +point point_from_array(const T array[3]); bool point_is_approx_equal(point lhs, point rhs, T tol); point point_neg(point rhs); diff --git a/src/c_interface/scalar_field.c b/src/c_interface/scalar_field.c index 656a13537ee5a0b32ef2e1f8795c5471230b154c..2517ba2f6943a5ad673a1e03476368aa7ed2948e 100644 --- a/src/c_interface/scalar_field.c +++ b/src/c_interface/scalar_field.c @@ -146,6 +146,41 @@ void scalar_field_write_file(scalar_field field, char *dir, char *prefix, int i) fclose(fp); } +void scalar_field_from_futhark_f32_3d_inplace(futhark_3d *f, struct futhark_context *ctx, scalar_field field) { +#ifndef NDEBUG + const int64_t *shape = futhark_shape_3d(ctx, f); + fint nx = shape[0]; + fint ny = shape[1]; + fint nz = shape[2]; +#endif + + assert(nx == field.nx); + assert(ny == field.ny); + assert(nz == field.nz); + + futhark_values_3d(ctx, f, field.data); +} + +scalar_field scalar_field_from_futhark_f32_3d(futhark_3d *f, struct futhark_context *ctx) { + const int64_t *shape = futhark_shape_3d(ctx, f); + fint nx = shape[0]; + fint ny = shape[1]; + fint nz = shape[2]; + + scalar_field field = scalar_field_allocate(nx, ny, nz); + + scalar_field_from_futhark_f32_3d_inplace(f, ctx, field); + + return field; +} + +futhark_3d *scalar_field_to_futhark_f32_3d(scalar_field field, struct futhark_context *ctx) { + + futhark_3d *f = futhark_new_3d(ctx, field.data, field.nx, field.ny, field.nz); + assert(f != NULL); + return f; +} + // TODO: add possibility to have rho/u form futhark directly // void scalar_field_from_futhark_f32_3d_inplace(struct futhark_f32_3d *f, struct futhark_context *ctx, scalar_field field) { // assert(f != NULL); diff --git a/src/c_interface/scalar_field.h b/src/c_interface/scalar_field.h index 29fe91155644dec12b29234e0168ec971c69206a..76375b2064c093ea25664fd03bcd932359cfa55e 100644 --- a/src/c_interface/scalar_field.h +++ b/src/c_interface/scalar_field.h @@ -37,6 +37,10 @@ scalar_field_2d scalar_field_extract_2d_y(scalar_field field, int iy); scalar_field_2d scalar_field_extract_2d_z(scalar_field field, int iz); +void scalar_field_from_futhark_f32_3d_inplace(futhark_3d *rho, struct futhark_context *ctx, scalar_field field); +scalar_field scalar_field_from_futhark_f32_3d(futhark_3d *rho, struct futhark_context *ctx); +futhark_3d *scalar_field_to_futhark_f32_3d(scalar_field field, struct futhark_context *ctx); + // TODO: add possibility to have rho/u form futhark directly // void scalar_field_from_futhark_f32_3d_inplace(struct futhark_f32_3d *f, struct futhark_context *ctx, scalar_field field); diff --git a/src/c_interface/triangle.c b/src/c_interface/triangle.c index 8ce853fbbcecc52c73f4e099b645e65d44999aa0..5ef570c1c2ddf3ac786f175560744801c7e1bf8c 100644 --- a/src/c_interface/triangle.c +++ b/src/c_interface/triangle.c @@ -133,6 +133,14 @@ void triangle_print(triangle t) { point_print(t.p2); } +triangle triangle_from_array(const T data[9]) { + point p0 = point_from_array(data); + point p1 = point_from_array(&data[3]); + point p2 = point_from_array(&data[6]); + + return triangle_create(p0, p1, p2); +} + static char *stl_create_fname(char const * const prefix, char *name) { char *buffer = malloc(80 * sizeof(char)); sprintf(buffer, "%s%s.stl", prefix, name); diff --git a/src/c_interface/triangle.h b/src/c_interface/triangle.h index 063984c4d2b6e7cbbc1950a4c9c5398081632228..29b1727164941a03e2c8264b77ded021fb06eec2 100644 --- a/src/c_interface/triangle.h +++ b/src/c_interface/triangle.h @@ -10,6 +10,7 @@ typedef struct { } triangle; triangle triangle_create(point p0, point p1, point p2); +triangle triangle_from_array(const T data[9]); bool triangle_is_approx_equal(triangle lhs, triangle rhs, T eps); diff --git a/src/dynamics.fut b/src/dynamics.fut index 05b1fe383e06a043ad287d88e35893f4363ea580..c1c1854098320ca8a0be52adcc9897c0f0d8a562 100644 --- a/src/dynamics.fut +++ b/src/dynamics.fut @@ -48,6 +48,9 @@ module mk_bgk (real: real) (d: descriptor with real = real.t) : (dynamics with r let u = d.map_d( (real.f64 1) / rho * ) j let feq = compute_feq rho u in d.map2_q(\fi feqi -> fi * ( (real.f64 1) - omega) + feqi * omega) f feq + -- mad function used here. Not sure it adds any efficiency + -- in d.map2_q(\fi feqi -> real.mad (fi) ( (real.f64 1) - omega) (feqi * omega)) f feq + let compute_velocity (f: d.vec_q real) = let j = compute_j f @@ -164,6 +167,9 @@ module mk_reg (real: real) let feq = compute_feq rho u let fneq = compute_fneq f feq let fneq = regularize fneq u + in d.map2_q(\feqi fneqi -> fneqi * ( (real.f64 1) - omega) + feqi) feq fneq + -- mad function used here. Not sure it adds any efficiency + -- in d.map2_q(\feqi fneqi -> real.mad (fneqi) ( (real.f64 1) - omega) (feqi)) feq fneq } diff --git a/src/futhark.pkg b/src/futhark.pkg index c05fea53ef883b0070e53c8c6dd7e30dc0c9bf8c..4b152a13d60a62d51bbdca7f44ae638c8f7fa91b 100644 --- a/src/futhark.pkg +++ b/src/futhark.pkg @@ -1,3 +1,4 @@ require { github.com/athas/vector 0.7.0 #f5aaa219a02949d1eb2978f81419cf5614abfa3d + github.com/omalaspinas/futcubes 0.0.0-20210219193616+d16367e9f96dbd7938d7916483386a8aa0516723 #d16367e9f96dbd7938d7916483386a8aa0516723 } diff --git a/src/liblbm_f32.fut b/src/liblbm_f32.fut index 0e7309bb533c72456a2677a2ccb15a9fe8785cce..09762b4df7dc4fc89ec87c9ccc4ea1699e7a0742 100644 --- a/src/liblbm_f32.fut +++ b/src/liblbm_f32.fut @@ -1,6 +1,7 @@ -- Program for Lattice-Boltzmann in Futhark import "globals_f32" import "sim" +import "polygonise" module sim_d3q27_reg_bfl_f32 = mk_sim d3q27_reg_bfl_f32 @@ -10,6 +11,8 @@ module sim_d3q19_reg_bfl_f32 = mk_sim d3q19_reg_bfl_f32 entry main_d3q19_reg = sim_d3q19_reg_bfl_f32.run +entry main_polygonise = polygonise_f32 + -- Test the sub1 function. -- == -- input { 21i64 21i64 21i64 27i64 3i64 1.5f32 1000i64 } diff --git a/src/liblbm_f64.fut b/src/liblbm_f64.fut index 7f8f6c46ea49086e446f9463cf297633463277ee..20d8830fc1c2e13d48abce20233d7eb077889489 100644 --- a/src/liblbm_f64.fut +++ b/src/liblbm_f64.fut @@ -1,6 +1,7 @@ -- Program for Lattice-Boltzmann in Futhark import "globals_f64" import "sim" +import "polygonise" module sim_d3q27_reg_bfl_f64 = mk_sim d3q27_reg_bfl_f64 @@ -10,6 +11,8 @@ module sim_d3q19_reg_bfl_f64 = mk_sim d3q19_reg_bfl_f64 entry main_d3q19_reg_f64 = sim_d3q19_reg_bfl_f64.run +entry main_polygonise = polygonise_f64 + -- -- executes Lattice-Boltzmann it times and -- let lattice_boltzmann [nx][ny][nz] (fin: [nx][ny][nz](lbm_model.vec_q real)) (vel: [nx][ny][nz](lbm_model.vec_d real)) (dists: [nx][ny][nz](lbm_model.vec_q real)) (omega: real) (max_t: i64): [nx][ny][nz](lbm_model.vec_q real) = diff --git a/src/meson.build b/src/meson.build index ee65f6f30f4273e82521640ef41a89e6f3b9f225..dbef9df9df115eb9ca7a036def38170247cfd8dc 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,15 +1,38 @@ +fut_sources = [ + 'bc.fut', + 'vectors.fut', + 'utilities.fut', + 'sym_tens.fut', + 'sim.fut', + 'liblbm_f64.fut', + 'liblbm_f32.fut', + 'lbm.fut', + 'lattice.fut', + 'globals.fut', + 'globals_f64.fut', + 'globals_f32.fut', + 'descriptor.fut', + 'data_analysis.fut', + 'dynamics.fut', + 'polygonise.fut'] + +fut_dep = declare_dependency( + sources : fut_sources +) + futhark_generated = custom_target( 'futhark', - input: join_paths(meson.source_root(),'src',liblbm), + input: [join_paths(meson.source_root(), 'src', liblbm), fut_sources], output: ['liblbm.c', 'liblbm.h'], - command: [futhark, futhark_backend, '@INPUT@', '--library', '-o', 'src/liblbm'], + command: [futhark, futhark_backend, '@INPUT0@', '--library', '-o', 'src/liblbm'], install: true, - install_dir: 'src' + install_dir: 'src', ) liblbm_static = static_library('liblbm_static', [futhark_generated], c_args : ['-Wall', '-Wextra', '-pedantic', build_args], + include_directories: './', ) liblbm_dep = declare_dependency( @@ -17,6 +40,8 @@ liblbm_dep = declare_dependency( link_with : [liblbm_static], ) + + # gen = generator(futhark, # output: ['@BASENAME@.c', '@BASENAME@.h'], # arguments : [futhark_backend, '@INPUT@', '--library', '-o', 'src/liblbm'])