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; }
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 */
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(); }
/*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*/