//============================================================================== /// Collects information about the cells of a given list. //============================================================================== JDivideCpu::StCellInfo JDivideCpu::GetCellInfoData(unsigned n,unsigned nct,unsigned *beginb,unsigned *beginf)const{ const char met[]="GetCellInfoData"; if(!nct)RunException(met,"There are no cells for analysis."); if(beginf[nct]==0)RunException(met,"The data do not provide a full neighbour list."); unsigned vmin=-1,nmin=0,vmax=0,nmax=0,suma=0,nsuma=0,nvoid=0; for(unsigned box=0;box<nct;box++){ unsigned count=(beginb[box+1]-beginb[box])+(beginf[box+1]-beginf[box]); if(count>0){ if(vmin>count||!nmin){ vmin=count; nmin=1; } else if(vmin==count)nmin++; if(vmax<count||!nmax){ vmax=count; nmax=1; } else if(vmax==count)nmax++; suma+=count; nsuma++; } else nvoid++; } StCellInfo celinfo; celinfo.cells_void=nvoid; celinfo.min_incell=vmin; celinfo.min_count=nmin; celinfo.max_incell=vmax; celinfo.max_count=nmax; celinfo.media=float(suma)/nsuma; return(celinfo); }
//============================================================================== /// Computes the Neighbour List of boundary particles (Npb). //============================================================================== void JDivideCpu::DivBoundary(const tfloat3 *pos){ const char met[]="DivBoundary"; BoundMaxCellZ=0; //-Initialise amount and position of particles per cell. memset(PartsInCell,0,sizeof(unsigned)*NctTotMax); //-Calculates the cell of each particle. for(unsigned p=0;p<Npb;p++){ float dx=pos[p].x-PosMin.x,dy=pos[p].y-PosMin.y,dz=pos[p].z-PosMin.z; if(dx<0||dy<0||dz<0||dx>=DifMax.x||dy>=DifMax.y||dz>=DifMax.z)RunException(met,"A boundary particle was found outside the domain."); unsigned cx=unsigned(dx*OvSizeCell),cy=unsigned(dy*OvSizeCell),cz=unsigned(dz*OvSizeCell); if(BoundMaxCellZ<cz)BoundMaxCellZ=cz; int box=cx+cy*Ncells.x+cz*Nsheet; CellPart[p]=box; PartsInCell[box]++;//-Number of particles of each cell. } //-Calculates the first boundary particle of each cell. BeginBound[0]=0; for(unsigned box=0;box<NctTotMax;box++){ BeginBound[box+1]=BeginBound[box]+PartsInCell[box]; PartsInCell[box]=0; } //-Addresses particles in their cells. for(unsigned p=0;p<Npb;p++){ unsigned box=CellPart[p]; Parts[BeginBound[box]+PartsInCell[box]]=p; PartsInCell[box]++; } CellInfoOk=false; Ndivb++; }
//============================================================================== /// Configuration of the Neighbour List: Memory allocation, domain and cells. //============================================================================== void JDivideCpu::Config(float sizecell,float incz,unsigned np,unsigned nfixed,unsigned nmoving,unsigned nfloat,unsigned nfluid,const tfloat3 *pos,float dp){ const char met[]="Config"; Reset(); string aux="**Initialising "; Log->Print(aux+ClassName); if(np<1)RunException(met,"Invalid number of particles."); if(sizecell<=0)RunException(met,"Invalid value for cell size."); Np=np; Nfixed=nfixed; Nmoving=nmoving; Nfloat=nfloat; Nfluid=nfluid; Nbound=Nfixed+Nmoving+Nfloat; if(Np!=Nbound+Nfluid)RunException(met,"Error in number of particles."); Npb=Nbound-Nfloat; SizeCell=sizecell; OvSizeCell=float(1.0/SizeCell); IncZ=incz; //-Allocates memory dependent on Np. try{ CellPart=new unsigned[Np]; Parts=new unsigned[Np]; VSort=(byte*)new byte[max(sizeof(tfloat3)*Np,sizeof(tsymatrix3f)*(Np-Npb))]; } catch(const std::bad_alloc){ RunException(met,"Could not allocate the requested memory."); } VSortInt=(int*)VSort; VSortFloat=(float*)VSort; VSortFloat3=(tfloat3*)VSort; VSortFloat6=(tsymatrix3f*)VSort; //-Calculates limits of the domain. tfloat3 pmin,pmax; CheckLimits(0,Np,pos,pmin,pmax); float mod=sizecell*0.05f; pmin.x-=mod; pmin.y-=mod; pmin.z-=mod; pmax.x+=mod; pmax.y+=mod; pmax.z+=mod; DifMax.x=pmax.x-pmin.x; DifMax.y=pmax.y-pmin.y; DifMax.z=pmax.z-pmin.z; CalcCells(); if(ShowCellsInfo){ char tx[128]; sprintf(tx,"Cells of the initial domain: %d x %d x %d (%d)",Ncells.x,Ncells.y,Ncells.z,(Ncells.x*Ncells.y*Ncells.z)); Log->Print(tx); } pmax.z=(pmax.z-pmin.z)*(IncZ+1.f)+pmin.z; PosMin=pmin; DifMax.x=pmax.x-pmin.x; DifMax.y=pmax.y-pmin.y; DifMax.z=pmax.z-pmin.z; CalcCells(); VisuLimits(); CellInfoOk=false; }
int _tmain(int argc, _TCHAR* argv[]) { if ( (argc > 2) && (_wcsicmp( argv[1], L"exception" ) == 0) ) { return RunException( _wtoi( argv[2] ) ); } const wchar_t RepeatingWstr[] = L"The daily news in Japanese is: \x6bce\x65e5\x306e\x30cb\x30e5\x30fc\x30b9."; const char RepeatingAstr[] = "The daily news in Spanish is: la noticia diaria."; HMODULE hMod = NULL; hMod = LoadLibrary( L"gdi32.dll" ); OutputDebugStringA( "I write an ASCII message." ); OutputDebugStringA( "Filler in ASCII." ); OutputDebugStringW( L"And now a Unicode one. \x02a7. Adiós!" ); // a tesh in the middle hMod = LoadLibrary( L"ws2_32.dll" ); FreeLibrary( hMod ); hMod = LoadLibrary( L"ws2_32.dll" ); OutputDebugStringA( "I write an ASCII message." ); OutputDebugStringW( L"a\x4e00\x6c34" L"Axyz_0123\xD834\xDD1E!?" ); OutputDebugStringW( L"And now a Unicode one. Bye!" ); hMod = LoadLibrary( L"tapi32.dll" ); // longer than a memory page wchar_t longWstr[ 5000 ] = L""; char longAstr[ 5000 ] = ""; size_t repWstrLen = wcslen( RepeatingWstr ); size_t repAstrLen = strlen( RepeatingAstr ); for ( int i = 0; i < (_countof( longWstr ) / _countof( RepeatingWstr )); i++ ) { size_t charsLeft = _countof( longWstr ) - (i * repWstrLen); wcscpy_s( &longWstr[ i * repWstrLen ], charsLeft, RepeatingWstr ); } for ( int i = 0; i < (_countof( longAstr ) / _countof( RepeatingAstr )); i++ ) { size_t charsLeft = _countof( longAstr ) - (i * repAstrLen); strcpy_s( &longAstr[ i * repAstrLen ], charsLeft, RepeatingAstr ); } OutputDebugStringA( longAstr ); OutputDebugStringW( longWstr ); return 0; }
//============================================================================== /// Allocates the memory necessary for each configuration. //============================================================================== void JDivideCpu::ConfigMemory(){ const char met[]="ConfigMemory"; ClearMemory(); try{ PartsInCell=new unsigned[NctTotMax]; BeginBound=new unsigned[NctTotMax+1]; BeginFluid=new unsigned[NctTotMax+1]; } catch(const std::bad_alloc){ RunException(met,"Could not allocate the requested memory."); } memset(BeginBound,0,sizeof(unsigned)*(NctTotMax+1)); memset(BeginFluid,0,sizeof(unsigned)*(NctTotMax+1)); }
//============================================================================== /// Computes the Neighbour List of fluid particles. //============================================================================== bool JDivideCpu::DivFluid(const unsigned* idp,const tfloat3* pos,const tfloat3* vel,const float* rhop,float time){ const char met[]="DivFluid"; bool modifdata=false; //-Checks limits and calculates the cell of each particle. FluidMaxCellZ=BoundMaxCellZ; unsigned outcountpre=OutCount; const unsigned pfin=Np-NfluidOut; for(unsigned p=Npb;p<pfin;p++){ float dx=pos[p].x-PosMin.x,dy=pos[p].y-PosMin.y,dz=pos[p].z-PosMin.z; bool partfloating=(Nfloat&&idp[p]<Nbound? true: false); //-Particle floating. Floating particles are in the same block as fluid ones. bool partin=(dx>=0&&dy>=0&&dz>=0&&dx<DifMax.x&&dy<DifMax.y&&dz<DifMax.z); //-Particle within the domain. bool partrhopout=(partin&&!partfloating&&RhopOut&&(rhop[p]<RhopOutMin||rhop[p]>RhopOutMax)); //-Particle excluded by \ref RhopOut. if(partin&&!partrhopout){ //-Within the domain and valid density. unsigned cx=unsigned(dx*OvSizeCell),cy=unsigned(dy*OvSizeCell),cz=unsigned(dz*OvSizeCell); if(FluidMaxCellZ<cz)FluidMaxCellZ=cz; CellPart[p]=cx+cy*Ncells.x+cz*Nsheet; } else{ //-Out of the domain and no-valid density. if(partfloating){ char tx[1024]; sprintf(tx,"particle floating out> p:%u id:%u pos:(%f,%f,%f)\n",p,idp[p],pos[p].x,pos[p].y,pos[p].z); Log->Print(tx); RunException(met,"A floating body particle was found outside the domain."); } if(OutCount>=int(OutSize))OutResize(min(max(unsigned(1000),unsigned(OutSize*2)),Nfluid)); StParticleOut* out=Out+OutCount; out->p=p; out->id=idp[p]; out->pos=pos[p]; out->vel=vel[p]; out->rhop=rhop[p]; out->timeout=time; OutCount++; if(partrhopout)RhopOutCount++; } } //-Adjust doamin in Z axis. if(LastMaxCellZ!=FluidMaxCellZ){ Ncells.z=FluidMaxCellZ+1; Nct=Nsheet*Ncells.z; NctTot=Nct+1; LastMaxCellZ=FluidMaxCellZ; modifdata=true; } //-Assigns cell Nct to the new Particles-Out. if(outcountpre<OutCount){ NOutLast=OutCount-outcountpre; for(unsigned c=outcountpre;c<OutCount;c++)CellPart[Out[c].p]=Nct; NfluidOut+=(OutCount-outcountpre); modifdata=true; } else NOutLast=0; //-Counts particles per cell. memset(PartsInCell,0,sizeof(int)*NctTot); for(unsigned p=Npb;p<pfin;p++)PartsInCell[CellPart[p]]++; //-Calculates the first fluid particle of each cell. BeginFluid[0]=Npb; for(unsigned box=0;box<NctTot;box++){ BeginFluid[box+1]=BeginFluid[box]+PartsInCell[box]; PartsInCell[box]=0; } //-Addresses particles in their cells. for(unsigned p=Npb;p<pfin;p++){ unsigned box=CellPart[p]; Parts[BeginFluid[box]+PartsInCell[box]]=p; PartsInCell[box]++; } CellInfoOk=false; Ndivf++; return(modifdata); }