Ejemplo n.º 1
0
void amr_grid_add_local_patch(amr_grid_t* grid, int i, int j, int k)
{
  ASSERT(!grid->finalized);
  DECLARE_3D_ARRAY(patch_type_t, patch_types, grid->patch_types, grid->nx, grid->ny, grid->nz);
  patch_type_t patch_type = patch_types[i][j][k];
  ASSERT(patch_type == NO_PATCH);
  patch_types[i][j][k] = LOCAL_SAME_LEVEL;
  ++(grid->num_local_patches);
}
Ejemplo n.º 2
0
void amr_grid_add_remote_patch(amr_grid_t* grid, int i, int j, int k, int remote_owner)
{
  ASSERT(!grid->finalized);
  DECLARE_3D_ARRAY(patch_type_t, patch_types, grid->patch_types, grid->nx, grid->ny, grid->nz);
  patch_type_t patch_type = patch_types[i][j][k];
  ASSERT(patch_type == NO_PATCH);
  patch_types[i][j][k] = REMOTE_SAME_LEVEL;
  DECLARE_3D_ARRAY(int, remote_owners, grid->remote_owners, grid->nx, grid->ny, grid->nz);
  remote_owners[i][j][k] = remote_owner;
}
Ejemplo n.º 3
0
static void compute_integral(gmls_functional_t* functional,
                             real_t t,
                             multicomp_poly_basis_t* poly_basis,
                             real_t* solution, 
                             point_t* quad_points,
                             real_t* quad_weights,
                             vector_t* quad_normals,
                             int num_quad_points,
                             real_t* lambdas)
{
  START_FUNCTION_TIMER();
  bool on_boundary = (quad_normals != NULL);

  // Loop through the points and compute the lambda matrix of functional 
  // approximants.
  int num_comp = functional->num_comp;
  int basis_dim = multicomp_poly_basis_dim(poly_basis);
  memset(lambdas, 0, sizeof(real_t) * num_comp * basis_dim * num_comp);
  DECLARE_3D_ARRAY(real_t, lam, lambdas, num_comp, basis_dim, num_comp);
  for (int q = 0; q < num_quad_points; ++q)
  {
    point_t* xq = &quad_points[q];
    real_t wq = quad_weights[q];
    vector_t* nq = (on_boundary) ? &quad_normals[q] : NULL;

    // Now compute the (multi-component) integrands for the functional at 
    // this point.
    real_t integrands[num_comp*basis_dim*num_comp];
    functional->vtable.eval_integrands(functional->context, t, poly_basis, 
                                       xq, nq, solution, integrands);

    // Integrate.
    DECLARE_3D_ARRAY(real_t, I, integrands, num_comp, num_comp, basis_dim);
    for (int i = 0; i < num_comp; ++i)
      for (int j = 0; j < basis_dim; ++j)
        for (int k = 0; k < num_comp; ++k)
          lam[i][j][k] += wq * I[i][k][j];
  }
  STOP_FUNCTION_TIMER();
}
Ejemplo n.º 4
0
void amr_grid_finalize(amr_grid_t* grid)
{
  ASSERT(!grid->finalized);

  // Make sure that we have accounted for all patches in our construction 
  // process.
  DECLARE_3D_ARRAY(patch_type_t, patch_types, grid->patch_types, grid->nx, grid->ny, grid->nz);
  if (grid->num_local_patches < (grid->nx * grid->ny * grid->nz))
  {
    for (int i = 0; i < grid->nx; ++i)
    {
      for (int j = 0; j < grid->ny; ++j)
      {
        for (int k = 0; k < grid->nz; ++k)
        {
          if (patch_types[i][j][k] == NO_PATCH)
            polymec_error("amr_grid_finalize: no local or remote patch at (%d, %d, %d).", i, j, k);
        }
      }
    }
  }

  // Make an array of indices for locally-present patches.
  grid->local_patch_indices = polymec_malloc(sizeof(int) * 3 * grid->num_local_patches);
  int l = 0;
  for (int i = 0; i < grid->nx; ++i)
  {
    for (int j = 0; j < grid->ny; ++j)
    {
      for (int k = 0; k < grid->nz; ++k, ++l)
      {
        grid->local_patch_indices[3*l]   = i;
        grid->local_patch_indices[3*l+1] = j;
        grid->local_patch_indices[3*l+2] = k;
      }
    }
  }

  // Establish our remote copying pattern.
  grid->cell_ex = grid_cell_exchanger_new(grid);
  grid->x_face_ex = grid_x_face_exchanger_new(grid);
  grid->y_face_ex = grid_y_face_exchanger_new(grid);
  grid->z_face_ex = grid_z_face_exchanger_new(grid);
  grid->x_edge_ex = grid_x_edge_exchanger_new(grid);
  grid->y_edge_ex = grid_y_edge_exchanger_new(grid);
  grid->z_edge_ex = grid_z_edge_exchanger_new(grid);
  grid->node_ex = grid_node_exchanger_new(grid);
  grid->finalized = true;
}
Ejemplo n.º 5
0
static void elastic_eval_integrands(void* context, real_t t, 
                                    multicomp_poly_basis_t* basis, 
                                    point_t* x, vector_t* n, real_t* solution,
                                    real_t* integrands)
{
  elastic_t* elastic = context;
  int dim = multicomp_poly_basis_dim(basis);

  // Evaluate the polynomial derivatives. All the components use the 
  // same basis, so we don't have to distinguish between them
  real_t dpdx[dim], dpdy[dim], dpdz[dim];
  multicomp_poly_basis_compute(basis, 0, 1, 0, 0, x, dpdx);
  multicomp_poly_basis_compute(basis, 0, 0, 1, 0, x, dpdy);
  multicomp_poly_basis_compute(basis, 0, 0, 0, 1, x, dpdz);

  // Evaluate the D and N matrices.
  real_t D[6*6], N[3*6];
  eval_stress_strain_matrix(elastic->E, elastic->nu, D);
  eval_normal_vector_matrix(n, N);

  memset(integrands, 0, sizeof(int) * dim);
  DECLARE_3D_ARRAY(real_t, I, integrands, 3, 3, dim);
  for (int k = 0; k < dim; ++k)
  {
    // Evaluate the P matrix for the kth vector.
    real_t P[6*3];
    eval_basis_matrix(dpdx[k], dpdy[k], dpdz[k], P);

    // Compute N * D * P (a 3x3 matrix) for the kth vector.
    real_t DP[6*3];
    real_t alpha = 1.0, beta = 0.0;
    char no_trans = 'N';
    int six = 6, three = 3;
    rgemm(&no_trans, &no_trans, &six, &three, &six, &alpha, D, &six, P, &six, 
          &beta, DP, &six);
    real_t NDP[6*3];
    rgemm(&no_trans, &no_trans, &three, &three, &six, &alpha, N, &three, DP, &six,
          &beta, NDP, &three);
    I[0][0][k] = NDP[0]; I[0][1][k] = NDP[3]; I[0][2][k] = NDP[6];
    I[1][0][k] = NDP[1]; I[1][1][k] = NDP[4]; I[1][2][k] = NDP[7];
    I[2][0][k] = NDP[2]; I[2][1][k] = NDP[5]; I[2][2][k] = NDP[8];
  }
}
Ejemplo n.º 6
0
void test_real_array3(void** state) 
{ 
  void* storage = polymec_malloc(sizeof(real_t)*10*10*10);
  DECLARE_3D_ARRAY(real_t, a, storage, 10, 10, 10);
  for (int i = 0; i < 10; ++i)
    for (int j = 0; j < 10; ++j)
      for (int k = 0; k < 10; ++k)
        a[i][j][k] = 100*i + 10*j + k;
  for (int i = 0; i < 10; ++i)
  {
    for (int j = 0; j < 10; ++j)
    {  
      for (int k = 0; k < 10; ++k)
      {  
        assert_real_equal(100*i + 10*j + k, a[i][j][k]);
      }
    }
  }
  polymec_free(storage);
} 
Ejemplo n.º 7
0
// Returns the number of values that patch (i, j, k) transmits to patch (i1, j1, k1).
// The patch mask identifies those kinds of patches included in the total.
static int num_transmitted_patch_values(amr_grid_t* grid, 
                                        amr_grid_data_centering_t centering, int patch_mask, 
                                        int i, int j, int k, int i1, int j1, int k1)
{
  // Make sure the patches abut one another in index space.
  if ((ABS(i - i1) + ABS(j - j1) + ABS(k - k1)) > 1)
    return 0;

  // Figure out how many values are on a side.
  int x_padding, y_padding, z_padding;
  switch(centering)
  {
    case AMR_GRID_CELL: 
      x_padding = y_padding = z_padding = 0; break;
    case AMR_GRID_X_FACE: 
      x_padding = 1; y_padding = z_padding = 0; break;
    case AMR_GRID_Y_FACE: 
      y_padding = 1; x_padding = z_padding = 0; break;
    case AMR_GRID_Z_FACE: 
      z_padding = 1; x_padding = y_padding = 0; break;
    case AMR_GRID_X_EDGE: 
      x_padding = 0; y_padding = z_padding = 1; break;
    case AMR_GRID_Y_EDGE: 
      y_padding = 0; x_padding = z_padding = 1; break;
    case AMR_GRID_Z_EDGE: 
      z_padding = 0; x_padding = y_padding = 1; break;
    case AMR_GRID_NODE: 
      x_padding = y_padding = z_padding = 1;
  }
  int px, py, pz;
  amr_grid_get_patch_size(grid, &px, &py, &pz);
  int x_size = px + x_padding, y_size = py + y_padding, z_size = pz + z_padding;

  // Handle neighbor grid cases, if any.
  amr_grid_t* grid1 = grid;
  int cross_section_size = 0;
  if (i1 == -1)
  {
    grid1 = (grid->neighbors[0] != NULL) ? grid->neighbors[0] : NULL;
    i1 = grid1->nx - 1;
    cross_section_size = y_size * z_size;
  }
  else if (i1 == grid->px)
  {
    grid1 = (grid->neighbors[1] != NULL) ? grid->neighbors[1] : NULL;
    i1 = 0;
    cross_section_size = y_size * z_size;
  }
  else if (j1 == -1)
  {
    grid1 = (grid->neighbors[2] != NULL) ? grid->neighbors[2] : NULL;
    j1 = grid1->ny - 1;
    cross_section_size = x_size * z_size;
  }
  else if (j1 == grid->py)
  {
    grid1 = (grid->neighbors[3] != NULL) ? grid->neighbors[3] : NULL;
    j1 = 0;
    cross_section_size = x_size * z_size;
  }
  else if (k1 == -1)
  {
    grid1 = (grid->neighbors[4] != NULL) ? grid->neighbors[4] : NULL;
    k1 = grid1->nz - 1;
    cross_section_size = x_size * y_size;
  }
  else if (k1 == grid->px)
  {
    grid1 = (grid->neighbors[5] != NULL) ? grid->neighbors[5] : NULL;
    k1 = 0;
    cross_section_size = x_size * y_size;
  }

  if (grid1 == NULL)
    return 0;

  DECLARE_3D_ARRAY(patch_type_t, patch_types, grid1->patch_types, grid1->nx, grid1->ny, grid1->nz);
  patch_type_t patch_type = patch_types[i1][j1][k1];
  if ((patch_mask | patch_type) == 0)
    return 0;

  return cross_section_size;
}
Ejemplo n.º 8
0
bool amr_grid_has_local_patch(amr_grid_t* grid, int i, int j, int k)
{
  DECLARE_3D_ARRAY(patch_type_t, patch_types, grid->patch_types, grid->nx, grid->ny, grid->nz);
  return (patch_types[i][j][k] == LOCAL_SAME_LEVEL);
}
Ejemplo n.º 9
0
// Copies data from the patch buffer to the patches in the given grid.
static void patch_buffer_copy_out(patch_buffer_t* buffer, amr_grid_data_t* grid_data)
{
  amr_grid_t* grid = amr_grid_data_grid(grid_data);
  amr_grid_data_centering_t centering = amr_grid_data_centering(grid_data);
  int num_components = amr_grid_data_num_components(grid_data);
  int num_ghosts = amr_grid_data_num_ghosts(grid_data);

  // Now count up the sent data for each patch.
  int local_mask = LOCAL_SAME_LEVEL | LOCAL_FINER_LEVEL | LOCAL_COARSER_LEVEL;
  int pos = 0, i, j, k, p = 0;
  amr_patch_t* patch;
  DECLARE_3D_ARRAY(patch_type_t, patch_types, grid->patch_types, grid->nx, grid->ny, grid->nz);
  while (amr_grid_data_next_local_patch(grid_data, &pos, &i, &j, &k, &patch))
  {
    patch_type_t patch_type = patch_types[i][j][k];
    if (patch_type == LOCAL_SAME_LEVEL)
      polymec_error("patch_buffer_copy_out: adaptive mesh refinement is not yet supported!");

    DECLARE_AMR_PATCH_ARRAY(array, patch);
    int offset = buffer->patch_receive_offsets[p];

    // Copy out -x values.
    int num_values = num_transmitted_patch_values(grid, centering, local_mask, i, j, k, i-1, j, k);
    for (int j = patch->j1; j < patch->j2; ++j)
      for (int k = patch->k1; k < patch->k2; ++k)
        for (int g = 0; g < num_ghosts; ++g)
          for (int c = 0; c < num_components; ++c, ++offset)
            array[g][j][k][c] = buffer->data[offset];

    // Copy out +x values.
    num_values = num_transmitted_patch_values(grid, centering, local_mask, i, j, k, i+1, j, k);
    for (int j = patch->j1; j < patch->j2; ++j)
      for (int k = patch->k1; k < patch->k2; ++k)
        for (int g = 0; g < num_ghosts; ++g)
          for (int c = 0; c < num_components; ++c, ++offset)
            array[patch->i2+num_ghosts-g-1][j][k][c] = buffer->data[offset];

    // Copy out -y values.
    num_values = num_transmitted_patch_values(grid, centering, local_mask, i, j, k, i, j-1, k);
    for (int i = patch->i1; i < patch->i2; ++i)
      for (int k = patch->k1; k < patch->k2; ++k)
        for (int g = 0; g < num_ghosts; ++g)
          for (int c = 0; c < num_components; ++c, ++offset)
            array[i][g][k][c] = buffer->data[offset];

    // Copy out +y values.
    num_values = num_transmitted_patch_values(grid, centering, local_mask, i, j, k, i, j+1, k);
    for (int i = patch->i1; i < patch->i2; ++i)
      for (int k = patch->k1; k < patch->k2; ++k)
        for (int g = 0; g < num_ghosts; ++g)
          for (int c = 0; c < num_components; ++c, ++offset)
            array[i][patch->j2+num_ghosts-g-1][k][c] = buffer->data[offset];

    // Copy out -z values.
    num_values = num_transmitted_patch_values(grid, centering, local_mask, i, j, k, i, j, k-1);
    for (int i = patch->i1; i < patch->i2; ++i)
      for (int j = patch->j1; j < patch->j2; ++j)
        for (int g = 0; g < num_ghosts; ++g)
          for (int c = 0; c < num_components; ++c, ++offset)
            array[i][j][g][c] = buffer->data[offset];

    // Copy out +z values.
    num_values = num_transmitted_patch_values(grid, centering, local_mask, i, j, k, i, j, k+1);
    for (int i = patch->i1; i < patch->i2; ++i)
      for (int j = patch->j1; j < patch->j2; ++j)
        for (int g = 0; g < num_ghosts; ++g)
          for (int c = 0; c < num_components; ++c, ++offset)
            array[i][j][patch->k2+num_ghosts-g-1][c] = buffer->data[offset];

    ASSERT(offset == buffer->patch_receive_offsets[p+1]);
    ++p;
  }
}