Example #1
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;
}
Example #2
0
/* assumes static lock is held */
static inline bool quark_init_if_needed()
{
  if (quark_string_hash == NULL)
  {
    quark_string_hash = create_hashtable(31, string_hash, string_eq);
    quark_string_index = ptr_array_new(10);
    ptr_array_append(quark_string_index, NULL);
    return true;
  }
  return false;
}
Example #3
0
static ptr_array _gather_roots(STATE, cpu c) {
  ptr_array roots;
  roots = ptr_array_new(NUM_OF_GLOBALS + 100);

  memcpy(roots->array, state->global, sizeof(struct rubinius_globals));
  roots->length = NUM_OF_GLOBALS;

  cpu_add_roots(state, c, roots);
  /* truncate the free_context list since we don't care about them
     after we've collected anyway */
  return roots;
}
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;
}
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;
}
void str_grid_cell_filler_insert(str_grid_cell_filler_t* cell_filler, 
                                 int i, int j, int k,
                                 str_grid_patch_filler_t* patch_filler)
{
  int index = patch_index(cell_filler, i, j, k);
  ASSERT(str_grid_has_patch(cell_filler->grid, i, j, k));
  ptr_array_t** fillers_p = (ptr_array_t**)int_ptr_unordered_map_get(cell_filler->patch_fillers, index);
  ptr_array_t* fillers;
  if (fillers_p != NULL)
    fillers = *fillers_p;
  else
  {
    fillers = ptr_array_new();
    int_ptr_unordered_map_insert_with_v_dtor(cell_filler->patch_fillers, index, fillers, DTOR(ptr_array_free));
  }
  ptr_array_append(fillers, patch_filler);
}
Example #7
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;
}
amr_data_hierarchy_t* amr_data_hierarchy_new(amr_grid_hierarchy_t* grids,
                                             int num_components,
                                             int num_ghosts)
{
  ASSERT(num_components > 0);
  amr_data_hierarchy_t* data = polymec_malloc(sizeof(amr_data_hierarchy_t));
  data->grids = grids;
  data->num_components = num_components;
  data->num_ghosts = num_ghosts;
  data->grid_data = ptr_array_new();

  int pos = 0;
  amr_grid_t* level;
  while (amr_grid_hierarchy_next_coarsest(grids, &pos, &level))
  {
    amr_grid_data_t* grid_data = amr_grid_data_new(level, AMR_GRID_CELL, data->num_components, data->num_ghosts);
    ptr_array_append_with_dtor(data->grid_data, grid_data, DTOR(amr_grid_data_free));
  }
  return data;
}
void create_boundary_generators(ptr_array_t* surface_points, 
                                ptr_array_t* surface_normals, 
                                ptr_array_t* surface_tags,
                                point_t** boundary_generators,
                                int* num_boundary_generators,
                                char*** tag_names,
                                int_array_t*** tags,
                                int* num_tags)
{
  ASSERT(surface_points->size >= 4); // surface must be closed!
  ASSERT(surface_points->size == surface_normals->size);
  ASSERT(surface_points->size == surface_tags->size);

  int num_surface_points = surface_points->size;

  // Compute the minimum distance from each surface point to its neighbors.
  real_t* h_min = polymec_malloc(sizeof(real_t) * num_surface_points);
  {
    // Dump the surface points into a kd-tree.
    point_t* surf_points = polymec_malloc(sizeof(point_t) * num_surface_points);
    for (int i = 0; i < num_surface_points; ++i)
      surf_points[i] = *((point_t*)surface_points->data[i]);
    kd_tree_t* tree = kd_tree_new(surf_points, num_surface_points);

    int neighbors[2];
    for (int i = 0; i < num_surface_points; ++i)
    {
      // Find the "nearest 2" points to the ith surface point--the first is 
      // the point itself, and the second is its nearest neighbor.
      // FIXME: Serious memory error within here. We work around it for 
      // FIXME: the moment by freshing the tree pointer, which is 
      // FIXME: corrupted. ICK!
      kd_tree_t* tree_p = tree;
      kd_tree_nearest_n(tree, &surf_points[i], 2, neighbors);
      tree = tree_p;
      ASSERT(neighbors[0] == i);
      ASSERT(neighbors[1] >= 0);
      ASSERT(neighbors[1] < num_surface_points);
      h_min[i] = point_distance(&surf_points[i], &surf_points[neighbors[1]]);
    }

    // Clean up.
    kd_tree_free(tree);
    polymec_free(surf_points);
  }

  // Generate boundary points for each surface point based on how many 
  // surfaces it belongs to. 
  ptr_array_t* boundary_points = ptr_array_new();
  string_int_unordered_map_t* tag_indices = string_int_unordered_map_new();
  ptr_array_t* boundary_tags = ptr_array_new();
  for (int i = 0; i < num_surface_points; ++i)
  {
    // Add any tags from this point to the set of existing boundary tags.
    string_slist_t* tags = surface_tags->data[i];
    for (string_slist_node_t* t_iter = tags->front; t_iter != NULL; t_iter = t_iter->next)
      string_int_unordered_map_insert(tag_indices, t_iter->value, tag_indices->size);

    // Retrieve the surface point.
    point_t* x_surf = surface_points->data[i];

    // Retrieve the list of normal vectors for this surface point.
    ptr_slist_t* normal_list = surface_normals->data[i];
    int num_normals = normal_list->size;
    vector_t normals[num_normals];
    int n_offset = 0;
    for (ptr_slist_node_t* n_iter = normal_list->front; n_iter != NULL; n_iter = n_iter->next)
      normals[n_offset++] = *((vector_t*)n_iter->value);

    // For now, let's keep things relatively simple.
    if (num_normals > 2)
    {
      polymec_error("create_boundary_generators: Too many normal vectors (%d) for surface point %d at (%g, %g, %g)",
                    num_normals, i, x_surf->x, x_surf->y, x_surf->z);
    }

    // Create boundary points based on this list of normals.
    if (num_normals == 1)
    {
      // This point only belongs to one surface, so we create boundary points 
      // on either side of it.
      point_t* x_out = polymec_malloc(sizeof(point_t));
      x_out->x = x_surf->x + h_min[i]*normals[0].x;
      x_out->y = x_surf->y + h_min[i]*normals[0].y;
      x_out->z = x_surf->z + h_min[i]*normals[0].z;
      ptr_array_append_with_dtor(boundary_points, x_out, polymec_free);

      point_t* x_in = polymec_malloc(sizeof(point_t));
      x_in->x = x_surf->x - h_min[i]*normals[0].x;
      x_in->y = x_surf->y - h_min[i]*normals[0].y;
      x_in->z = x_surf->z - h_min[i]*normals[0].z;
      ptr_array_append_with_dtor(boundary_points, x_in, polymec_free);
    }
    else if (num_normals == 2)
    {
      // This point appears at the interface between two surfaces.
      // (Or so it seems.)
      ASSERT(vector_dot(&normals[0], &normals[1]) < 0.0);

      point_t* x1 = polymec_malloc(sizeof(point_t));
      x1->x = x_surf->x + h_min[i]*normals[0].x;
      x1->y = x_surf->y + h_min[i]*normals[0].y;
      x1->z = x_surf->z + h_min[i]*normals[0].z;
      ptr_array_append_with_dtor(boundary_points, x1, polymec_free);

      point_t* x2 = polymec_malloc(sizeof(point_t));
      x2->x = x_surf->x - h_min[i]*normals[1].x;
      x2->y = x_surf->y - h_min[i]*normals[1].y;
      x2->z = x_surf->z - h_min[i]*normals[1].z;
      ptr_array_append_with_dtor(boundary_points, x2, polymec_free);
    }

    // Tag the boundary point appropriately.
    ptr_array_append(boundary_tags, tags); // Borrowed ref to tags.
  }

  // Move the surface points into a contiguous array.
  *boundary_generators = polymec_malloc(sizeof(point_t) * boundary_points->size);
  *num_boundary_generators = boundary_points->size;
  for (int i = 0; i < boundary_points->size; ++i)
  {
    (*boundary_generators)[i] = *((point_t*)boundary_points->data[i]);
  }

  // Transcribe the tags.
  *tag_names = polymec_malloc(sizeof(char*) * tag_indices->size);
  *tags = polymec_malloc(sizeof(int_array_t*) * tag_indices->size);
  *num_tags = tag_indices->size;
  char* tag_name;
  int pos = 0, tag_index;
  while (string_int_unordered_map_next(tag_indices, &pos, &tag_name, &tag_index))
  {
    (*tag_names)[tag_index] = string_dup(tag_name);
    (*tags)[tag_index] = int_array_new();
    for (int j = 0; j < *num_boundary_generators; ++j)
      int_array_append((*tags)[tag_index], tag_index);
  }

  // Clean up.
  string_int_unordered_map_free(tag_indices);
  polymec_free(h_min);
}
Example #10
0
amr_grid_t* amr_grid_new(MPI_Comm comm,
                         int nx, int ny, int nz, 
                         int px, int py, int pz, 
                         bool periodic_in_x, 
                         bool periodic_in_y, 
                         bool periodic_in_z)
{
  ASSERT(nx > 0);
  ASSERT(ny > 0);
  ASSERT(nz > 0);
  ASSERT(px > 0);
  ASSERT(py > 0);
  ASSERT(pz > 0);

  amr_grid_t* grid = polymec_malloc(sizeof(amr_grid_t));
  grid->nx = nx;
  grid->ny = ny;
  grid->nz = nz;
  grid->px = px;
  grid->py = py;
  grid->pz = pz;
  grid->x_periodic = periodic_in_x;
  grid->y_periodic = periodic_in_y;
  grid->z_periodic = periodic_in_z;
  grid->num_local_patches = 0;
  grid->local_patch_indices = NULL;
  grid->patch_types = polymec_malloc(sizeof(patch_type_t) * nx * ny * nz);
  grid->remote_owners = polymec_malloc(sizeof(int) * nx * ny * nz);
  grid->comm = comm;
  for (int i = 0; i < nx * ny * nz; ++i)
  {
    grid->patch_types[i] = NO_PATCH;
    grid->remote_owners[i] = -1;
  }

  grid->ref_ratio = 0;
  grid->coarser = NULL;
  grid->coarse_interpolator = NULL;
  grid->finer = NULL;
  grid->fine_interpolator = NULL;

  for (int n = 0; n < 6; ++n)
  {
    grid->neighbors[n] = NULL;
    grid->neighbor_interpolators[n] = NULL;
  }

  grid->finalized = false;
  grid->cell_ex = NULL;
  grid->x_face_ex = NULL;
  grid->y_face_ex = NULL;
  grid->z_face_ex = NULL;
  grid->x_edge_ex = NULL;
  grid->y_edge_ex = NULL;
  grid->z_edge_ex = NULL;
  grid->node_ex = NULL;

  for (int centering = 0; centering < 8; ++centering)
    grid->local_buffers[centering] = ptr_array_new();
  grid->pending_data = int_ptr_unordered_map_new();

  return grid;
}