Пример #1
0
void RectangularMesh::
assign_material_id_in_cells(const TriangularMesh &tri_mesh)
{
  double t0 = get_wall_time();
  std::cout << "Assigning material IDs in cells..." << std::endl;

  _cells_ID = new int[_n_elements_x*_n_elements_z];

  const double x0 = _min_coord.x(); // limits in x-direction
  const double x1 = _max_coord.x();
  const double z0 = _min_coord.z(); // limits in z-direction
  const double z1 = _max_coord.z();
  const double hx = (x1 - x0) / _n_elements_x; // step in x-direction
  const double hz = (z1 - z0) / _n_elements_z; // step in z-direction

  const bool throw_exception = false;

  for (int iz = 0; iz < _n_elements_z; ++iz)
  {
    const double zcen = z0 + (iz+0.5)*hz; // z-coord of a cell center
    int triangle_index = 0; // reset the index from the previous search
    for (int ix = 0; ix < _n_elements_x; ++ix)
    {
      const double xcen = x0 + (ix+0.5)*hx; // x-coord of a cell center
      Point2 cell_center(xcen, zcen);
      require(tri_mesh.contains_point(cell_center), "The triangular mesh "
              "doesn't contain the point: " + d2s(cell_center));

      // every search along the x-line at the same z-coordinate starts with the
      // previously found triangle
      triangle_index = tri_mesh.find_element(cell_center,
                                             triangle_index,
                                             throw_exception);

      if (triangle_index < 0) // if it wasn't found
      {
        std::cout << "  full search for point " << cell_center << std::endl;
        triangle_index = tri_mesh.full_search(cell_center);
      }

      const int mat_ID = tri_mesh.element(triangle_index).material_id();
      _cells_ID[iz*_n_elements_x + ix] = mat_ID;
    }
  }

  std::cout << "Assigning material IDs in cells is done. Time = "
            << get_wall_time() - t0 << std::endl;
}
Пример #2
0
EXPORT  void  	rect_grid_center(
	const RECT_GRID	*rect_grid,
	const int 	*icoords,
	double 		*fcoords)
{
  	int 	i, dim = rect_grid->dim;

	for (i = 0; i < dim; ++i)
	{
	    if ((icoords[i] < 0) || (icoords[i] >= rect_grid->gmax[i]))
	    {
		screen("ERROR in rect_grid_center(), "
		       "center for icoords not on rect_grid:\n");
		print_int_vector("icoords = ",icoords,dim,"\n");
		print_RECT_GRID_structure(rect_grid);
		clean_up(ERROR);
	    }
	    fcoords[i] = cell_center(icoords[i],i,rect_grid);
	}
}		/* end rect_grid_center */
Пример #3
0
void Fluid::setupVBOs() {
  HandleGLError("in setup fluid VBOs");

  fluid_particles.clear();
  fluid_velocity_vis.clear();  
  fluid_face_velocity_vis.clear();
  fluid_pressure_vis.clear();
  fluid_cell_type_vis.clear();

  // =====================================================================================
  // setup the particles
  // =====================================================================================
  for (int x = 0; x < nx; x++) {
    for (int y = 0; y < ny; y++) {
      for (int z = 0; z < nz; z++) {
	Cell *cell = getCell(x,y,z);
	std::vector<FluidParticle*> &particles = cell->getParticles();
	for (unsigned int iter = 0; iter < particles.size(); iter++) {
	  FluidParticle *p = particles[iter];
	  Vec3f v = p->getPosition();
	  fluid_particles.push_back(VBOPos(v));
	}
      }
    }
  }

  // =====================================================================================
  // visualize the velocity
  // =====================================================================================
  if (args->dense_velocity == 0) {
    // one velocity vector per cell, at the centroid
    for (int i = 0; i < nx; i++) {
      for (int j = 0; j < ny; j++) {
	for (int k = 0; k < nz; k++) {
	  Vec3f cell_center((i+0.5)*dx,(j+0.5)*dy,(k+0.5)*dz);
	  Vec3f direction(get_u_avg(i,j,k),get_v_avg(i,j,k),get_w_avg(i,j,k));
	  Vec3f pt2 = cell_center+100*args->timestep*direction;
	  fluid_velocity_vis.push_back(VBOPosColor(cell_center,Vec3f(1,0,0)));
	  fluid_velocity_vis.push_back(VBOPosColor(pt2,Vec3f(1,1,1)));
	}
      }
    }
  } else if (args->dense_velocity == 1) {
    double z = nz*dz / 2.0;
    for (double x = 0; x <= (nx+0.01)*dx; x+=0.25*dx) {
      for (double y = 0; y <= (ny+0.01)*dy; y+=0.25*dy) {
	Vec3f vel = getInterpolatedVelocity(Vec3f(x,y,z));
	Vec3f pt1(x,y,z);
	Vec3f pt2 = pt1 + 100*args->timestep*vel;
	fluid_velocity_vis.push_back(VBOPosColor(pt1,Vec3f(1,0,0)));
	fluid_velocity_vis.push_back(VBOPosColor(pt2,Vec3f(1,1,1)));
      } 
    }
  } else if (args->dense_velocity == 2) {
    double y = ny*dy / 2.0;
    for (double x = 0; x <= (nx+0.01)*dx; x+=0.25*dx) {
      for (double z = 0; z <= (nz+0.01)*dz; z+=0.25*dz) {
	Vec3f vel = getInterpolatedVelocity(Vec3f(x,y,z));
	Vec3f pt1(x,y,z);
	Vec3f pt2 = pt1 + 100*args->timestep*vel;
	fluid_velocity_vis.push_back(VBOPosColor(pt1,Vec3f(1,0,0)));
	fluid_velocity_vis.push_back(VBOPosColor(pt2,Vec3f(1,1,1)));
      }
    } 
  } else if (args->dense_velocity == 3) {
    double x = nx*dx / 2.0;
    for (double y = 0; y <= (ny+0.01)*dy; y+=0.25*dy) {
      for (double z = 0; z <= (nz+0.01)*dz; z+=0.25*dz) {
	Vec3f vel = getInterpolatedVelocity(Vec3f(x,y,z));
	Vec3f pt1(x,y,z);
	Vec3f pt2 = pt1 + 100*args->timestep*vel;
	fluid_velocity_vis.push_back(VBOPosColor(pt1,Vec3f(1,0,0)));
	fluid_velocity_vis.push_back(VBOPosColor(pt2,Vec3f(1,1,1)));
      }
    } 
  }

  // =====================================================================================
  // visualize the face velocity
  // render stubby triangles to visualize the u, v, and w velocities between cell faces
  // =====================================================================================
  for (int i = 0; i < nx; i++) {
    for (int j = 0; j < ny; j++) {
      for (int k = 0; k < nz; k++) {
	double dt = args->timestep;
	double u = get_u_plus(i,j,k)*100*dt;
	double v = get_v_plus(i,j,k)*100*dt;
	double w = get_w_plus(i,j,k)*100*dt;
	double x = i*dx;
	double y = j*dy;
	double z = k*dz;
	if (u < -10*dt) {
	  Vec3f pts[5] = { Vec3f(x+dx+u,y+0.5*dy,z+0.5*dz),
			   Vec3f(x+dx,y+0.55*dy,z+0.55*dz),
			   Vec3f(x+dx,y+0.55*dy,z+0.45*dz),
			   Vec3f(x+dx,y+0.45*dy,z+0.45*dz),
			   Vec3f(x+dx,y+0.45*dy,z+0.55*dz) };
	  setupConeVBO(pts,Vec3f(1,0,0),fluid_face_velocity_vis);	  
	} else if (u > 10*dt) {
	  Vec3f pts[5] = { Vec3f(x+dx+u,y+0.5*dy,z+0.5*dz),
			   Vec3f(x+dx,y+0.45*dy,z+0.45*dz),
			   Vec3f(x+dx,y+0.55*dy,z+0.45*dz),
			   Vec3f(x+dx,y+0.55*dy,z+0.55*dz),
			   Vec3f(x+dx,y+0.45*dy,z+0.55*dz) };
	  setupConeVBO(pts,Vec3f(1,0,0),fluid_face_velocity_vis);	  
	}
	if (v < -10*dt) {
	  Vec3f pts[5] = { Vec3f(x+0.5*dx,y+dy+v,z+0.5*dz),
			   Vec3f(x+0.45*dx,y+dy,z+0.45*dz),
			   Vec3f(x+0.55*dx,y+dy,z+0.45*dz),
			   Vec3f(x+0.55*dx,y+dy,z+0.55*dz),
			   Vec3f(x+0.45*dx,y+dy,z+0.55*dz) };
	  setupConeVBO(pts,Vec3f(0,1,0),fluid_face_velocity_vis);	  
	} else if (v > 10*dt) {
	  Vec3f pts[5] = { Vec3f(x+0.5*dx,y+dy+v,z+0.5*dz),
			   Vec3f(x+0.55*dx,y+dy,z+0.55*dz),
			   Vec3f(x+0.55*dx,y+dy,z+0.45*dz),
			   Vec3f(x+0.45*dx,y+dy,z+0.45*dz),
			   Vec3f(x+0.45*dx,y+dy,z+0.55*dz) };
	  setupConeVBO(pts,Vec3f(0,1,0),fluid_face_velocity_vis);	  
	}
	if (w < -10*dt) {
	  Vec3f pts[5] = { Vec3f(x+0.5*dx,y+0.5*dy,z+dz+w),
			   Vec3f(x+0.55*dx,y+0.55*dy,z+dz),
			   Vec3f(x+0.55*dx,y+0.45*dy,z+dz),
			   Vec3f(x+0.45*dx,y+0.45*dy,z+dz),
			   Vec3f(x+0.45*dx,y+0.55*dy,z+dz) };
	  setupConeVBO(pts,Vec3f(0,0,1),fluid_face_velocity_vis);	  
	} else if (w > 10*dt) {
	  Vec3f pts[5] = { Vec3f(x+0.5*dx,y+0.5*dy,z+dz+w),
			   Vec3f(x+0.45*dx,y+0.45*dy,z+dz),
			   Vec3f(x+0.55*dx,y+0.45*dy,z+dz),
			   Vec3f(x+0.55*dx,y+0.55*dy,z+dz),
			   Vec3f(x+0.45*dx,y+0.55*dy,z+dz) };
	  setupConeVBO(pts,Vec3f(0,0,1),fluid_face_velocity_vis);	  
	}
      }
    }
  }

  // =====================================================================================
  // visualize the cell pressure
  // =====================================================================================
  for (int i = 0; i < nx; i++) {
    for (int j = 0; j < ny; j++) {
      for (int k = 0; k < nz; k++) {
	Vec3f pts[8] = { Vec3f((i+0.1)*dx,(j+0.1)*dy,(k+0.1)*dz),
			 Vec3f((i+0.1)*dx,(j+0.1)*dy,(k+0.9)*dz),
			 Vec3f((i+0.1)*dx,(j+0.9)*dy,(k+0.1)*dz),
			 Vec3f((i+0.1)*dx,(j+0.9)*dy,(k+0.9)*dz),
			 Vec3f((i+0.9)*dx,(j+0.1)*dy,(k+0.1)*dz),
			 Vec3f((i+0.9)*dx,(j+0.1)*dy,(k+0.9)*dz),
			 Vec3f((i+0.9)*dx,(j+0.9)*dy,(k+0.1)*dz),
			 Vec3f((i+0.9)*dx,(j+0.9)*dy,(k+0.9)*dz) };
          double p = getCell(i,j,k)->getPressure();
          p *= 0.1;
          if (p > 1) p = 1;
          if (p < -1) p = -1;
          assert(p >= -1 && p <= 1);
          Vec3f color;
	  if (p < 0) {
            color = Vec3f(1+p,1+p,1);
          } else {
            color = Vec3f(1,1-p,1-p);
          }
	  setupCubeVBO(pts,color,fluid_pressure_vis);
      }
    }
  }

  // =====================================================================================
  // render the MAC cells (FULL, SURFACE, or EMPTY)
  // =====================================================================================
  for (int i = 0; i < nx; i++) {
    for (int j = 0; j < ny; j++) {
      for (int k = 0; k < nz; k++) {
	Vec3f pts[8] = { Vec3f((i+0.1)*dx,(j+0.1)*dy,(k+0.1)*dz),
			 Vec3f((i+0.1)*dx,(j+0.1)*dy,(k+0.9)*dz),
			 Vec3f((i+0.1)*dx,(j+0.9)*dy,(k+0.1)*dz),
			 Vec3f((i+0.1)*dx,(j+0.9)*dy,(k+0.9)*dz),
			 Vec3f((i+0.9)*dx,(j+0.1)*dy,(k+0.1)*dz),
			 Vec3f((i+0.9)*dx,(j+0.1)*dy,(k+0.9)*dz),
			 Vec3f((i+0.9)*dx,(j+0.9)*dy,(k+0.1)*dz),
			 Vec3f((i+0.9)*dx,(j+0.9)*dy,(k+0.9)*dz) };
	Cell *cell = getCell(i,j,k);
	Vec3f color;
	if (cell->getStatus() == CELL_FULL) {
	  color = Vec3f(1,0,0);
	} else if (cell->getStatus() == CELL_SURFACE) {
	  color=Vec3f(0,0,1);
	} else {
	  continue;
	}
	setupCubeVBO(pts,color,fluid_cell_type_vis);
      }
    }
  }

  // cleanup old buffer data (if any)
  cleanupVBOs();

  // copy the data to each VBO
  glBindBuffer(GL_ARRAY_BUFFER,fluid_particles_VBO); 
  glBufferData(GL_ARRAY_BUFFER,sizeof(VBOPos)*fluid_particles.size(),&fluid_particles[0],GL_STATIC_DRAW); 
  if (fluid_velocity_vis.size() > 0) {
    glBindBuffer(GL_ARRAY_BUFFER,fluid_velocity_vis_VBO); 
    glBufferData(GL_ARRAY_BUFFER,sizeof(VBOPosColor)*fluid_velocity_vis.size(),&fluid_velocity_vis[0],GL_STATIC_DRAW); 
  }
  if (fluid_face_velocity_vis.size() > 0) {
    glBindBuffer(GL_ARRAY_BUFFER,fluid_face_velocity_vis_VBO); 
    glBufferData(GL_ARRAY_BUFFER,sizeof(VBOPosNormalColor)*fluid_face_velocity_vis.size(),&fluid_face_velocity_vis[0],GL_STATIC_DRAW); 
  }
  glBindBuffer(GL_ARRAY_BUFFER,fluid_pressure_vis_VBO); 
  glBufferData(GL_ARRAY_BUFFER,sizeof(VBOPosNormalColor)*fluid_pressure_vis.size(),&fluid_pressure_vis[0],GL_STATIC_DRAW); 
  glBindBuffer(GL_ARRAY_BUFFER,fluid_cell_type_vis_VBO); 
  glBufferData(GL_ARRAY_BUFFER,sizeof(VBOPosNormalColor)*fluid_cell_type_vis.size(),&fluid_cell_type_vis[0],GL_STATIC_DRAW); 

  HandleGLError("leaving setup fluid");

  // =====================================================================================
  // setup a marching cubes representation of the surface
  // =====================================================================================
  for (int i = 0; i <= nx; i++) {
    for (int j = 0; j <= ny; j++) {
      for (int k = 0; k <= nz; k++) {
	marchingCubes->set(i,j,k,interpolateIsovalue(Vec3f((i-0.5),(j-0.5),(k-0.5))));
      } 
    }
  }
  marchingCubes->setupVBOs();
}
Пример #4
0
/*ARGSUSED*/
EXPORT	void	get_state_1d_overlay(
	float		*coords,
	Locstate	s,
	COMP_TYPE	*ct,
	HYPER_SURF	*hs,
	INTERFACE	*intfc,
	INIT_DATA	*init,
	int		stype)
{
	ONED_OVERLAY	*olay = (ONED_OVERLAY*)ct->extra;
	INPUT_SOLN	**is = olay->is;
	RECT_GRID	*gr = &is[0]->grid;
	INTERFACE	*intfc1d = olay->intfc1d;
	float		x, coords1d[3], m, sp;
	float		dcoords[3];
	float		c0[3], c1[3];
	float		alpha;
	int		i0[3], i1[3], i, dim = ct->params->dim;
	int		nvars = olay->prt->n_restart_vars;
	static Locstate	s0 = 0, s1 = 0;

	debug_print("init_states","Entered get_state_1d_overlay()\n");
	if (s0 == NULL)
	{
	    (*ct->params->_alloc_state)(&s0,ct->params->sizest);
	    (*ct->params->_alloc_state)(&s1,ct->params->sizest);
	}

	for (i = 0; i < dim; ++i)
	    dcoords[i] = coords[i] - olay->origin[i];
	switch (olay->overlay_type)
	{
	case RADIAL_OVERLAY:
	    x = mag_vector(dcoords,dim);
	    break;
	case CYLINDRICAL_OVERLAY:
	    sp = scalar_product(dcoords,olay->direction,dim);
	    for (i = 0; i < dim; ++i)
	    	dcoords[i] -= sp*olay->direction[i];
	    x = mag_vector(dcoords,dim);
	    break;
	case RECTANGULAR_OVERLAY:
	    x = scalar_product(dcoords,olay->direction,dim);
	    break;
	case OVERLAY_TYPE_UNSET:
	default:
	    x = -HUGE_VAL;
	    screen("ERROR in get_state_1d_overlay(), unset overlay type\n");
	    clean_up(ERROR);
	    break;
	}
	if (x > gr->U[0])
	    x = gr->U[0];
	if (x < gr->L[0])
	    x = gr->L[0];
	coords1d[0] = x;
	if (rect_in_which(coords1d,i0,gr) == FUNCTION_FAILED)
	{
	    screen("ERROR in get_state_1d_overlay(), rect_in_which() failed\n");
	    print_general_vector("dcoords = ",dcoords,dim,"\n");
	    (void) printf("overlay type = %d, x = %g\n",olay->overlay_type,x);
	    (void) printf("rectangular grid gr\n");
	    print_rectangular_grid(gr);
	    (void) printf("One dimensional interface\n");
	    print_interface(intfc1d);
	    clean_up(ERROR);
	}
	c0[0] = cell_center(i0[0],0,gr);
	if (x < c0[0])
	{
	    i1[0] = i0[0];
	    i0[0]--;
	    if (i0[0] < 0)
		i0[0] = 0;
	    c1[0] = c0[0];
	    c0[0] = cell_center(i0[0],0,gr);
	}
	else
	{
	    i1[0] = i0[0] + 1;
	    if (i1[0] >= gr->gmax[0])
	    	i1[0] = i0[0];
	    c1[0] = cell_center(i1[0],0,gr);
	}
	if (component(c0,intfc1d) != ct->comp)
	{
	    set_oned_state_from_interface(c0,s0,ct,olay);
	}
	else
	{
	    g_restart_initializer(i0,nvars,ct->comp,is,s0,init);
	    Init_params(s0,ct->params);
	}
	if (component(c1,intfc1d) != ct->comp)
	{
	    set_oned_state_from_interface(c1,s1,ct,olay);
	}
	else
	{
	    g_restart_initializer(i1,nvars,ct->comp,is,s1,init);
	    Init_params(s1,ct->params);
	}
	alpha = (c1[0] > c0[0]) ? (x - c0[0])/(c1[0] - c0[0]) : 0.5;
	ct->params->dim = 1;
	interpolate_states(olay->front,1.0-alpha,alpha,c0,s0,c1,s1,s);
	ct->params->dim = dim;

	m = Mom(s)[0];
	switch (olay->overlay_type)
	{
	case RADIAL_OVERLAY:
	case CYLINDRICAL_OVERLAY:
	    if (x > 0.0)
	    {
	        for (i = 0; i < dim; ++i)
	    	    Mom(s)[i] = m*dcoords[i]/x;
	    }
	    else
	    {
	        for (i = 0; i < dim; ++i)
	    	    Mom(s)[i] = 0.0;
	    }
	    break;
	case RECTANGULAR_OVERLAY:
	    for (i = 0; i < dim; ++i)
	    	Mom(s)[i] = m*olay->direction[i];
	    break;
	case OVERLAY_TYPE_UNSET:
	default:
	    screen("ERROR in get_state_1d_overlay(), unset overlay type\n");
	    clean_up(ERROR);
	    break;
	}
	set_state(s,stype,s);
}		/*end get_state_1d_overlay*/