Skip to content
Snippets Groups Projects
Select Git revision
  • eac3a2c54929c92e3bfcab6d28c2200581e821fa
  • master default protected
  • array_3d
  • gradients
  • poylgonise
  • apps
  • bench
  • streaming_modif
  • bug
  • multi_thread
  • refactoring_c_code
  • futhark_refac
  • one_dim_t_floats
  • reg
  • reg_order3
  • trying_base64
  • merging_j
  • trying_regularized
  • futharkalabos3d_troels_3d
  • futharkalabos3d_troels
  • futharkalabos3d_tuple
21 results

tensor_field.c

Blame
  • tensor_field.c 3.36 KiB
    #include "tensor_field.h"
    #include <math.h>
    #include <stdlib.h>
    #include <assert.h>
    
    bool tensor_field_consistant_spatial_size_tensor_field(tensor_field lhs, tensor_field rhs) {
        return (rhs.nx == lhs.nx && rhs.ny == lhs.ny && rhs.nz == lhs.nz);
    }
    
    bool tensor_field_consistant_size_tensor_field(tensor_field lhs, tensor_field rhs) {
        return (rhs.nx == lhs.nx && rhs.ny == lhs.ny && rhs.nz == lhs.nz && rhs.q == lhs.q);
    }
    
    bool tensor_field_consistant_size_scalar_field(tensor_field lhs, scalar_field rhs) {
        return (rhs.nx == lhs.nx && rhs.ny == lhs.ny && rhs.nz == lhs.nz);
    }
    
    tensor_field tensor_field_allocate(fint nx, fint ny, fint nz, fint q) {
        tensor_field field;
        field.nx = nx;
        field.ny = ny;
        field.nz = nz;
        field.q  = q;
        field.dim = 3;
        
        field.data = malloc(sizeof(T) * nx * ny * nz * q);
        field.grid = malloc(sizeof(T ***) * nx);
        for (fint ix = 0; ix < nx; ++ix) {
            field.grid[ix] = malloc(sizeof(T **) * ny);
            for (fint iy = 0; iy < ny; ++iy) {
                field.grid[ix][iy] = malloc(sizeof(T *) * nz);
                for (fint iz = 0; iz < nz; ++iz) {
                    field.grid[ix][iy][iz] = field.data + q * (iz + nz * (iy + ny * ix));
                }
            }
        }
        return field;
    }
    
    void tensor_field_deallocate(tensor_field field) {
        free(field.data);
    
        for (fint ix = 0; ix < field.nx; ++ix) {
            for (fint iy = 0; iy < field.ny; ++iy) {
                free(field.grid[ix][iy]);
            }
            free(field.grid[ix]);
        }
        free(field.grid);
    }
    
    void tensor_field_from_futhark_f32_4d_inplace(struct futhark_f32_4d *f, struct futhark_context *ctx, tensor_field field) {
        int64_t *shape = futhark_shape_f32_4d(ctx, f);
        fint nx = shape[0];
        fint ny = shape[1];
        fint nz = shape[2];
        fint q = shape[3];
    
        assert(nx == field.nx);
        assert(ny == field.ny);
        assert(nz == field.nz);
        assert(q == field.q);
    
        futhark_values_f32_4d(ctx, f, field.data);
    }
    
    void tensor_field_compute_norm_inplace(tensor_field field, scalar_field norm) {
        assert(norm.nx == field.nx);
        assert(norm.ny == field.ny);
        assert(norm.nz == field.nz);
    
        for (int ix = 0; ix < field.nx; ++ix) {
            for (int iy = 0; iy < field.ny; ++iy) {
                for (int iz = 0; iz < field.nz; ++iz) {
                    T n = 0.0;
                    for (int id = 0; id < field.q; ++id) {
                        n += field.grid[ix][iy][iz][id] * field.grid[ix][iy][iz][id];
                    }
                    norm.grid[ix][iy][iz] = sqrt(n);
                }
            }
        }
    }
    
    tensor_field tensor_field_from_futhark_f32_4d(struct futhark_f32_4d *f, struct futhark_context *ctx) {
        int64_t *shape = futhark_shape_f32_4d(ctx, f);
        fint nx = shape[0];
        fint ny = shape[1];
        fint nz = shape[2];
        fint q = shape[3];
    
        tensor_field field = tensor_field_allocate(nx, ny, nz, q);
    
        tensor_field_from_futhark_f32_4d_inplace(f, ctx, field);
    
        return field;
    }
    
    struct futhark_f32_4d *tensor_field_to_futhark_f32_4d(tensor_field field, struct futhark_context *ctx) {
        
        struct futhark_f32_4d *f = futhark_new_f32_4d(ctx,
                                              field.data, field.nx, field.ny, field.nz, field.q);
        return f;
    }
    
    scalar_field tensor_field_compute_norm(tensor_field field) {
        scalar_field norm = scalar_field_allocate(field.nx, field.ny, field.nz);
    
        tensor_field_compute_norm_inplace(field, norm);
    
        return norm;
    }