Esempio n. 1
0
fe_block_t* fe_block_new(int num_elem,
                         fe_mesh_element_t type,
                         int num_elem_nodes,
                         int* elem_node_indices)
{
  ASSERT(num_elem > 0);
  ASSERT(elem_node_indices != NULL);
  fe_block_t* block = polymec_malloc(sizeof(fe_block_t));
  block->num_elem = num_elem;
  block->elem_type = type;

  // Element nodes.
  block->elem_node_offsets = polymec_malloc(sizeof(int) * num_elem_nodes * num_elem);
  block->elem_node_offsets[0] = 0;
  for (int i = 0; i < num_elem; ++i)
    block->elem_node_offsets[i+1] = block->elem_node_offsets[i] + num_elem_nodes;
  block->elem_nodes = polymec_malloc(sizeof(int) * block->elem_node_offsets[num_elem]);
  memcpy(block->elem_nodes, elem_node_indices, sizeof(int) * block->elem_node_offsets[num_elem]);

  // Elements don't understand their faces.
  block->elem_face_offsets = NULL;
  block->elem_faces = NULL;

  return block;
}
Esempio n. 2
0
fe_mesh_t* fe_mesh_new(MPI_Comm comm, int num_nodes)
{
  ASSERT(num_nodes >= 4);
  fe_mesh_t* mesh = polymec_malloc(sizeof(fe_mesh_t));
  mesh->comm = comm;
  mesh->num_nodes = num_nodes;
  mesh->blocks = ptr_array_new();
  mesh->block_names = string_array_new();
  mesh->block_elem_offsets = int_array_new();
  int_array_append(mesh->block_elem_offsets, 0);
  mesh->node_coords = polymec_malloc(sizeof(point_t) * mesh->num_nodes);
  memset(mesh->node_coords, 0, sizeof(point_t) * mesh->num_nodes);

  mesh->num_faces = 0;
  mesh->face_node_offsets = NULL;
  mesh->face_nodes = NULL;
  mesh->face_edge_offsets = NULL;
  mesh->face_edges = NULL;

  mesh->num_edges = 0;
  mesh->edge_node_offsets = NULL;
  mesh->edge_nodes = NULL;

  mesh->elem_sets = tagger_new();
  mesh->face_sets = tagger_new();
  mesh->edge_sets = tagger_new();
  mesh->node_sets = tagger_new();
  mesh->side_sets = tagger_new();

  return mesh;
}
Esempio n. 3
0
static void* slm_clone(void* context)
{
  slm_t* mat = context;
  slm_t* clone = polymec_malloc(sizeof(slm_t));
  clone->sparsity = adj_graph_clone(mat->sparsity);
  clone->A = supermatrix_new(clone->sparsity);
  int nnz = ((NCformat*)clone->A->Store)->nnz;
  real_t* Aij = ((NCformat*)clone->A->Store)->nzval;
  real_t* Bij = ((NCformat*)mat->A->Store)->nzval;
  memcpy(Aij, Bij, sizeof(real_t) * nnz);

  clone->N = mat->N;
  clone->rhs_data = polymec_malloc(sizeof(double) * clone->N);
  memcpy(clone->rhs_data, mat->rhs_data, sizeof(double) * clone->N);
  dCreate_Dense_Matrix(&clone->rhs, clone->N, 1, clone->rhs_data, clone->N, SLU_DN, SLU_D, SLU_GE);
  clone->X_data = polymec_malloc(sizeof(double) * clone->N);
  memcpy(clone->X_data, mat->X_data, sizeof(double) * clone->N);
  dCreate_Dense_Matrix(&clone->X, clone->N, 1, clone->X_data, clone->N, SLU_DN, SLU_D, SLU_GE);
  clone->R = polymec_malloc(sizeof(double) * clone->N);
  memcpy(clone->R, mat->R, sizeof(double) * clone->N);
  clone->C = polymec_malloc(sizeof(double) * clone->N);
  memcpy(clone->C, mat->C, sizeof(double) * clone->N);
  StatInit(&clone->stat);

  clone->cperm = NULL;
  clone->rperm = NULL;
  clone->options = mat->options;
  clone->options.Fact = DOFACT;
  clone->etree = NULL;

  return clone;
}
Esempio n. 4
0
fe_block_t* polyhedral_fe_block_new(int num_elem,
                                    int* num_elem_faces,
                                    int* elem_face_indices)
{
  ASSERT(num_elem > 0);
  ASSERT(num_elem_faces != NULL);
  ASSERT(elem_face_indices != NULL);
  fe_block_t* block = polymec_malloc(sizeof(fe_block_t));
  block->num_elem = num_elem;
  block->elem_type = FE_POLYHEDRON;

  // Element faces.
  int tot_elem_faces = 0;
  for (int i = 0; i < num_elem; ++i)
    tot_elem_faces += num_elem_faces[i];
  block->elem_face_offsets = polymec_malloc(sizeof(int) * tot_elem_faces);
  block->elem_face_offsets[0] = 0;
  for (int i = 0; i < num_elem; ++i)
    block->elem_face_offsets[i+1] = block->elem_face_offsets[i] + num_elem_faces[i];
  block->elem_faces = polymec_malloc(sizeof(int) * block->elem_face_offsets[num_elem]);
  memcpy(block->elem_faces, elem_face_indices, sizeof(int) * block->elem_face_offsets[num_elem]);

  // Element nodes/edges are not determined until the block is added to 
  // the mesh.
  block->elem_node_offsets = NULL;
  block->elem_nodes = NULL;

  return block;
}
Esempio n. 5
0
exchanger_t* exchanger_new_with_rank(MPI_Comm comm, int rank)
{
  exchanger_t* ex = polymec_malloc(sizeof(exchanger_t));
  ex->comm = comm;
  ex->rank = rank;
  MPI_Comm_size(comm, &(ex->nprocs));
  ex->send_offset = 0;
  ex->receive_offset = 0;
  ex->dl_thresh = -1.0;
  ex->dl_output_rank = -1;
  ex->dl_output_stream = NULL;
  ex->send_map = exchanger_map_new();
  ex->receive_map = exchanger_map_new();
  ex->num_pending_msgs = 0;
  ex->pending_msg_cap = 32;
  ex->pending_msgs = polymec_malloc(ex->pending_msg_cap * sizeof(mpi_message_t*));
  memset(ex->pending_msgs, 0, ex->pending_msg_cap * sizeof(mpi_message_t*));
  ex->orig_buffers = polymec_malloc(ex->pending_msg_cap * sizeof(void*));
  memset(ex->orig_buffers, 0, ex->pending_msg_cap * sizeof(void*));
  ex->transfer_counts = polymec_malloc(ex->pending_msg_cap * sizeof(int*));
  memset(ex->transfer_counts, 0, ex->pending_msg_cap * sizeof(int*));
  ex->max_send = -1;
  ex->max_receive = -1;

  return ex;
}
local_matrix_t* var_block_diagonal_matrix_new(int num_block_rows,
                                              int* block_sizes)
{
  bdm_t* A = polymec_malloc(sizeof(bdm_t));
  A->num_block_rows = num_block_rows;
  A->D_offsets = polymec_malloc(sizeof(int) * (num_block_rows+1));
  A->B_offsets = polymec_malloc(sizeof(int) * (num_block_rows+1));
  A->D_offsets[0] = A->B_offsets[0] = 0;
  bool constant_block_size = true;
  int bs0 = -1;
  for (int i = 0; i < num_block_rows; ++i)
  {
    int bs = block_sizes[i];
    if (bs0 == -1)
      bs0 = bs;
    else if (bs != bs0)
      constant_block_size = false;
    ASSERT(bs >= 1);
    A->D_offsets[i+1] = A->D_offsets[i] + bs*bs;
    A->B_offsets[i+1] = A->B_offsets[i] + bs;
  }
  if (constant_block_size)
    A->block_size = bs0;
  else
    A->block_size = -1;
  int N = A->D_offsets[A->num_block_rows];
  A->D = polymec_malloc(sizeof(real_t) * N);

  char name[1024];
  if (constant_block_size)
    snprintf(name, 1024, "Block diagonal matrix (bs = %d)", bs0);
  else
    snprintf(name, 1024, "Variable block diagonal matrix");
  local_matrix_vtable vtable = {.clone = bdm_clone,
                                .dtor = bdm_dtor,
                                .zero = bdm_zero,
                                .num_columns = bdm_num_columns,
                                .get_columns = bdm_get_columns,
                                .add_identity = bdm_add_identity,
                                .add_column_vector = bdm_add_column_vector,
                                .add_row_vector = bdm_add_row_vector,
                                .solve = bdm_solve,
                                .fprintf = bdm_fprintf,
                                .value = bdm_value,
                                .set_value = bdm_set_value,
                                .get_diag = bdm_get_diag,
                                .matvec = bdm_matvec,
                                .add_matrix = bdm_add_matrix,
                                .norm = bdm_norm};
  if (constant_block_size)
  {
    vtable.add_column_vector = bdm_add_column_vector_constant_bs;
    vtable.value = bdm_value_constant_bs;
    vtable.set_value = bdm_set_value_constant_bs;
  }
  return local_matrix_new(name, A, vtable, A->B_offsets[num_block_rows]);
}
Esempio n. 7
0
cpr_differencer_t* cpr_differencer_new(MPI_Comm comm,
                                       void* F_context,
                                       int (*F)(void* context, real_t, real_t* x, real_t* Fval),
                                       int (*F_dae)(void* context, real_t, real_t* x, real_t* xdot, real_t* Fval),
                                       void (*F_dtor)(void* context),
                                       adj_graph_t* sparsity,
                                       int num_local_rows,
                                       int num_remote_rows)
{
  ASSERT(num_local_rows > 0);
  ASSERT(num_remote_rows >= 0);

  // Exactly one of F and F_dae must be given.
  ASSERT((F != NULL) || (F_dae != NULL));
  ASSERT((F == NULL) || (F_dae == NULL));

  START_FUNCTION_TIMER();

  cpr_differencer_t* diff = polymec_malloc(sizeof(cpr_differencer_t));
  diff->comm = comm;
  diff->F_context = F_context;
  diff->F = F;
  diff->F_dae = F_dae;
  diff->F_dtor = F_dtor;

  // Steal the graph.
  diff->sparsity = sparsity;

  // The number of local rows is known at this point.
  diff->num_local_rows = num_local_rows;

  // However, we can't know the actual number of remote block rows without 
  // knowing the specific communication pattern! However, it is safe to just 
  // multiply the given number of remote block rows by the maximum block size, 
  // since only the underlying RHS function will actually use the data.
  diff->num_remote_rows = num_remote_rows;

  // Assemble a graph coloring for any matrix we treat.
  diff->coloring = adj_graph_coloring_new(diff->sparsity, SMALLEST_LAST);

  // Get the maximum number of colors on all MPI processes so that we can 
  // compute in lockstep.
  int num_colors = adj_graph_coloring_num_colors(diff->coloring);
  MPI_Allreduce(&num_colors, &diff->max_colors, 1, MPI_INT, MPI_MAX, diff->comm);
  log_debug("cpr_differencer: graph coloring produced %d colors.", diff->max_colors);

  // Make work vectors.
  diff->num_work_vectors = 4;
  diff->work = polymec_malloc(sizeof(real_t*) * diff->num_work_vectors);
  int N = diff->num_local_rows + diff->num_remote_rows;
  for (int i = 0; i < diff->num_work_vectors; ++i)
    diff->work[i] = polymec_malloc(sizeof(real_t) * N);
  diff->Jv = polymec_malloc(sizeof(real_t) * (diff->num_local_rows + diff->num_remote_rows));

  STOP_FUNCTION_TIMER();
  return diff;
}
Esempio n. 8
0
str_grid_edge_data_t* str_grid_edge_data_with_buffer(str_grid_t* grid, 
                                                     int num_components,
                                                     void* buffer)
{
  ASSERT(num_components > 0);

  // Allocate storage.
  int num_patches = 3 * str_grid_num_patches(grid);
  size_t patches_size = sizeof(str_grid_patch_t*) * num_patches;
  size_t edge_data_size = sizeof(str_grid_edge_data_t) + patches_size;
  str_grid_edge_data_t* edge_data = polymec_malloc(edge_data_size);
  edge_data->grid = grid;
  edge_data->nc = num_components;

  str_grid_get_extents(grid, &edge_data->nx, &edge_data->ny, &edge_data->nz);
  edge_data->x_patches = int_ptr_unordered_map_new();
  edge_data->y_patches = int_ptr_unordered_map_new();
  edge_data->z_patches = int_ptr_unordered_map_new();
  edge_data->patch_offsets = polymec_malloc(sizeof(int) * (3*num_patches+1));
  edge_data->buffer = NULL;

  // Now populate the patches for x-, y-, and z-edges.
  int px, py, pz;
  str_grid_get_patch_size(grid, &px, &py, &pz);
  edge_data->patch_lx = 1.0 / edge_data->nx;
  edge_data->patch_ly = 1.0 / edge_data->ny;
  edge_data->patch_lz = 1.0 / edge_data->nz;
  int pos = 0, i, j, k;
  while (str_grid_next_patch(grid, &pos, &i, &j, &k))
  {
    int index = patch_index(edge_data, i, j, k);

    int_ptr_unordered_map_insert_with_v_dtor(edge_data->x_patches, index, 
                                             str_grid_patch_with_buffer(px+1, py, pz, num_components, 0, NULL),
                                             DTOR(str_grid_patch_free));

    int_ptr_unordered_map_insert_with_v_dtor(edge_data->y_patches, index, 
                                             str_grid_patch_with_buffer(px, py+1, pz, num_components, 0, NULL),
                                             DTOR(str_grid_patch_free));

    int_ptr_unordered_map_insert_with_v_dtor(edge_data->z_patches, index, 
                                             str_grid_patch_with_buffer(px, py, pz+1, num_components, 0, NULL),
                                             DTOR(str_grid_patch_free));
  }
  count_edges(edge_data);

  // Set the buffer.
  str_grid_edge_data_set_buffer(edge_data, buffer, false);

  return edge_data;
}
Esempio n. 9
0
fe_mesh_t* fe_mesh_from_mesh(mesh_t* fv_mesh,
                             string_array_t* element_block_tags)
{
  fe_mesh_t* fe_mesh = fe_mesh_new(fv_mesh->comm, fv_mesh->num_nodes);

  if ((element_block_tags != NULL) && (element_block_tags->size > 1))
  {
    // Block-by-block construction.
    for (int b = 0; b < element_block_tags->size; ++b)
    {
      char* tag_name = element_block_tags->data[b];
      size_t num_elem;
      int* block_tag = mesh_tag(fv_mesh->cell_tags, tag_name, &num_elem);
      int* num_elem_faces = polymec_malloc(sizeof(int) * num_elem);
      int elem_faces_size = 0;
      for (int i = 0; i < num_elem; ++i)
      {
        int nef = fv_mesh->cell_face_offsets[block_tag[i]+1] - fv_mesh->cell_face_offsets[block_tag[i]];
        num_elem_faces[i] = nef;
        elem_faces_size += nef;
      }
      int* elem_faces = polymec_malloc(sizeof(int) * elem_faces_size);
      int offset = 0;
      for (int i = 0; i < num_elem; ++i)
      {
        for (int f = 0; f < num_elem_faces[i]; ++f, ++offset)
          elem_faces[offset+f] = fv_mesh->cell_faces[fv_mesh->cell_face_offsets[block_tag[i]+f]];
      }
      fe_block_t* block = polyhedral_fe_block_new((int)num_elem, num_elem_faces, fv_mesh->cell_faces);
      fe_mesh_add_block(fe_mesh, tag_name, block);
      polymec_free(num_elem_faces);
      polymec_free(elem_faces);
    }
  }
  else
  {
    // One honking block.
    int num_elem = fv_mesh->num_cells;
    int* num_elem_faces = polymec_malloc(sizeof(int) * num_elem);
    for (int i = 0; i < num_elem; ++i)
      num_elem_faces[i] = fv_mesh->cell_face_offsets[i+1] - fv_mesh->cell_face_offsets[i];
    fe_block_t* block = polyhedral_fe_block_new(num_elem, num_elem_faces, fv_mesh->cell_faces);
    fe_mesh_add_block(fe_mesh, "block_1", block);
    polymec_free(num_elem_faces);
  }

  // Copy coordinates.
  memcpy(fe_mesh_node_positions(fe_mesh), fv_mesh->nodes, sizeof(point_t) * fv_mesh->num_nodes);

  return fe_mesh;
}
Esempio n. 10
0
void fe_mesh_set_face_nodes(fe_mesh_t* mesh, 
                            int num_faces,
                            int* num_face_nodes, 
                            int* face_nodes)
{
  ASSERT(num_faces > 0);
  mesh->num_faces = num_faces;
  mesh->face_node_offsets = polymec_malloc(sizeof(int) * (mesh->num_faces+1));
  mesh->face_node_offsets[0] = 0;
  for (int i = 0; i < num_faces; ++i)
    mesh->face_node_offsets[i+1] = mesh->face_node_offsets[i] + num_face_nodes[i];
  mesh->face_nodes = polymec_malloc(sizeof(int) * mesh->face_node_offsets[num_faces]);
  memcpy(mesh->face_nodes, face_nodes, sizeof(int) * mesh->face_node_offsets[num_faces]);
}
Esempio n. 11
0
polygon2_t* polygon2_new_with_ordering(point2_t* points, int* ordering, int num_points)
{
  ASSERT(points != NULL);
  ASSERT(num_points >= 3);
  polygon2_t* poly = GC_MALLOC(sizeof(polygon2_t));
  poly->vertices = polymec_malloc(sizeof(point2_t)*num_points);
  memcpy(poly->vertices, points, sizeof(point2_t)*num_points);
  poly->num_vertices = num_points;
  poly->ordering = polymec_malloc(sizeof(int)*num_points);
  memcpy(poly->ordering, ordering, sizeof(int)*num_points);
  polygon2_compute_area(poly);
  GC_register_finalizer(poly, polygon2_free, poly, NULL, NULL);
  return poly;
}
Esempio n. 12
0
ode_integrator_t* functional_euler_ode_integrator_new(real_t theta, 
                                                      MPI_Comm comm,
                                                      int num_local_values,
                                                      int num_remote_values,
                                                      void* context, 
                                                      int (*rhs)(void* context, real_t t, real_t* x, real_t* xdot),
                                                      void (*dtor)(void* context))
{
  ASSERT(theta >= 0.0);
  ASSERT(theta <= 1.0);
  ASSERT(num_local_values > 0);
  ASSERT(num_remote_values >= 0);
  ASSERT(rhs != NULL);

  euler_ode_t* integ = polymec_malloc(sizeof(euler_ode_t));
  integ->theta = theta;
  integ->comm = comm;
  integ->num_local_values = num_local_values;
  integ->num_remote_values = num_remote_values;
  integ->context = context;
  integ->rhs = rhs;
  integ->dtor = dtor;
  integ->newton = NULL;
  integ->observers = ptr_array_new();

  integ->x_old = polymec_malloc(sizeof(real_t) * (num_local_values + num_remote_values));
  integ->x_new = polymec_malloc(sizeof(real_t) * (num_local_values + num_remote_values));
  integ->f1 = polymec_malloc(sizeof(real_t) * num_local_values); // no ghosts here!
  integ->f2 = polymec_malloc(sizeof(real_t) * num_local_values); // no ghosts here!

  ode_integrator_vtable vtable = {.step = euler_step, 
                                  .advance = euler_advance, 
                                  .dtor = euler_dtor};

  int order = 1;
  if (theta == 0.5) 
    order = 2;

  char name[1024];
  snprintf(name, 1024, "Functional Euler integrator(theta = %g)", theta);
  ode_integrator_t* I = ode_integrator_new(name, integ, vtable, order);

  // Set default iteration criteria.
  euler_ode_integrator_set_max_iterations(I, 100);
  euler_ode_integrator_set_tolerances(I, 1e-4, 1.0);
  euler_ode_integrator_set_lp_convergence_norm(I, 0);

  return I;
}
Esempio n. 13
0
static exchanger_channel_t* exchanger_channel_new(int num_indices, int* indices, bool copy_indices)
{
  ASSERT(num_indices > 0);
  ASSERT(indices != NULL);
  exchanger_channel_t* c = polymec_malloc(sizeof(exchanger_channel_t));
  c->num_indices = num_indices;
  if (copy_indices)
  {
    c->indices = polymec_malloc(sizeof(int)*num_indices);
    memcpy(c->indices, indices, sizeof(int)*num_indices);
  }
  else
    c->indices = indices; // Assumes control of memory
  return c;
}
Esempio n. 14
0
static void* bdm_clone(void* context)
{
  bdm_t* mat = context;
  bdm_t* clone = polymec_malloc(sizeof(bdm_t));
  clone->num_block_rows = mat->num_block_rows;
  clone->D_offsets = polymec_malloc(sizeof(int) * (clone->num_block_rows+1));
  memcpy(clone->D_offsets, mat->D_offsets, sizeof(int) * (clone->num_block_rows+1));
  clone->B_offsets = polymec_malloc(sizeof(int) * (clone->num_block_rows+1));
  memcpy(clone->B_offsets, mat->B_offsets, sizeof(int) * (clone->num_block_rows+1));
  int N = clone->D_offsets[clone->num_block_rows];
  clone->D = polymec_malloc(sizeof(real_t) * N);
  memcpy(clone->D, mat->D, sizeof(real_t) * N);
  clone->block_size = mat->block_size;
  return clone;
}
Esempio n. 15
0
ode_integrator_t* newton_euler_ode_integrator_new(MPI_Comm comm,
                                                  int num_local_values,
                                                  int num_remote_values,
                                                  void* context,
                                                  int (*rhs)(void* context, real_t t, real_t* x, real_t* xdot),
                                                  void (*dtor)(void* context),
                                                  newton_pc_t* precond,
                                                  newton_krylov_t solver_type,
                                                  int max_krylov_dim)
{
  ASSERT(num_local_values > 0);
  ASSERT(num_remote_values >= 0);
  ASSERT(max_krylov_dim > 3);
  ASSERT(rhs != NULL);

  euler_ode_t* integ = polymec_malloc(sizeof(euler_ode_t));
  integ->theta = -FLT_MAX;
  integ->comm = comm;
  integ->num_local_values = num_local_values;
  integ->num_remote_values = num_remote_values;
  integ->context = context;
  integ->rhs = rhs;
  integ->dtor = dtor;

  // Set up the Newton solver.
  newton_solver_vtable newton_vtable = {.eval = evaluate_residual};
  integ->newton = newton_solver_new(comm, num_local_values, num_remote_values,
                                    integ, newton_vtable, precond, 
                                    solver_type, max_krylov_dim, 5);

  integ->observers = ptr_array_new();

  integ->x_old = polymec_malloc(sizeof(real_t) * (num_local_values + num_remote_values));
  integ->x_new = polymec_malloc(sizeof(real_t) * (num_local_values + num_remote_values));
  integ->f1 = integ->f2 = NULL;

  ode_integrator_vtable vtable = {.step = newton_euler_step, 
                                  .advance = euler_advance, 
                                  .dtor = euler_dtor};

  int order = 1;
  ode_integrator_t* I = ode_integrator_new("Backward Euler Newton integrator", integ, vtable, order);

  // Set default iteration criteria.
  euler_ode_integrator_set_max_iterations(I, 100);

  return I;
}
Esempio n. 16
0
void test_real_array6(void** state) 
{ 
  void* storage = polymec_malloc(sizeof(real_t)*2*2*2*2*2*2);
  DECLARE_6D_ARRAY(real_t, a, storage, 2, 2, 2, 2, 2, 2);
  for (int i = 0; i < 2; ++i)
    for (int j = 0; j < 2; ++j)
      for (int k = 0; k < 2; ++k)
        for (int l = 0; l < 2; ++l)
          for (int m = 0; m < 2; ++m)
            for (int n = 0; n < 2; ++n)
              a[i][j][k][l][m][n] = 32*i + 16*j + 8*k + 4*l + 2*m + n;
  for (int i = 0; i < 2; ++i)
  {
    for (int j = 0; j < 2; ++j)
    {  
      for (int k = 0; k < 2; ++k)
      {  
        for (int l = 0; l < 2; ++l)
        {  
          for (int m = 0; m < 2; ++m)
          {
            for (int n = 0; n < 2; ++n)
            {
              assert_real_equal(32*i + 16*j + 8*k + 4*l + 2*m + n, a[i][j][k][l][m][n]);
            }
          }
        }
      }
    }
  }
  polymec_free(storage);
} 
Esempio n. 17
0
static octree_node_t* branch_new()
{
  octree_node_t* node = polymec_malloc(sizeof(octree_node_t));
  node->type = OCTREE_BRANCH_NODE;
  memset(node->branch_node.children, 0, 8*sizeof(octree_node_t*));
  return node;
}
Esempio n. 18
0
real_t* exodus_file_read_face_field(exodus_file_t* file,
                                    int time_index,
                                    const char* field_name)
{
  // Find the variable index.
  int index = 0;
  while (index < file->face_var_names->size)
  {
    if (strcmp(field_name, file->face_var_names->data[index]) == 0)
      break;
    ++index;
  }

  // Fetch the field data.
  if (index < file->face_var_names->size)
  {
    int offset = 0;
    real_t* field = polymec_malloc(sizeof(real_t) * file->num_faces);
    memset(field, 0, sizeof(real_t) * file->num_faces);
    for (int i = 0; i < file->num_face_blocks; ++i)
    {
      int N;
      ex_get_block(file->ex_id, EX_FACE_BLOCK, file->face_block_ids[i], NULL, &N, NULL, NULL, NULL, NULL);
      ex_get_var(file->ex_id, time_index, EX_FACE_BLOCK, index+1, i, N, &field[offset]);
      offset += N;
    }
    return field;
  }
  else
    return NULL;
}
Esempio n. 19
0
sp_func_t* difference_new(sp_func_t* surface1, sp_func_t* surface2)
{
  ASSERT(surface1 != NULL);
  ASSERT(sp_func_num_comp(surface1) == 1);
  ASSERT(surface2 != NULL);
  ASSERT(sp_func_num_comp(surface2) == 1);

  diff_t* diff = polymec_malloc(sizeof(diff_t));
  diff->s1 = surface1;
  diff->s2 = surface2;

  char diff_str[4096];
  sprintf(diff_str, "Difference (%s, %s)", sp_func_name(surface1), sp_func_name(surface2));
  sp_func_vtable vtable = {.eval = diff_eval, .dtor = polymec_free};
  sp_func_t* difference = sp_func_new(diff_str, diff, vtable, SP_FUNC_INHOMOGENEOUS, 1);

  // Register the gradient function if we have it.
  if (sp_func_has_deriv(surface1, 1) && sp_func_has_deriv(surface2, 1))
  {
    char diff_grad_str[4096];
    sprintf(diff_grad_str, "grad %s", diff_str);
    sp_func_vtable vtable_g = {.eval = diff_eval_gradient}; // Notice no dtor.
    sp_func_t* diff_grad = sp_func_new(diff_grad_str, diff, vtable_g, SP_FUNC_INHOMOGENEOUS, 3);
    sp_func_register_deriv(difference, 1, diff_grad);
  }
Esempio n. 20
0
static void* np_byte_read(byte_array_t* bytes, size_t* offset)
{
  // Read the name.
  int name_len; 
  byte_array_read_ints(bytes, 1, &name_len, offset);
  char name[name_len+1];
  byte_array_read_chars(bytes, name_len, name, offset);
  name[name_len] = '\0';

  // Read the offsets, indices, weights.
  int num_pairs, num_weights;
  byte_array_read_ints(bytes, 1, &num_pairs, offset);
  int* pairs = polymec_malloc(sizeof(int) * 2 * num_pairs);
  byte_array_read_ints(bytes, 2*num_pairs, pairs, offset);
  byte_array_read_ints(bytes, 1, &num_weights, offset);
  real_t* weights = NULL;
  if (num_weights > 0)
    byte_array_read_real_ts(bytes, num_weights, weights, offset);

  // Exchanger stuff.
  serializer_t* ser = exchanger_serializer();
  exchanger_t* ex = serializer_read(ser, bytes, offset);

  return neighbor_pairing_new(name, num_pairs, pairs, weights, ex);
}
Esempio n. 21
0
neighbor_pairing_t* silo_file_read_neighbor_pairing(silo_file_t* file,
                                                    const char* neighbors_name,
                                                    MPI_Comm comm)
{
  neighbor_pairing_t* p = polymec_malloc(sizeof(neighbor_pairing_t));
  char name_name[FILENAME_MAX];
  snprintf(name_name, FILENAME_MAX, "%s_neighbor_pairing_name", neighbors_name);
  p->name = silo_file_read_string(file, name_name);
  char pairs_name[FILENAME_MAX];
  snprintf(pairs_name, FILENAME_MAX, "%s_neighbor_pairing_pairs", neighbors_name);
  int size;
  p->pairs = silo_file_read_int_array(file, pairs_name, &size);
  ASSERT((size % 2) == 0);
  p->num_pairs = size/2;
  char weights_name[FILENAME_MAX];
  snprintf(weights_name, FILENAME_MAX, "%s_neighbor_pairing_weights", neighbors_name);
  int num_weights;
  p->weights = silo_file_read_real_array(file, weights_name, &num_weights);
  ASSERT((num_weights == p->num_pairs) || 
         ((num_weights == 0) && (p->weights == NULL)));
  char ex_name[FILENAME_MAX];
  snprintf(ex_name, FILENAME_MAX, "%s_neighbor_pairing_ex", neighbors_name);
  p->ex = silo_file_read_exchanger(file, ex_name, comm);
  return p;
}
Esempio n. 22
0
fe_block_t* fe_block_clone(fe_block_t* block)
{
  fe_block_t* copy = polymec_malloc(sizeof(fe_block_t));
  copy->num_elem = block->num_elem;
  copy->elem_type = block->elem_type;
  return copy;
}
Esempio n. 23
0
void test_int_array5(void** state) 
{ 
  void* storage = polymec_malloc(sizeof(int)*2*2*2*2*2);
  DECLARE_5D_ARRAY(int, a, storage, 2, 2, 2, 2, 2);
  for (int i = 0; i < 2; ++i)
    for (int j = 0; j < 2; ++j)
      for (int k = 0; k < 2; ++k)
        for (int l = 0; l < 2; ++l)
          for (int m = 0; m < 2; ++m)
            a[i][j][k][l][m] = 16*i + 8*j + 4*k + 2*l + m;
  for (int i = 0; i < 2; ++i)
  {
    for (int j = 0; j < 2; ++j)
    {  
      for (int k = 0; k < 2; ++k)
      {  
        for (int l = 0; l < 2; ++l)
        {  
          for (int m = 0; m < 2; ++m)
          {
            assert_int_equal(16*i + 8*j + 4*k + 2*l + m, a[i][j][k][l][m]);
          }
        }
      }
    }
  }
  polymec_free(storage);
} 
Esempio n. 24
0
shape_function_t* mls_shape_function_new(int polynomial_degree,
                                         shape_function_kernel_t* kernel,
                                         point_cloud_t* domain,
                                         stencil_t* neighborhoods,
                                         real_t* smoothing_lengths)
{
  ASSERT(polynomial_degree >= 0);
  ASSERT(polynomial_degree <= 4);

  mls_t* mls = polymec_malloc(sizeof(mls_t));
  mls->W = kernel;

  // Set up a polynomial to evaluate the moment matrix.
  mls->poly_degree = polynomial_degree;
  mls->basis_dim = polynomial_basis_dim(polynomial_degree);
  real_t poly_coeffs[mls->basis_dim];
  for (int i = 0; i < mls->basis_dim; ++i)
    poly_coeffs[i] = 1.0;
  mls->P = polynomial_new(polynomial_degree, poly_coeffs, NULL);
  mls->domain = domain;
  mls->neighborhoods = neighborhoods;
  mls->smoothing_lengths = smoothing_lengths;
  mls->basis = NULL;
  mls->basis_ddx = NULL;
  mls->basis_ddy = NULL;
  mls->basis_ddz = NULL;

  // Count up the maximum neighborhood size and allocate storage.
  int max_neighborhood_size = -1;
  for (int i = 0; i < mls->domain->num_points; ++i)
    max_neighborhood_size = MAX(max_neighborhood_size, stencil_size(mls->neighborhoods, i));
  mls->xj = polymec_malloc(sizeof(point_t) * max_neighborhood_size);
  mls->hj = polymec_malloc(sizeof(real_t) * max_neighborhood_size);

  // Make sure our ghost points are consistent.
  stencil_exchange(mls->neighborhoods, mls->domain->points, 3, 0, MPI_REAL_T);
  stencil_exchange(mls->neighborhoods, mls->smoothing_lengths, 1, 0, MPI_REAL_T);

  shape_function_vtable vtable = {.neighborhood_size = mls_neighborhood_size,
                                  .get_neighborhood_points = mls_get_neighborhood_points,
                                  .set_neighborhood = mls_set_neighborhood,
                                  .compute = mls_compute,
                                  .dtor = mls_dtor};
  char name[1024];
  snprintf(name, 1023, "MLS shape function (p = %d)", polynomial_degree);
  return shape_function_new(name, mls, vtable);
}
Esempio n. 25
0
// This creates a new leaf node with a single occupant.
static octree_node_t* leaf_new(point_t* point, int index)
{
  octree_node_t* node = polymec_malloc(sizeof(octree_node_t));
  node->type = OCTREE_LEAF_NODE;
  node->leaf_node.index = index;
  node->leaf_node.point = *point;
  return node;
}
Esempio n. 26
0
fe_mesh_t* fe_mesh_clone(fe_mesh_t* mesh)
{
  fe_mesh_t* copy = polymec_malloc(sizeof(fe_mesh_t));
  copy->comm = mesh->comm;
  copy->num_nodes = mesh->num_nodes;
  copy->blocks = ptr_array_new();
  for (int i = 0; i < mesh->blocks->size; ++i)
    copy->blocks->data[i] = fe_block_clone(mesh->blocks->data[i]);
  copy->block_names = string_array_new();
  for (int i = 0; i < mesh->block_names->size; ++i)
    copy->block_names->data[i] = string_dup(mesh->block_names->data[i]);
  copy->block_elem_offsets = int_array_new();
  for (int i = 0; i < mesh->block_elem_offsets->size; ++i)
    int_array_append(copy->block_elem_offsets, mesh->block_elem_offsets->data[i]);
  copy->node_coords = polymec_malloc(sizeof(point_t) * copy->num_nodes);
  memcpy(copy->node_coords, mesh->node_coords, sizeof(point_t) * copy->num_nodes);
  return copy;
}
Esempio n. 27
0
static void fetch_variable_names(int ex_id, ex_entity_type obj_type, string_array_t* var_names)
{
  int num_vars;
  ex_get_variable_param(ex_id, obj_type, &num_vars);
  for (int i = 0; i < num_vars; ++i)
    string_array_append_with_dtor(var_names, (char*)polymec_malloc(sizeof(char) * (MAX_NAME_LENGTH+1)), string_free);
  if (num_vars > 0)
    ex_get_variable_names(ex_id, obj_type, num_vars, var_names->data);
}
Esempio n. 28
0
str_grid_cell_filler_t* str_grid_cell_filler_new(str_grid_t* grid)
{
  str_grid_cell_filler_t* filler = polymec_malloc(sizeof(str_grid_cell_filler_t));
  filler->grid = grid;
  str_grid_get_extents(grid, &filler->nx, &filler->ny, &filler->nz);
  filler->patch_fillers = int_ptr_unordered_map_new();
  filler->tokens = int_ptr_unordered_map_new();
  return filler;
}
Esempio n. 29
0
rng_t* posix_rng_new(size_t state_size)
{
  static const int num_bytes = 256;
  char* state = polymec_malloc(sizeof(char) * num_bytes);
  rng_vtable vtable = {.set_seed = posix_set_seed,
                       .get = posix_get,
                       .dtor = posix_free};
  initstate(random(), state, num_bytes);
  return rng_new("posix RNG", state, 0, posix_max, vtable, true, false);
}
Esempio n. 30
0
str_grid_node_data_t* str_grid_node_data_new(str_grid_t* grid, 
                                             int num_components)
{
  str_grid_node_data_t* node_data = 
    str_grid_node_data_with_buffer(grid, num_components, NULL);
  int data_size = node_data->num_nodes * node_data->nc;
  void* buffer = polymec_malloc(sizeof(real_t) * data_size);
  str_grid_node_data_set_buffer(node_data, buffer, true);
  return node_data;
}