//##################################################################### // Function Read //##################################################################### template<class T> void RGB_FILE<T>:: Read(const std::string& filename,ARRAY<VECTOR<T,3> ,VECTOR<int,2> >& image) { std::istream* input(FILE_UTILITIES::Safe_Open_Input(filename,true)); RGB_HEADER header;Read_Binary<T>(*input,header); image.Resize(1,header.width,1,header.height);unsigned char byte; if(!header.compression){ VECTOR<unsigned char,3> color_byte; for(int j=1;j<=image.counts.y;j++) for(int i=1;i<=image.counts.x;i++){Read_Binary<T>(*input,byte);image(i,j).x=IMAGE<T>::Byte_Color_To_Scalar_Color(byte);} for(int j=1;j<=image.counts.y;j++) for(int i=1;i<=image.counts.x;i++){Read_Binary<T>(*input,byte);image(i,j).y=IMAGE<T>::Byte_Color_To_Scalar_Color(byte);} for(int j=1;j<=image.counts.y;j++) for(int i=1;i<=image.counts.x;i++){Read_Binary<T>(*input,byte);image(i,j).z=IMAGE<T>::Byte_Color_To_Scalar_Color(byte);}} else{ unsigned char pixel,count;ARRAY<unsigned int> offset(header.height*header.channels),length(header.height*header.channels); unsigned int max_offset=0,max_offset_index=0; for(int k=1;k<=image.counts.y*header.channels;k++){Read_Binary<T>(*input,offset(k));Swap_Endianity(offset(k));if(offset(k)>max_offset){max_offset=offset(k);max_offset_index=k;}} for(int k=1;k<=image.counts.y*header.channels;k++){Read_Binary<T>(*input,length(k));Swap_Endianity(length(k));} // read the rest of the file into memory... ARRAY<unsigned char> data(offset(max_offset_index)+image.counts.y*2); int current_byte=512+image.counts.y*header.channels*2*4; while(current_byte<data.m) Read_Binary<T>(*input,data(current_byte++)); // unpack runs for(int band=1;band<=3;band++)for(int j=1;j<=image.counts.y;j++){ int index=offset(j+image.counts.y*(band-1)),end_index=index+length(j+image.counts.y*(band-1));int column=1; for(int i=1;index<end_index;i++){ pixel=data(index++);count=pixel & 0x7f;if(count==0) break; if(pixel & 0x80){for(int k=1;k<=count;k++){Read_Binary<T>(*input,byte);image(column,j)[band]=IMAGE<T>::Byte_Color_To_Scalar_Color(data(index++));column++;}} else{T float_pixel=IMAGE<T>::Byte_Color_To_Scalar_Color(data(index++));for(int k=1;k<=count;k++){image(column,j)[band]=float_pixel;column++;}}}}} delete input; }
//##################################################################### // Function Interpolate_From_Nodes_To_Cells //##################################################################### template<class T_GRID> template<class T2> void LINEAR_INTERPOLATION_DYADIC_HELPER<T_GRID>:: Interpolate_From_Nodes_To_Cells(const T_GRID& grid,const ARRAY<T2>& node_based,ARRAY<T2>& cell_based) { ARRAY<T_CELL*>& cell_pointer_from_index=grid.Cell_Pointer_From_Index();cell_based.Resize(grid.number_of_cells); for(int i=1;i<=grid.number_of_cells;i++){T_CELL* cell=cell_pointer_from_index(i);if(cell){ T2 sum=T2();for(int n=0;n<T_GRID::number_of_nodes_per_cell;n++)sum+=node_based(cell->Node(n)); cell_based(i)=sum/(T)T_GRID::number_of_nodes_per_cell;}} }
//##################################################################### // Function Constant_Extrapolate_RK2 //##################################################################### template<class TV,class T2> void EXTRAPOLATION_HIGHER_ORDER<TV,T2>:: Extrapolate_RK2(const MAPPING& m,const ARRAY<VECTOR<STENCIL,TV::m> >& stencil,ARRAY<T2>& u,const ARRAY<T2>* z,ARRAY<T2>& tmp,int o,T dt) { tmp.Resize(u.m); for(int i=m.max_solve_index(o)+1;i<=u.m;i++) tmp(i)=u(i); Extrapolate_FE(m,stencil,u,tmp,z,o,dt,1); Extrapolate_FE(m,stencil,tmp,u,z,o,dt,(T).5); }
//##################################################################### // Function Calculate_Node_Locations //##################################################################### template<class T> void RED_GREEN_GRID_3D<T>:: Calculate_Node_Locations(ARRAY<VECTOR<T,3> >& node_locations) const { node_locations.Resize(number_of_nodes,false,false); for(int i=1;i<=uniform_grid.counts.x;i++) for(int j=1;j<=uniform_grid.counts.y;j++) for(int ij=1;ij<=uniform_grid.counts.z;ij++) if(elements(i,j,ij)){ for(int n=0;n<4;n++) node_locations(elements(i,j,ij)->Node(n))=elements(i,j,ij)->Node_Location(n); elements(i,j,ij)->Interpolate_Node_Values_To_All_Children(node_locations);} }
//##################################################################### // Function Eigenvalues //##################################################################### template<class T,int bandwidth> void BANDED_SYMMETRIC_MATRIX<T,bandwidth>:: Eigenvalues(ARRAY<T>& eigenvalues) const { BANDED_SYMMETRIC_MATRIX D(*this); D.Diagonalize(); eigenvalues.Resize(Size(),false,false); for(int i=1;i<=Size();i++) eigenvalues(i)=D.A(i)[1]; }
//##################################################################### // Function Build_Mesh //##################################################################### template<class T> void RED_GREEN_GRID_3D<T>:: Build_Mesh(TETRAHEDRON_MESH& tetrahedron_mesh,const ARRAY<T>* phi,ARRAY<int>& cell_to_tetrahedron_mapping,ARRAY<int>* node_to_particle_mapping) const { tetrahedron_mesh.Clean_Memory(); cell_to_tetrahedron_mapping.Clean_Memory();cell_to_tetrahedron_mapping.Resize(number_of_cells); if(node_to_particle_mapping){node_to_particle_mapping->Clean_Memory();node_to_particle_mapping->Resize(number_of_nodes);} for(int i=1;i<=uniform_grid.counts.x;i++) for(int j=1;j<=uniform_grid.counts.y;j++) for(int ij=1;ij<=uniform_grid.counts.z;ij++) if(elements(i,j,ij)) elements(i,j,ij)->Build_Tetrahedron_Mesh(tetrahedron_mesh,phi,cell_to_tetrahedron_mapping,node_to_particle_mapping); tetrahedron_mesh.number_nodes=node_to_particle_mapping?node_to_particle_mapping->Max():number_of_nodes; }
//##################################################################### // Function Fill_un //##################################################################### template<class TV,class T2> void EXTRAPOLATION_HIGHER_ORDER<TV,T2>:: Fill_un(const MAPPING& m,const TV& one_over_dx,const ARRAY<TV>& normal,const ARRAY<T2>& x,ARRAY<T2>& xn,int o,int mo) { xn.Resize(m.max_solve_index(mo*2-o+1)); for(int i=m.max_solve_index(o+1)+1;i<=m.max_solve_index(mo*2-o+1);i++){ const TV_INT& index=m.index_to_node(i); T2 v=0; for(int d=1;d<=TV::m;d++){ TV_INT a=index,b=index;a(d)--;b(d)++; v+=(x(m.node_to_index(b))-x(m.node_to_index(a)))*(T).5*one_over_dx(d)*normal(i)(d);} xn(i)=v;} }
//##################################################################### // Function ISend_Columns //##################################################################### template<class T_GRID> template<class T_ARRAYS_HORIZONTAL_COLUMN> MPI::Request MPI_RLE_GRID<T_GRID>:: ISend_Columns(const T_ARRAYS_HORIZONTAL_COLUMN& columns,const ARRAY<T_BOX_HORIZONTAL_INT>& regions,const int neighbor,const int tag,ARRAY<char>& buffer) const { int buffer_size=MPI_UTILITIES::Pack_Size<TV_INT>(*comm); for(typename T_HORIZONTAL_GRID::CELL_ITERATOR iterator(local_grid.horizontal_grid,regions(neighbor)); iterator.Valid(); iterator.Next()) buffer_size+=MPI_UTILITIES::Pack_Size(columns(iterator.Cell_Index()),*comm); buffer.Resize(buffer_size); int position=0; MPI_UTILITIES::Pack(all_neighbor_directions(neighbor),buffer,position,*comm); for(typename T_HORIZONTAL_GRID::CELL_ITERATOR iterator(local_grid.horizontal_grid,regions(neighbor)); iterator.Valid(); iterator.Next()) MPI_UTILITIES::Pack(columns(iterator.Cell_Index()),buffer,position,*comm); return comm->Isend(&buffer(1),position,MPI::PACKED,all_neighbor_ranks(neighbor),tag); }
//##################################################################### // Function Read //##################################################################### template<class T> void BMP_FILE<T>:: Read(const std::string& filename,ARRAY<VECTOR<T,3> ,VECTOR<int,2> >& image) { std::istream* input=FILE_UTILITIES::Safe_Open_Input(filename); BMP_HEADER header;Read_Binary<T>(*input,header); image.Resize(1,header.w,1,header.h,false,false); int line_width=header.w*3,line_padding=((line_width+3)&~3)-line_width; input->seekg(header.offset,std::ios::beg); VECTOR<unsigned char,3> color_byte; for(int j=1;j<=header.h;j++){ for(int i=1;i<=header.w;i++){Read_Binary<T>(*input,color_byte);image(i,j)=IMAGE<T>::Byte_Color_To_Scalar_Color(VECTOR<unsigned char,3>(color_byte.z,color_byte.y,color_byte.x));} input->seekg(line_padding,std::ios::cur);} delete input; }
//##################################################################### // Function Calculate //##################################################################### template<class T> void Calculate(SEGMENTED_CURVE_2D<T>& curve,const GRID<VECTOR<T,2> >& grid,ARRAY<T,VECTOR<int,2> >& phi,bool print_progress) { bool bounding_box_defined=curve.bounding_box!=0;if(!bounding_box_defined) curve.Update_Bounding_Box(); phi.Resize(1,grid.counts.x,1,grid.counts.y); T epsilon=(T)1e-8*grid.min_dX; int total_cells=grid.counts.x*grid.counts.y,cells_done=0,progress=-1; for(int i=1;i<=grid.counts.x;i++) for(int j=1;j<=grid.counts.y;j++){ phi(i,j)=curve.Calculate_Signed_Distance(grid.X(i,j),epsilon); if(print_progress){ cells_done++;int new_progress=(int)((T)100*cells_done/total_cells); if(new_progress > progress){ #ifndef COMPILE_WITHOUT_READ_WRITE_SUPPORT LOG::cout<<new_progress<<"% "<<std::flush; #endif progress=new_progress;}}} #ifndef COMPILE_WITHOUT_READ_WRITE_SUPPORT if(print_progress) LOG::cout<<std::endl; #endif if(!bounding_box_defined){delete curve.bounding_box;curve.bounding_box=0;} }
//##################################################################### // Function Fill_Level //##################################################################### template<class TV,class T2> void EXTRAPOLATION_HIGHER_ORDER<TV,T2>:: Fill_Level(const GRID<TV>& grid,const T_LEVELSET& phi,int ghost,MAPPING& m,ARRAY<TV>& normal,ARRAY<VECTOR<STENCIL,TV::m> >& stencil,int order,T distance) { ARRAY<TV_INT> inside; m.node_to_index.Resize(grid.Domain_Indices(ghost+1)); // Need an extra ring for the sentinals m.index_to_node.Append(TV_INT::All_Ones_Vector()*INT_MAX); // First index is the "outside" index. normal.Append(TV::All_Ones_Vector()*INT_MAX); // Cells that must be solved for normally. for(UNIFORM_GRID_ITERATOR_NODE<TV> it(grid,ghost);it.Valid();it.Next()){ T p=phi.Phi(it.Location()); if(p<=0){ if(p>-(T)2.1*grid.dX.Max()){inside.Append(it.index);m.node_to_index(it.index)=-1;}} // Register two levels to prevent the closure below from leaking inside. else if(p<=(distance+(T)1e-4)*grid.dX.Max()) m.node_to_index(it.index)=m.index_to_node.Append(it.index);} // Ensure that two upwind nodes are being solved for. for(int i=2;i<=m.index_to_node.m;i++){ TV N=phi.Normal(grid.X(m.index_to_node(i))); normal.Append(N); for(int d=1;d<=TV::m;d++){ int s=N(d)<0?1:-1; TV_INT ind=m.index_to_node(i); for(int j=1;j<=2;j++){ ind(d)+=s; int& k=m.node_to_index(ind); if(!k) k=m.index_to_node.Append(ind);}}} m.max_solve_index(1)=m.index_to_node.m; // Register additional cells inside for derivatives. for(int o=1,i=1;o<=order*2;o++){ int previous=m.index_to_node.m,mx=inside.m; for(;i<=mx;i++){ bool added=false; for(int k=1;k<=TV::m*2;k++){ TV_INT ind=grid.Node_Neighbor(inside(i),k); int& n=m.node_to_index(ind); if(!n){n=-1;inside.Append(ind);} else if(n>0 && n<=previous && !added){ m.node_to_index(inside(i))=m.index_to_node.Append(inside(i)); normal.Append(phi.Normal(grid.X(inside(i)))); added=true;}} if(!added) inside.Append(TV_INT(inside(i)));} // Use a copy to avoid but on resize m.max_solve_index(o+1)=m.index_to_node.m;} // Register sentinal layer and precompute stencils. stencil.Resize(m.max_solve_index(order)); for(int i=2;i<=m.max_solve_index(order);i++){ TV N=normal(i); for(int d=1;d<=TV::m;d++){ int s=N(d)<0?1:-1; STENCIL& st=stencil(i)(d); st.scale=s*N(d)*grid.one_over_dX(d); TV_INT ind=m.index_to_node(i); for(int j=1;j<=3;j++){ st.nodes(j+1)=m.node_to_index(ind); ind(d)+=s;} ind(d)-=4*s; int& n=m.node_to_index(ind); if(!n) n=1; st.nodes(1)=n;}} }
template<class T_GRID,class T_BOX> static inline void Resize_Helper(ARRAY<int>& array,const T_GRID& grid,const T_BOX& box) { array.Resize(grid.Cell_Indices()); // for rle grids we have to allocate space for the entire grid due to the unstructuredness }