/* Carrega a rede. Arquivos devem estar no seguinte formato: * cada linha representa uma relacao: * userIndex userId N Ic Ip R * arquivo ordenado por ordem decrescente de * similaridade/dissimilaridade * */ void Network::load(char *netSimFile) { std::ifstream simFile, disFile; std::string line; std::string userIndex, userId, n, ic, ip, r; Neighbor ngb; unsigned int count; std::string lastUserIndex; /* carrega vizinhos mais similares */ simFile.open(netSimFile); if( !simFile.is_open() ) { std::cout << "\nError opening file!\n"; std::exit(-1); } count = 0; lastUserIndex = "0"; while(!simFile.eof()) { getline(simFile, line); if(simFile.eof()) break; /* separa os campos */ std::stringstream ss(line); ss>> userIndex, ss >> userId; ss >> n; ss >> ic; ss >> ip; ss >> r; if(userIndex != lastUserIndex) { count = 0; lastUserIndex = userIndex.c_str(); } if(++count <= this->numNeighbors) { ngb.init(atoi(userId.c_str()), atoi(n.c_str()), atof(ic.c_str()), atof(ip.c_str()), atof(r.c_str())); this->netSim[ atoi(userIndex.c_str()) ].push_back(ngb); } } simFile.close(); }
bool NbsTable::update(Neighbor nb) { m_nbs.lock(); auto insertResult = nbs.insert(std::make_pair<>(nb.getId(),nb)); bool isNewNb = insertResult.second; if (!isNewNb) { // Update element insertResult.first->second.setIp(nb.getIp()); insertResult.first->second.setLastSeen(std::chrono::system_clock::now()); } m_nbs.unlock(); return isNewNb; }
double KNN::calculateDistance(Neighbor a, Neighbor b) { double distance=0.0; vector<int> attrA, attrB; attrA = a.getInstance().getAttributes(); attrB = b.getInstance().getAttributes(); for(unsigned int i=0; i<attrA.size(); i++) distance += pow((attrA[i]-attrB[i]), 2); return sqrt(distance); }
void SmartBot::formNeighborhood() { //Serial.println(seenRobots->getSize()); while (!seenRobots->isEmpty()) if (true) { DllIter* iter = seenRobots->createIterator(); Neighbor* curMax = NULL; int curMaxIndex = 0; int maxVal = 0; while (iter->hasNext()) { Neighbor* next = iter->getNext(); int index = next->mostlySeenFrom(); if (next->receivedFrom[index] > maxVal) { maxVal = next->receivedFrom[index]; curMax = next; curMaxIndex = index; } } if (curMax != NULL && maxVal > 0) { if (neighbors[curMaxIndex] == NULL) { neighbors[curMaxIndex] = curMax; Serial.println("Removing from the DLL 1"); Serial.println(seenRobots->getSize()); //Serial.println(seenRobots->remove(*curMax)); //Serial.println(seenRobots->getSize()); } else { curMax->receivedFrom[curMaxIndex] = 0; if (curMax->mostlySeenFrom() < 0){ Serial.println("Removing from the DLL 2"); Serial.println(seenRobots->getSize()); //Serial.println(seenRobots->remove(*curMax)); //Serial.println(seenRobots->getSize()); } } } Serial.println("Almost DONE in formNeighbor"); delete iter; Serial.println("DONE in formNeighbor"); } }
void NeighborIdle::Execute(Entity* neighbor, FSM* fsm, float& elapsedTime) { // we aren't gonna do much yet. we may make him move around a // few tiles later Neighbor* self = (Neighbor*)neighbor; const int chanceOfMove = 1000; const int moveRange = 10; if (rand() % chanceOfMove == 1){ // move somewhere close //Vector2 test = self->GetPosition(); int x = self->GetPosition().x + (rand() % (moveRange * 2) - moveRange); int y = self->GetPosition().y + (rand() % (moveRange * 2) - moveRange); if (self->playField->isFreeTile(x, y)){ Tile* tile = self->playField->getTilePtr(x, y); fsm->SetCurrentState(new CharacterGoToTile(), tile); } } }
/******************* * Particle Methods * *******************/ float density_at_point(Vec3 point){ //first should generate a list of the particles we need to check, using the box for this point. int box_number = NEIGHBOR.compute_box_num(point,SUPPORT_RADIUS,CONTAINER.min.x,CONTAINER.max.x); Particle* temp_particle; vector<int> neighbor_vec = NEIGHBOR.box_particles[box_number]; float density = 0;//default_kernel(point,point); for (int i = 0; i<neighbor_vec.size(); i++){ //update density. There will be a problem if the point is exactly equal to sum particle (divide by zero error). temp_particle = PARTICLES[neighbor_vec[i]]; Vec3 diff_vec = point-temp_particle->position; float mag = dot(diff_vec,diff_vec); if(mag<H*H){ density += temp_particle->mass*default_kernel(point,temp_particle->position); } } return density; }
void Integrate::run(Atom &atom, Force* force, Neighbor &neighbor, Comm &comm, Thermo &thermo, Timer &timer) { int i, n; comm.timer = &timer; timer.array[TIME_TEST] = 0.0; int check_safeexchange = comm.check_safeexchange; mass = atom.mass; dtforce = dtforce / mass; //Use OpenMP threads only within the following loop containing the main loop. //Do not use OpenMP for setup and postprocessing. #pragma omp parallel private(i,n) { for(n = 0; n < ntimes; n++) { #pragma omp barrier x = &atom.x[0][0]; v = &atom.v[0][0]; f = &atom.f[0][0]; xold = &atom.xold[0][0]; nlocal = atom.nlocal; initialIntegrate(); #pragma omp barrier #pragma omp master timer.stamp(); if((n + 1) % neighbor.every) { #pragma omp barrier comm.communicate(atom); #pragma omp master timer.stamp(TIME_COMM); #pragma omp barrier } else { //these routines are not yet ported to OpenMP { if(check_safeexchange) { #pragma omp master { double d_max = 0; for(i = 0; i < atom.nlocal; i++) { double dx = (x[3 * i + 0] - xold[3 * i + 0]); if(dx > atom.box.xprd) dx -= atom.box.xprd; if(dx < -atom.box.xprd) dx += atom.box.xprd; double dy = (x[3 * i + 1] - xold[3 * i + 1]); if(dy > atom.box.yprd) dy -= atom.box.yprd; if(dy < -atom.box.yprd) dy += atom.box.yprd; double dz = (x[3 * i + 2] - xold[3 * i + 2]); if(dz > atom.box.zprd) dz -= atom.box.zprd; if(dz < -atom.box.zprd) dz += atom.box.zprd; double d = dx * dx + dy * dy + dz * dz; if(d > d_max) d_max = d; } d_max = sqrt(d_max); if((d_max > atom.box.xhi - atom.box.xlo) || (d_max > atom.box.yhi - atom.box.ylo) || (d_max > atom.box.zhi - atom.box.zlo)) printf("Warning: Atoms move further than your subdomain size, which will eventually cause lost atoms.\n" "Increase reneighboring frequency or choose a different processor grid\n" "Maximum move distance: %lf; Subdomain dimensions: %lf %lf %lf\n", d_max, atom.box.xhi - atom.box.xlo, atom.box.yhi - atom.box.ylo, atom.box.zhi - atom.box.zlo); } } //int tid = omp_get_thread_num(); //printf("Check B: %i %i %i\n",comm.me,tid,n); #pragma omp master timer.stamp_extra_start(); comm.exchange(atom); comm.borders(atom); #pragma omp master { timer.stamp_extra_stop(TIME_TEST); timer.stamp(TIME_COMM); } if(check_safeexchange) for(int i = 0; i < 3 * atom.nlocal; i++) atom.xold[i] = atom.x[i]; } #pragma omp barrier neighbor.build(atom); #pragma omp barrier #pragma omp master timer.stamp(TIME_NEIGH); } force->evflag = (n + 1) % thermo.nstat == 0; force->compute(atom, neighbor, comm, comm.me); #pragma omp master timer.stamp(TIME_FORCE); if(neighbor.halfneigh && neighbor.ghost_newton) { comm.reverse_communicate(atom); #pragma omp master timer.stamp(TIME_COMM); } v = &atom.v[0][0]; f = &atom.f[0][0]; nlocal = atom.nlocal; #pragma omp barrier finalIntegrate(); #pragma omp barrier if(thermo.nstat) thermo.compute(n + 1, atom, neighbor, force, timer, comm); } } //end OpenMP parallel }
void Atom::sort(Neighbor &neighbor) { neighbor.binatoms(*this,nlocal); #pragma omp barrier binpos = neighbor.bincount; bins = neighbor.bins; const int mbins = neighbor.mbins; const int atoms_per_bin = neighbor.atoms_per_bin; #pragma omp master { for(int i=1; i<mbins; i++) binpos[i] += binpos[i-1]; if(copy_size<nmax) { destroy_2d_MMD_float_array(x_copy); destroy_2d_MMD_float_array(v_copy); destroy_1d_int_array(type_copy); x_copy = (MMD_float*) create_2d_MMD_float_array(nmax, PAD); v_copy = (MMD_float*) create_2d_MMD_float_array(nmax, PAD); type_copy = create_1d_int_array(nmax); copy_size = nmax; } } #pragma omp barrier MMD_float* new_x = x_copy; MMD_float* new_v = v_copy; int* new_type = type_copy; MMD_float* old_x = x; MMD_float* old_v = v; int* old_type = type; #pragma omp for for(int mybin = 0; mybin<mbins; mybin++) { const int start = mybin>0?binpos[mybin-1]:0; const int count = binpos[mybin] - start; for(int k=0; k<count; k++) { const int new_i = start+k; const int old_i = bins[mybin*atoms_per_bin+k]; new_x[new_i*PAD+0] = old_x[old_i*PAD+0]; new_x[new_i*PAD+1] = old_x[old_i*PAD+1]; new_x[new_i*PAD+2] = old_x[old_i*PAD+2]; new_v[new_i*PAD+0] = old_v[old_i*PAD+0]; new_v[new_i*PAD+1] = old_v[old_i*PAD+1]; new_v[new_i*PAD+2] = old_v[old_i*PAD+2]; new_type[new_i] = old_type[old_i]; } } #pragma omp master { MMD_float* x_tmp = x; MMD_float* v_tmp = v; int* type_tmp = type; x = x_copy; v = v_copy; type = type_copy; x_copy = x_tmp; v_copy = v_tmp; type_copy = type_tmp; } #pragma omp barrier }
int main(int argc, char **argv) { //Common miniMD settings In in; in.datafile = NULL; int me=0; //local MPI rank int nprocs=1; //number of MPI ranks int num_threads=32; //number of Threads per Block threads int num_steps=-1; //number of timesteps (if -1 use value from lj.in) int system_size=-1; //size of the system (if -1 use value from lj.in) int check_safeexchange=0; //if 1 complain if atom moves further than 1 subdomain length between exchanges int do_safeexchange=0; //if 1 use safe exchange mode [allows exchange over multiple subdomains] int use_sse=0; //setting for SSE variant of miniMD only int screen_yaml=0; //print yaml output to screen also int yaml_output=0; //print yaml output int halfneigh=0; //1: use half neighborlist; 0: use full neighborlist; -1: use original miniMD version half neighborlist force char* input_file = NULL; int ghost_newton = 0; int skip_gpu = 999; int neighbor_size = -1; //OpenCL specific int platform = 0; int device = 0; int subdevice = -1; int ppn = 2; int use_tex = 0; int threads_per_atom = 1; int map_device=0; for(int i = 0; i < argc; i++) { if((strcmp(argv[i], "-i") == 0) || (strcmp(argv[i], "--input_file") == 0)) { input_file = argv[++i]; continue; } if((strcmp(argv[i],"-p")==0)||(strcmp(argv[i],"--platform")==0)) {platform=atoi(argv[++i]); continue;} if((strcmp(argv[i],"-d")==0)||(strcmp(argv[i],"--device")==0)) {device=atoi(argv[++i]); continue;} if((strcmp(argv[i],"-sd")==0)||(strcmp(argv[i],"--subdevice")==0)) {subdevice=atoi(argv[++i]); continue;} if((strcmp(argv[i],"-sd_map")==0)||(strcmp(argv[i],"--subdevice_mapping")==0)) {subdevice=1-me%ppn; continue;} if((strcmp(argv[i],"-ng")==0)||(strcmp(argv[i],"--num_gpus")==0)) {ppn=atoi(argv[++i]); continue;} if((strcmp(argv[i],"-dm")==0)||(strcmp(argv[i],"--device_map")==0)) {map_device=1; continue;} } MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &me); MPI_Comm_size(MPI_COMM_WORLD, &nprocs); if(map_device) {device = me%ppn; if(device>=skip_gpu) device++;} OpenCLWrapper* opencl = new OpenCLWrapper; if( me == 0) printf("# Platforms: %i\n",opencl->num_platforms); printf("# Proc: %i using device %i\n",me,device); opencl->Init(argc,argv,device,device+1,NULL,platform,subdevice); int error = 0; if(input_file == NULL) error = input(in, "in.lj.miniMD"); else error = input(in, input_file); if (error) { MPI_Finalize(); exit(0); } for(int i=0;i<argc;i++) { if((strcmp(argv[i],"-t")==0)||(strcmp(argv[i],"--num_threads")==0)) {num_threads=atoi(argv[++i]); continue;} if((strcmp(argv[i],"-n")==0)||(strcmp(argv[i],"--nsteps")==0)) {num_steps=atoi(argv[++i]); continue;} if((strcmp(argv[i],"-s")==0)||(strcmp(argv[i],"--size")==0)) {system_size=atoi(argv[++i]); continue;} if((strcmp(argv[i],"--half_neigh")==0)) {halfneigh=atoi(argv[++i]); continue;} if((strcmp(argv[i],"-sse")==0)) {use_sse=atoi(argv[++i]); continue;} if((strcmp(argv[i],"--check_exchange")==0)) {check_safeexchange=1; continue;} if((strcmp(argv[i],"-o")==0)||(strcmp(argv[i],"--yaml_output")==0)) {yaml_output=atoi(argv[++i]); continue;} if((strcmp(argv[i],"--yaml_screen")==0)) {screen_yaml=1; continue;} if((strcmp(argv[i], "-f") == 0) || (strcmp(argv[i], "--data_file") == 0)) { if(in.datafile == NULL) in.datafile = new char[1000]; strcpy(in.datafile, argv[++i]); continue; } if((strcmp(argv[i], "-u") == 0) || (strcmp(argv[i], "--units") == 0)) { in.units = strcmp(argv[++i], "metal") == 0 ? 1 : 0; continue; } if((strcmp(argv[i], "-p") == 0) || (strcmp(argv[i], "--force") == 0)) { in.forcetype = strcmp(argv[++i], "eam") == 0 ? FORCEEAM : FORCELJ; continue; } if((strcmp(argv[i], "-gn") == 0) || (strcmp(argv[i], "--ghost_newton") == 0)) { ghost_newton = atoi(argv[++i]); continue; } if((strcmp(argv[i], "--skip_gpu") == 0)) { skip_gpu = atoi(argv[++i]); continue; } if((strcmp(argv[i], "-b") == 0) || (strcmp(argv[i], "--neigh_bins") == 0)) { neighbor_size = atoi(argv[++i]); continue; } if((strcmp(argv[i],"-tex")==0)||(strcmp(argv[i],"--texture")==0)) {use_tex=atoi(argv[++i]); continue;} if((strcmp(argv[i],"-tpa")==0)) {threads_per_atom=atoi(argv[++i]); continue;} if((strcmp(argv[i],"-h")==0)||(strcmp(argv[i],"--help")==0)) { printf("\n---------------------------------------------------------\n"); printf("-------------" VARIANT_STRING "------------\n"); printf("---------------------------------------------------------\n\n"); printf("miniMD is a simple, parallel molecular dynamics (MD) code,\n" "which is part of the Mantevo project at Sandia National\n" "Laboratories ( http://www.mantevo.org ).\n" "The original authors of MPI based miniMD are Steve Plimpton ([email protected]) ,\n" "Paul Crozier ([email protected]) with current versions \n" "written by Christian Trott ([email protected]).\n\n"); printf("Commandline Options:\n"); printf("\n Execution configuration:\n"); printf("\t-t / --num_threads <threads>: set number of threads per block (default 32)\n"); printf("\t--half_neigh <int>: use half neighborlists (default 0)\n" "\t 0: full neighborlist\n" "\t 1: half neighborlist (not supported in OpenCL variant)\n" "\t -1: original miniMD half neighborlist force \n" "\t (not supported in OpenCL variant)\n"); printf("\t-d / --device <int>: select device (default 0)\n"); printf("\t-dm / --device_map: map devices to MPI ranks\n"); printf("\t-ng / --num_gpus <int>: give number of GPUs per Node (used in conjuction with -dm\n" "\t to determine device id: 'id=mpi_rank%%ng' (default 2)\n"); printf("\t--skip_gpu <int>: skip the specified gpu when assigning devices to MPI ranks\n" "\t used in conjunction with -dm (but must come first in arg list)\n"); printf("\t-p / --platform <int>: select platform (default 0)\n"); printf("\t-sse <sse_version>: use explicit sse intrinsics (use miniMD-SSE variant)\n"); printf("\t-gn / --ghost_newton <int>: set usage of newtons third law for ghost atoms\n" "\t (only applicable with half neighborlists)\n"); printf("\n Simulation setup:\n"); printf("\t-i / --input_file <string>: set input file to be used (default: in.lj.miniMD)\n"); printf("\t-n / --nsteps <nsteps>: set number of timesteps for simulation\n"); printf("\t-s / --size <size>: set linear dimension of systembox and neighbor bins\n"); printf("\t-b / --neigh_bins <int>: set linear dimension of neighbor bin grid\n"); printf("\t-u / --units <string>: set units (lj or metal), see LAMMPS documentation\n"); printf("\t-p / --force <string>: set interaction model (lj or eam)\n"); printf("\t-f / --data_file <string>: read configuration from LAMMPS data file\n"); printf("\n Miscelaneous:\n"); printf("\t--check_exchange: check whether atoms moved further than subdomain width\n"); printf("\t--safe_exchange: perform exchange communication with all MPI processes\n" "\t within rcut_neighbor (outer force cutoff)\n"); printf("\t--yaml_output <int>: level of yaml output (default 0)\n"); printf("\t--yaml_screen: write yaml output also to screen\n"); printf("\t-tex / --texture <int>: use texture cache in force kernel (default 0)\n"); printf("\t-h / --help: display this help message\n\n"); printf("---------------------------------------------------------\n\n"); exit(0); } } Atom atom; Force force; Neighbor neighbor; Integrate integrate; Thermo thermo; Comm comm; Timer timer; ThreadData threads; if(in.forcetype == FORCEEAM) { printf("ERROR: " VARIANT_STRING " does not yet support EAM simulations. Exiting.\n"); MPI_Finalize(); exit(0); } if(ghost_newton!=0) { if(me ==0 ) printf("ERROR: -ghost_newton %i is not supported in " VARIANT_STRING ". Exiting.\n",ghost_newton); MPI_Finalize(); exit(0); } if(halfneigh!=0) { if(me ==0 ) printf("ERROR: -half_neigh %i is not supported in " VARIANT_STRING ". Exiting.\n",halfneigh); MPI_Finalize(); exit(0); } if(halfneigh!=0) { if(me ==0 ) printf("ERROR: -half_neigh %i is not supported in " VARIANT_STRING ". Exiting.\n",halfneigh); MPI_Finalize(); exit(0); } if(use_tex!=0) { if(me ==0 ) printf("ERROR: -tex %i is currently broken. Exiting.\n",use_tex); MPI_Finalize(); exit(0); } if(use_sse) { #ifndef VARIANT_SSE if(me ==0 ) printf("ERROR: Trying to run with -sse with miniMD reference version. Use SSE variant instead. Exiting.\n"); MPI_Finalize(); exit(0); #endif } threads.mpi_me=me; threads.mpi_num_threads=nprocs; threads.omp_me=0; threads.omp_num_threads=num_threads; atom.threads = &threads; comm.threads = &threads; force.threads = &threads; integrate.threads = &threads; neighbor.threads = &threads; thermo.threads = &threads; opencl->blockdim = num_threads; atom.threads_per_atom = threads_per_atom; atom.use_tex = use_tex; comm.do_safeexchange=do_safeexchange; force.use_sse=use_sse; neighbor.halfneigh=halfneigh; compile_kernels(opencl); integrate.opencl = opencl; force.opencl = opencl; neighbor.opencl = opencl; atom.opencl = opencl; comm.opencl = opencl; if(num_steps > 0) in.ntimes = num_steps; if(system_size > 0) { in.nx = system_size; in.ny = system_size; in.nz = system_size; } if(neighbor_size > 0) { neighbor.nbinx = neighbor_size; neighbor.nbiny = neighbor_size; neighbor.nbinz = neighbor_size; } if(neighbor_size < 0 && in.datafile == NULL) { MMD_float neighscale = 5.0 / 6.0; neighbor.nbinx = neighscale * in.nx; neighbor.nbiny = neighscale * in.ny; neighbor.nbinz = neighscale * in.ny; } if(neighbor_size < 0 && in.datafile) neighbor.nbinx = -1; if(neighbor.nbinx == 0) neighbor.nbinx = 1; if(neighbor.nbiny == 0) neighbor.nbiny = 1; if(neighbor.nbinz == 0) neighbor.nbinz = 1; integrate.ntimes = in.ntimes; integrate.dt = in.dt; neighbor.every = in.neigh_every; neighbor.cutneigh = in.neigh_cut; force.cutforce = in.force_cut; thermo.nstat = in.thermo_nstat; if(me == 0) printf("# Create System:\n"); if(in.datafile) { read_lammps_data(atom, comm, neighbor, integrate, thermo, in.datafile, in.units); MMD_float volume = atom.box.xprd * atom.box.yprd * atom.box.zprd; in.rho = 1.0 * atom.natoms / volume; force.setup(); } else { create_box(atom, in.nx, in.ny, in.nz, in.rho); comm.setup(neighbor.cutneigh, atom); neighbor.setup(atom); integrate.setup(); force.setup(); create_atoms(atom, in.nx, in.ny, in.nz, in.rho); thermo.setup(in.rho, integrate, atom, in.units); create_velocity(in.t_request, atom, thermo); } if(me == 0) printf("# Done .... \n"); if(me == 0) { fprintf(stdout, "# " VARIANT_STRING " output ...\n"); fprintf(stdout, "# Systemparameters: \n"); fprintf(stdout, "\t# MPI processes: %i\n", neighbor.threads->mpi_num_threads); fprintf(stdout, "\t# OpenMP threads: %i\n", neighbor.threads->omp_num_threads); fprintf(stdout, "\t# Inputfile: %s\n", input_file == 0 ? "in.lj.miniMD" : input_file); fprintf(stdout, "\t# Datafile: %s\n", in.datafile ? in.datafile : "None"); fprintf(stdout, "\t# ForceStyle: %s\n", in.forcetype == FORCELJ ? "LJ" : "EAM"); fprintf(stdout, "\t# Units: %s\n", in.units == 0 ? "LJ" : "METAL"); fprintf(stdout, "\t# Atoms: %i\n", atom.natoms); fprintf(stdout, "\t# System size: %2.2lf %2.2lf %2.2lf (unit cells: %i %i %i)\n", atom.box.xprd, atom.box.yprd, atom.box.zprd, in.nx, in.ny, in.nz); fprintf(stdout, "\t# Density: %lf\n", in.rho); fprintf(stdout, "\t# Force cutoff: %lf\n", force.cutforce); fprintf(stdout, "\t# Neigh cutoff: %lf\n", neighbor.cutneigh); fprintf(stdout, "\t# Half neighborlists: %i\n", neighbor.halfneigh); fprintf(stdout, "\t# Neighbor bins: %i %i %i\n", neighbor.nbinx, neighbor.nbiny, neighbor.nbinz); fprintf(stdout, "\t# Neighbor frequency: %i\n", neighbor.every); fprintf(stdout, "\t# Timestep size: %lf\n", integrate.dt); fprintf(stdout, "\t# Thermo frequency: %i\n", thermo.nstat); fprintf(stdout, "\t# Ghost Newton: %i\n", ghost_newton); fprintf(stdout, "\t# Use SSE intrinsics: %i\n", force.use_sse); fprintf(stdout, "\t# Do safe exchange: %i\n", comm.do_safeexchange); fprintf(stdout, "\t# Size of float: %i\n\n",sizeof(MMD_float)); } comm.exchange(atom); comm.borders(atom); atom.d_x->upload(); atom.d_v->upload(); //atom.d_vold->upload(); neighbor.build(atom); if (me == 0) printf("# Starting dynamics ...\n"); if (me == 0) printf("# Timestep T U P Time\n"); thermo.compute(0,atom,neighbor,force,timer,comm); force.compute(atom,neighbor,comm.me); timer.barrier_start(TIME_TOTAL); integrate.run(atom,force,neighbor,comm,thermo,timer); timer.barrier_stop(TIME_TOTAL); int natoms; MPI_Allreduce(&atom.nlocal,&natoms,1,MPI_INT,MPI_SUM,MPI_COMM_WORLD); thermo.compute(-1,atom,neighbor,force,timer,comm); if(me == 0) { double time_other=timer.array[TIME_TOTAL]-timer.array[TIME_FORCE]-timer.array[TIME_NEIGH]-timer.array[TIME_COMM]; printf("\n\n"); printf("# Performance Summary:\n"); printf("# MPI_proc OMP_threads nsteps natoms t_total t_force t_neigh t_comm t_other performance perf/thread grep_string t_extra\n"); printf("%i %i %i %i %lf %lf %lf %lf %lf %lf %lf PERF_SUMMARY %lf\n\n\n", nprocs,num_threads,integrate.ntimes,natoms, timer.array[TIME_TOTAL],timer.array[TIME_FORCE],timer.array[TIME_NEIGH],timer.array[TIME_COMM],time_other, 1.0*natoms*integrate.ntimes/timer.array[TIME_TOTAL],1.0*natoms*integrate.ntimes/timer.array[TIME_TOTAL]/nprocs/num_threads,timer.array[TIME_TEST]); } if(yaml_output) output(in,atom,force,neighbor,comm,thermo,integrate,timer,screen_yaml); MPI_Barrier(MPI_COMM_WORLD); MPI_Finalize(); delete opencl; return 0; }
bool compare(Neighbor a, Neighbor b) { return a.getDistance() < b.getDistance(); }
otError DataPollManager::SendDataPoll(void) { otError error; Message * message; Neighbor *parent; VerifyOrExit(mEnabled, error = OT_ERROR_INVALID_STATE); VerifyOrExit(!Get<Mac::Mac>().GetRxOnWhenIdle(), error = OT_ERROR_INVALID_STATE); parent = Get<Mle::MleRouter>().GetParentCandidate(); VerifyOrExit((parent != NULL) && parent->IsStateValidOrRestoring(), error = OT_ERROR_INVALID_STATE); mTimer.Stop(); for (message = Get<MeshForwarder>().GetSendQueue().GetHead(); message; message = message->GetNext()) { VerifyOrExit(message->GetType() != Message::kTypeMacDataPoll, error = OT_ERROR_ALREADY); } message = Get<MessagePool>().New(Message::kTypeMacDataPoll, 0); VerifyOrExit(message != NULL, error = OT_ERROR_NO_BUFS); error = Get<MeshForwarder>().SendMessage(*message); if (error != OT_ERROR_NONE) { message->Free(); } exit: switch (error) { case OT_ERROR_NONE: otLogDebgMac("Sending data poll"); if (mNoBufferRetxMode == true) { mNoBufferRetxMode = false; ScheduleNextPoll(kRecalculatePollPeriod); } else { ScheduleNextPoll(kUsePreviousPollPeriod); } break; case OT_ERROR_INVALID_STATE: otLogWarnMac("Data poll tx requested while data polling was not enabled!"); StopPolling(); break; case OT_ERROR_ALREADY: otLogDebgMac("Data poll tx requested when a previous data request still in send queue."); ScheduleNextPoll(kUsePreviousPollPeriod); break; case OT_ERROR_NO_BUFS: default: mNoBufferRetxMode = true; ScheduleNextPoll(kRecalculatePollPeriod); break; } return error; }
int main(int argc, char** argv) { In in; in.datafile = NULL; int me = 0; //local MPI rank int nprocs = 1; //number of MPI ranks int num_threads = 1; //number of OpenMP threads int num_steps = -1; //number of timesteps (if -1 use value from lj.in) int system_size = -1; //size of the system (if -1 use value from lj.in) int nx = -1; int ny = -1; int nz = -1; int check_safeexchange = 0; //if 1 complain if atom moves further than 1 subdomain length between exchanges int do_safeexchange = 0; //if 1 use safe exchange mode [allows exchange over multiple subdomains] int use_sse = 0; //setting for SSE variant of miniMD only int screen_yaml = 0; //print yaml output to screen also int yaml_output = 0; //print yaml output int halfneigh = 1; //1: use half neighborlist; 0: use full neighborlist; -1: use original miniMD version half neighborlist force int teams = 1; int device = 0; int neighbor_size = -1; char* input_file = NULL; int ghost_newton = 1; int sort = -1; for(int i = 0; i < argc; i++) { if((strcmp(argv[i], "-i") == 0) || (strcmp(argv[i], "--input_file") == 0)) { input_file = argv[++i]; continue; } } MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &me); MPI_Comm_size(MPI_COMM_WORLD, &nprocs); int error = 0; if(input_file == NULL) error = input(in, "in.lj.miniMD"); else error = input(in, input_file); if(error) { MPI_Finalize(); exit(0); } for(int i = 0; i < argc; i++) { if((strcmp(argv[i], "-t") == 0) || (strcmp(argv[i], "--num_threads") == 0)) { num_threads = atoi(argv[++i]); continue; } if((strcmp(argv[i], "--teams") == 0)) { teams = atoi(argv[++i]); continue; } if((strcmp(argv[i], "-n") == 0) || (strcmp(argv[i], "--nsteps") == 0)) { num_steps = atoi(argv[++i]); continue; } if((strcmp(argv[i], "-s") == 0) || (strcmp(argv[i], "--size") == 0)) { system_size = atoi(argv[++i]); continue; } if((strcmp(argv[i], "-nx") == 0)) { nx = atoi(argv[++i]); continue; } if((strcmp(argv[i], "-ny") == 0)) { ny = atoi(argv[++i]); continue; } if((strcmp(argv[i], "-nz") == 0)) { nz = atoi(argv[++i]); continue; } if((strcmp(argv[i], "-b") == 0) || (strcmp(argv[i], "--neigh_bins") == 0)) { neighbor_size = atoi(argv[++i]); continue; } if((strcmp(argv[i], "--half_neigh") == 0)) { halfneigh = atoi(argv[++i]); continue; } if((strcmp(argv[i], "-sse") == 0)) { use_sse = atoi(argv[++i]); continue; } if((strcmp(argv[i], "--check_exchange") == 0)) { check_safeexchange = 1; continue; } if((strcmp(argv[i], "--sort") == 0)) { sort = atoi(argv[++i]); continue; } if((strcmp(argv[i], "-o") == 0) || (strcmp(argv[i], "--yaml_output") == 0)) { yaml_output = atoi(argv[++i]); continue; } if((strcmp(argv[i], "--yaml_screen") == 0)) { screen_yaml = 1; continue; } if((strcmp(argv[i], "-f") == 0) || (strcmp(argv[i], "--data_file") == 0)) { if(in.datafile == NULL) in.datafile = new char[1000]; strcpy(in.datafile, argv[++i]); continue; } if((strcmp(argv[i], "-u") == 0) || (strcmp(argv[i], "--units") == 0)) { in.units = strcmp(argv[++i], "metal") == 0 ? 1 : 0; continue; } if((strcmp(argv[i], "-p") == 0) || (strcmp(argv[i], "--force") == 0)) { in.forcetype = strcmp(argv[++i], "eam") == 0 ? FORCEEAM : FORCELJ; continue; } if((strcmp(argv[i], "-gn") == 0) || (strcmp(argv[i], "--ghost_newton") == 0)) { ghost_newton = atoi(argv[++i]); continue; } if((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "--help") == 0)) { printf("\n-----------------------------------------------------------------------------------------------------------\n"); printf("-------------" VARIANT_STRING "--------------------\n"); printf("-------------------------------------------------------------------------------------------------------------\n\n"); printf("miniMD is a simple, parallel molecular dynamics (MD) code,\n" "which is part of the Mantevo project at Sandia National\n" "Laboratories ( http://www.mantevo.org ).\n" "The original authors of miniMD are Steve Plimpton ([email protected]) ,\n" "Paul Crozier ([email protected]) with current\n" "versions written by Christian Trott ([email protected]).\n\n"); printf("Commandline Options:\n"); printf("\n Execution configuration:\n"); printf("\t--teams <nteams>: set number of thread-teams used per MPI rank (default 1)\n"); printf("\t-t / --num_threads <threads>: set number of threads per thread-team (default 1)\n"); printf("\t--half_neigh <int>: use half neighborlists (default 1)\n" "\t 0: full neighborlist\n" "\t 1: half neighborlist\n" "\t -1: original miniMD half neighborlist force (not OpenMP safe)\n"); printf("\t-d / --device <int>: choose device to use (only applicable for GPU execution)\n"); printf("\t-dm / --device_map: map devices to MPI ranks\n"); printf("\t-ng / --num_gpus <int>: give number of GPUs per Node (used in conjuction with -dm\n" "\t to determine device id: 'id=mpi_rank%%ng' (default 2)\n"); printf("\t--skip_gpu <int>: skip the specified gpu when assigning devices to MPI ranks\n" "\t used in conjunction with -dm (but must come first in arg list)\n"); printf("\t-sse <sse_version>: use explicit sse intrinsics (use miniMD-SSE variant)\n"); printf("\t-gn / --ghost_newton <int>: set usage of newtons third law for ghost atoms\n" "\t (only applicable with half neighborlists)\n"); printf("\n Simulation setup:\n"); printf("\t-i / --input_file <string>: set input file to be used (default: in.lj.miniMD)\n"); printf("\t-n / --nsteps <int>: set number of timesteps for simulation\n"); printf("\t-s / --size <int>: set linear dimension of systembox\n"); printf("\t-nx/-ny/-nz <int>: set linear dimension of systembox in x/y/z direction\n"); printf("\t-b / --neigh_bins <int>: set linear dimension of neighbor bin grid\n"); printf("\t-u / --units <string>: set units (lj or metal), see LAMMPS documentation\n"); printf("\t-p / --force <string>: set interaction model (lj or eam)\n"); printf("\t-f / --data_file <string>: read configuration from LAMMPS data file\n"); printf("\n Miscelaneous:\n"); printf("\t--check_exchange: check whether atoms moved further than subdomain width\n"); printf("\t--safe_exchange: perform exchange communication with all MPI processes\n" "\t within rcut_neighbor (outer force cutoff)\n"); printf("\t--sort <n>: resort atoms (simple bins) every <n> steps (default: use reneigh frequency; never=0)"); printf("\t-o / --yaml_output <int>: level of yaml output (default 1)\n"); printf("\t--yaml_screen: write yaml output also to screen\n"); printf("\t-h / --help: display this help message\n\n"); printf("---------------------------------------------------------\n\n"); exit(0); } } Atom atom; Neighbor neighbor; Integrate integrate; Thermo thermo; Comm comm; Timer timer; ThreadData threads; Force* force; if(in.forcetype == FORCEEAM) { force = (Force*) new ForceEAM(); if(ghost_newton == 1) { if(me == 0) printf("# EAM currently requires '--ghost_newton 0'; Changing setting now.\n"); ghost_newton = 0; } } if(in.forcetype == FORCELJ) force = (Force*) new ForceLJ(); threads.mpi_me = me; threads.mpi_num_threads = nprocs; threads.omp_me = 0; threads.omp_num_threads = num_threads; atom.threads = &threads; comm.threads = &threads; force->threads = &threads; integrate.threads = &threads; neighbor.threads = &threads; thermo.threads = &threads; force->epsilon = in.epsilon; force->sigma = in.sigma; force->sigma6 = in.sigma*in.sigma*in.sigma*in.sigma*in.sigma*in.sigma; neighbor.ghost_newton = ghost_newton; omp_set_num_threads(num_threads); neighbor.timer = &timer; force->timer = &timer; comm.check_safeexchange = check_safeexchange; comm.do_safeexchange = do_safeexchange; force->use_sse = use_sse; neighbor.halfneigh = halfneigh; if(halfneigh < 0) force->use_oldcompute = 1; if(use_sse) { #ifdef VARIANT_REFERENCE if(me == 0) printf("ERROR: Trying to run with -sse with miniMD reference version. Use SSE variant instead. Exiting.\n"); MPI_Finalize(); exit(0); #endif } if(num_steps > 0) in.ntimes = num_steps; if(system_size > 0) { in.nx = system_size; in.ny = system_size; in.nz = system_size; } if(nx > 0) { in.nx = nx; if(ny > 0) in.ny = ny; else if(system_size < 0) in.ny = nx; if(nz > 0) in.nz = nz; else if(system_size < 0) in.nz = nx; } if(neighbor_size > 0) { neighbor.nbinx = neighbor_size; neighbor.nbiny = neighbor_size; neighbor.nbinz = neighbor_size; } if(neighbor_size < 0 && in.datafile == NULL) { MMD_float neighscale = 5.0 / 6.0; neighbor.nbinx = neighscale * in.nx; neighbor.nbiny = neighscale * in.ny; neighbor.nbinz = neighscale * in.nz; } if(neighbor_size < 0 && in.datafile) neighbor.nbinx = -1; if(neighbor.nbinx == 0) neighbor.nbinx = 1; if(neighbor.nbiny == 0) neighbor.nbiny = 1; if(neighbor.nbinz == 0) neighbor.nbinz = 1; integrate.ntimes = in.ntimes; integrate.dt = in.dt; integrate.sort_every = sort>0?sort:(sort<0?in.neigh_every:0); neighbor.every = in.neigh_every; neighbor.cutneigh = in.neigh_cut; force->cutforce = in.force_cut; thermo.nstat = in.thermo_nstat; if(me == 0) printf("# Create System:\n"); if(in.datafile) { read_lammps_data(atom, comm, neighbor, integrate, thermo, in.datafile, in.units); MMD_float volume = atom.box.xprd * atom.box.yprd * atom.box.zprd; in.rho = 1.0 * atom.natoms / volume; force->setup(); if(in.forcetype == FORCEEAM) atom.mass = force->mass; } else { create_box(atom, in.nx, in.ny, in.nz, in.rho); comm.setup(neighbor.cutneigh, atom); neighbor.setup(atom); integrate.setup(); force->setup(); if(in.forcetype == FORCEEAM) atom.mass = force->mass; create_atoms(atom, in.nx, in.ny, in.nz, in.rho); thermo.setup(in.rho, integrate, atom, in.units); create_velocity(in.t_request, atom, thermo); } if(me == 0) printf("# Done .... \n"); if(me == 0) { fprintf(stdout, "# " VARIANT_STRING " output ...\n"); fprintf(stdout, "# Run Settings: \n"); fprintf(stdout, "\t# MPI processes: %i\n", neighbor.threads->mpi_num_threads); fprintf(stdout, "\t# OpenMP threads: %i\n", neighbor.threads->omp_num_threads); fprintf(stdout, "\t# Inputfile: %s\n", input_file == 0 ? "in.lj.miniMD" : input_file); fprintf(stdout, "\t# Datafile: %s\n", in.datafile ? in.datafile : "None"); fprintf(stdout, "# Physics Settings: \n"); fprintf(stdout, "\t# ForceStyle: %s\n", in.forcetype == FORCELJ ? "LJ" : "EAM"); fprintf(stdout, "\t# Force Parameters: %2.2lf %2.2lf\n",in.epsilon,in.sigma); fprintf(stdout, "\t# Units: %s\n", in.units == 0 ? "LJ" : "METAL"); fprintf(stdout, "\t# Atoms: %i\n", atom.natoms); fprintf(stdout, "\t# System size: %2.2lf %2.2lf %2.2lf (unit cells: %i %i %i)\n", atom.box.xprd, atom.box.yprd, atom.box.zprd, in.nx, in.ny, in.nz); fprintf(stdout, "\t# Density: %lf\n", in.rho); fprintf(stdout, "\t# Force cutoff: %lf\n", force->cutforce); fprintf(stdout, "\t# Timestep size: %lf\n", integrate.dt); fprintf(stdout, "# Technical Settings: \n"); fprintf(stdout, "\t# Neigh cutoff: %lf\n", neighbor.cutneigh); fprintf(stdout, "\t# Half neighborlists: %i\n", neighbor.halfneigh); fprintf(stdout, "\t# Neighbor bins: %i %i %i\n", neighbor.nbinx, neighbor.nbiny, neighbor.nbinz); fprintf(stdout, "\t# Neighbor frequency: %i\n", neighbor.every); fprintf(stdout, "\t# Sorting frequency: %i\n", integrate.sort_every); fprintf(stdout, "\t# Thermo frequency: %i\n", thermo.nstat); fprintf(stdout, "\t# Ghost Newton: %i\n", ghost_newton); fprintf(stdout, "\t# Use intrinsics: %i\n", force->use_sse); fprintf(stdout, "\t# Do safe exchange: %i\n", comm.do_safeexchange); fprintf(stdout, "\t# Size of float: %i\n\n", (int) sizeof(MMD_float)); } comm.exchange(atom); if(sort>0) atom.sort(neighbor); comm.borders(atom); force->evflag = 1; #pragma omp parallel { neighbor.build(atom); force->compute(atom, neighbor, comm, me); } if(neighbor.halfneigh && neighbor.ghost_newton) comm.reverse_communicate(atom); if(me == 0) printf("# Starting dynamics ...\n"); if(me == 0) printf("# Timestep T U P Time\n"); #pragma omp parallel { thermo.compute(0, atom, neighbor, force, timer, comm); } timer.barrier_start(TIME_TOTAL); integrate.run(atom, force, neighbor, comm, thermo, timer); timer.barrier_stop(TIME_TOTAL); int natoms; MPI_Allreduce(&atom.nlocal, &natoms, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); force->evflag = 1; force->compute(atom, neighbor, comm, me); if(neighbor.halfneigh && neighbor.ghost_newton) comm.reverse_communicate(atom); thermo.compute(-1, atom, neighbor, force, timer, comm); if(me == 0) { double time_other = timer.array[TIME_TOTAL] - timer.array[TIME_FORCE] - timer.array[TIME_NEIGH] - timer.array[TIME_COMM]; printf("\n\n"); printf("# Performance Summary:\n"); printf("# MPI_proc OMP_threads nsteps natoms t_total t_force t_neigh t_comm t_other performance perf/thread grep_string t_extra\n"); printf("%i %i %i %i %lf %lf %lf %lf %lf %lf %lf PERF_SUMMARY %lf\n\n\n", nprocs, num_threads, integrate.ntimes, natoms, timer.array[TIME_TOTAL], timer.array[TIME_FORCE], timer.array[TIME_NEIGH], timer.array[TIME_COMM], time_other, 1.0 * natoms * integrate.ntimes / timer.array[TIME_TOTAL], 1.0 * natoms * integrate.ntimes / timer.array[TIME_TOTAL] / nprocs / num_threads, timer.array[TIME_TEST]); } if(yaml_output) output(in, atom, force, neighbor, comm, thermo, integrate, timer, screen_yaml); delete force; MPI_Barrier(MPI_COMM_WORLD); MPI_Finalize(); return 0; }
/***************** * OpenGL Methods * *****************/ void initScene(){ //create a list of random particles Particle* new_part; float noise = float(rand())/(float(RAND_MAX))*.1; float x,y,z,v_x,v_y,v_z; ////2D Drop Scene //float step = .017; //for(float i = 2.0*CONTAINER.max.x/5.0f; i<3.0*(CONTAINER.max.x)/5.0f; i=i+step){ // for(float j = 4.0*CONTAINER.max.y/5.0f; j<(CONTAINER.max.y); j=j+step){ // noise = float(rand())/(float(RAND_MAX))*.05f; // Vec3 pos(i,j,0); // Vec3 vel(0,-5,0); // new_part = new Particle(pos,vel,MASS); // PARTICLES.push_back(new_part); // } //} //step = .017; //for(float i = CONTAINER.min.x; i<(CONTAINER.max.x); i=i+step){ // for(float j = CONTAINER.min.y; j<(CONTAINER.max.y)/5.0f; j=j+step){ // noise = float(rand())/(float(RAND_MAX))*.05f; // Vec3 pos(i,j,0); // Vec3 vel(0,0,0); // new_part = new Particle(pos,vel,MASS); // PARTICLES.push_back(new_part); // } //} ////2D Throw Scene //Semi random grid of particles // float step = .025; // for(float i = 4.0*CONTAINER.max.x/5.0f; i<(CONTAINER.max.x); i=i+step){ // for(float j = 3.0*CONTAINER.max.y/4.0f; j<(CONTAINER.max.y); j=j+step){ // for(float k = 2.0*CONTAINER.max.z/4.0f; k<(3.0f*CONTAINER.max.z/4.0f); k=k+step) { // noise = float(rand())/(float(RAND_MAX))*.05f; // Vec3 pos(i,j,k); // Vec3 vel(-1,-8,0); // new_part = new Particle(pos,vel,MASS); // PARTICLES.push_back(new_part); // } // } // } // // step = .025; // for(float i = CONTAINER.min.x; i<1.0f*(CONTAINER.max.x)/5.0f; i=i+step){ // for(float j = 3.0*CONTAINER.max.y/4.0f; j<(CONTAINER.max.y); j=j+step){ // for(float k = 2.0*CONTAINER.max.z/4.0f; k<(3.0f*CONTAINER.max.z/4.0f); k=k+step) { // noise = float(rand())/(float(RAND_MAX))*.05f; // Vec3 pos(i,j,k); // Vec3 vel(5,-5,0); // new_part = new Particle(pos,vel,MASS); // PARTICLES.push_back(new_part); // } // } // } ////3D Drop Scene float step = .05; for(float i = 2.0*CONTAINER.max.x/5.0; i<3.0f*(CONTAINER.max.x)/5.0f; i=i+step){ for(float j = 2.0*CONTAINER.max.y/5.0f; j<3.0f*(CONTAINER.max.y)/5.0f; j=j+step){ for(float k = 1.0*CONTAINER.max.y/5.0f; k<4.0f*(CONTAINER.max.y)/5.0f; k=k+step){ noise = float(rand())/(float(RAND_MAX))*.05f; Vec3 pos(i,j,k); Vec3 vel(0,-3,0); new_part = new Particle(pos,vel,MASS,1000.0f); PARTICLES.push_back(new_part); } } } //step = .02; //for(float i = CONTAINER.min.x; i<(CONTAINER.max.x); i=i+step){ // for(float j = CONTAINER.min.y; j<1.0f*(CONTAINER.max.y)/5.0f; j=j+step){ // for(float k = CONTAINER.min.z; k<(CONTAINER.max.z); k=k+step){ // noise = float(rand())/(float(RAND_MAX))*.05f; // Vec3 pos(i,j,k); // Vec3 vel(0.3,1,0); // new_part = new Particle(pos,vel,MASS,1000.0f); // PARTICLES.push_back(new_part); // } // } //} ////3D Uniform Scene // float step = .05; // for(float i = CONTAINER.min.x; i<(CONTAINER.max.x); i=i+step){ // for(float j = CONTAINER.min.y; j<(CONTAINER.max.y); j=j+step){ // for(float k = 1.0*CONTAINER.min.z; k<(CONTAINER.max.z); k=k+step){ // //noise = float(rand())/(float(RAND_MAX))*.05f; // Vec3 pos(i,j,k); // Vec3 vel(-5,-3,0); // new_part = new Particle(pos,vel,MASS,1000.0f); // PARTICLES.push_back(new_part); // } // } // } NUM_PARTICLES = PARTICLES.size(); cout<<NUM_PARTICLES<<endl; ////random particles // for (int i = 0; i<NUM_PARTICLES; i++){ // x = .2f+float(rand())/(float(RAND_MAX))*.1f; // y = float(rand())/(float(RAND_MAX))/5.0 + .1f; // z = 0.0f;//.2f + float(rand())/(float(RAND_MAX))*.1f; // // v_x = -.5f+float(rand())/(float(RAND_MAX))*2.0f*noise; // v_y = -0.2+float(rand())/(float(RAND_MAX))*noise; // v_z = 0.0f;//-0.2+float(rand())/(float(RAND_MAX))*noise; // // // Vec3 pos(x,y,z); // Vec3 vel(v_x,v_y,v_z); // float mass = 4.0f+(float(rand())/(float(RAND_MAX)))*5.0f; // //also need to instantiate the other fields // new_part = new Particle(pos,vel,MASS); // PARTICLES.push_back(new_part); // } NUM_PARTICLES = PARTICLES.size(); cout<<NUM_PARTICLES<<endl; NEIGHBOR.place_particles(PARTICLES,SUPPORT_RADIUS,CONTAINER); //create some lights GLfloat light_position[] = {1,1,1,0}; GLfloat mat_specular[] = {0,0,0,1.0}; GLfloat mat_diffuse[] = {0.0,0.0,1.0,1.0}; GLfloat mat_ambient[] = {.1,.1,.1,1}; GLfloat mat_shininess[] = {20.0}; glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular); glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess); glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse); glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient); glLightfv(GL_LIGHT0,GL_POSITION,light_position); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); }
/* Create a new list of particles from the old list. Then, throw the old list. To do this, calculate all quanities in Navier-Stokes, then use timestep to update particle location from old location and velocity. */ void run_time_step(){ vector<Particle*> new_particles; vector<float> pressure_list; vector<Vec3> pressure_grad_list; vector<Vec3> viscosity_list; vector<float> color_list; vector<Vec3> tension_list; NEIGHBOR.place_particles(PARTICLES, SUPPORT_RADIUS, CONTAINER); //update using slow algorithm for now Particle *base_particle, *temp_particle, *new_particle; float density = 0; //Sets density at each point for (int i = 0; i<NUM_PARTICLES; i++){ density = 0; base_particle = PARTICLES[i]; vector<int> neighbor_vec = base_particle->neighbors; int n = neighbor_vec.size(); for (int j = 0; j<n; j++){ // changed to neighbors temp_particle = PARTICLES[neighbor_vec[j]]; Vec3 r = base_particle->position-temp_particle->position; float mag = dot(r,r); if(mag<H*H){ density += temp_particle->mass*default_kernel(base_particle->position,temp_particle->position); } } base_particle->density = density; //changed this to not include stiffness at all pressure_list.push_back(STIFFNESS*(density-IDEAL_DENSITY)); } //Sets pressure gradient at each point using densities from last loop for (int i = 0; i<NUM_PARTICLES; i++){ base_particle = PARTICLES[i]; Vec3 pressure_gradient(0,0,0); vector<int> neighbor_vec = base_particle->neighbors; for (int j = 0; j<neighbor_vec.size(); j++){ // changed to neighbors if(i!=neighbor_vec[j]){ temp_particle = PARTICLES[neighbor_vec[j]]; Vec3 r = base_particle->position-temp_particle->position; float mag = dot(r,r); if(mag<H*H){ Vec3 weight = pressure_kernel_gradient(base_particle->position,temp_particle->position); pressure_gradient += weight * temp_particle->mass * ((pressure_list[i]+pressure_list[j])/(2.0f*temp_particle->density)); } } } pressure_grad_list.push_back(pressure_gradient*(-1.0f)); } //Sets viscosity at each particle for (int i = 0; i<NUM_PARTICLES; i++){ base_particle = PARTICLES[i]; Vec3 viscosity_laplacian(0,0,0); vector<int> neighbor_vec = base_particle->neighbors; for (int j = 0; j<neighbor_vec.size(); j++){ if(i!=neighbor_vec[j]){ temp_particle = PARTICLES[neighbor_vec[j]]; Vec3 r = base_particle->position-temp_particle->position; float mag = dot(r,r); if(mag<H*H){ float weight = viscosity_kernel_laplacian(base_particle->position,temp_particle->position); viscosity_laplacian += ((temp_particle->velocity - base_particle->velocity)/base_particle->density)*weight * temp_particle->mass; } } } viscosity_list.push_back(viscosity_laplacian*VISCOSITY); } //Sets color field laplacian at each point for surface tension for (int i = 0; i<NUM_PARTICLES; i++){ base_particle = PARTICLES[i]; float color = 0.0f; vector<int> neighbor_vec = base_particle->neighbors; for (int j = 0; j<neighbor_vec.size(); j++){ if(i!=neighbor_vec[j]){ temp_particle = PARTICLES[neighbor_vec[j]]; Vec3 r = base_particle->position-temp_particle->position; float mag = dot(r,r); if(mag<H*H){ color += (temp_particle->mass / temp_particle->density) * default_laplacian(base_particle->position,temp_particle->position); } } } color_list.push_back(color); } //set the normal at each point for (int i = 0; i<NUM_PARTICLES; i++){ base_particle = PARTICLES[i]; Vec3 normal(0,0,0); vector<int> neighbor_vec = base_particle->neighbors; for (int j = 0; j<neighbor_vec.size(); j++){ if(i!=neighbor_vec[j]){ temp_particle = PARTICLES[neighbor_vec[j]]; Vec3 r = base_particle->position-temp_particle->position; float mag = dot(r,r); if(mag<H*H){ normal += default_gradient(base_particle->position,temp_particle->position)*(temp_particle->mass / temp_particle->density); } } } float length = sqrt(dot(normal,normal)); if(length>TENSION_THRESHOLD){ normal = normal/sqrt(length); tension_list.push_back(normal*(-1.0f*color_list[i])); }else{ Vec3 v(0,0,0); tension_list.push_back(v); } } //Create new particles from old particles and from pressure gradient. for (int i = 0; i<NUM_PARTICLES; i++){ temp_particle = PARTICLES[i]; //using Navier Stokes, calculate the change in velocity. //First add external forces Vec3 acceleration = GRAVITY + (tension_list[i]*SURFACE_TENSION + (viscosity_list[i]*VISCOSITY) + pressure_grad_list[i])/temp_particle->density; Vec3 position = temp_particle->position; Vec3 velocity = temp_particle->velocity; Vec3 new_velocity,new_position; //if(CURRENT_TIME==0){ new_velocity = velocity+acceleration*TIMESTEP; new_position = position + (velocity + acceleration*TIMESTEP)*TIMESTEP; //}else{ //new_velocity = (position-temp_particle->prev_position)/TIMESTEP; //new_position = position*2.0f - temp_particle->prev_position + acceleration*TIMESTEP*TIMESTEP; //} float mass = temp_particle->mass; temp_particle = new Particle(new_position,new_velocity,mass,temp_particle->density); temp_particle->prev_position = position; CONTAINER.in_container(temp_particle,TIMESTEP); //applies reflections if outside of boundary. new_particles.push_back(temp_particle); } PARTICLES = new_particles; //reset neighbor structure NEIGHBOR.place_particles(PARTICLES,SUPPORT_RADIUS,CONTAINER); }
// go through every (child) object static Bool Recurse(HierarchyHelp *hh, BaseThread *bt, BaseObject *main, BaseObject *op, const Matrix &ml, Real srad, Real crad, LONG sub, Bool single) { // test if input object if polygonal if (op->GetType()==Opolygon) { BaseObject *tp = NULL; PolyInfo *pli = NULL; const Vector *padr = ToPoly(op)->GetPointR(); Vector pa,pb; LONG pcnt = ToPoly(op)->GetPointCount(),i,side,a=0,b=0; const CPolygon *vadr = ToPoly(op)->GetPolygonR(); LONG vcnt = ToPoly(op)->GetPolygonCount(); Matrix m; Neighbor n; // load names from resource String pstr = GeLoadString(IDS_ATOM_POINT); String estr = GeLoadString(IDS_ATOM_EDGE); // initialize neighbor class if (!n.Init(pcnt,vadr,vcnt,NULL)) return FALSE; // create separate objects // if this option is enabled no polygonal geometry is build - more parametric objects // are returned instead if (single) { for (i=0; i<pcnt; i++) { // alloc sphere primitive tp=BaseObject::Alloc(Osphere); if (!tp) return FALSE; // add phong tag if (!tp->MakeTag(Tphong)) return FALSE; tp->SetName(pstr+" "+LongToString(i)); // set object parameters BaseContainer *bc = tp->GetDataInstance(); bc->SetReal(PRIM_SPHERE_RAD,srad); bc->SetReal(PRIM_SPHERE_SUB,sub); // insert as last object under main tp->InsertUnderLast(main); // set position in local coordinates tp->SetRelPos(padr[i]*ml); } for (i=0; i<vcnt; i++) { // get polygon info for i-th polygon pli = n.GetPolyInfo(i); for (side=0; side<4; side++) { // only proceed if edge has not already been processed // and edge really exists (for triangles side 2 from c..d does not exist as c==d) if (pli->mark[side] || side==2 && vadr[i].c==vadr[i].d) continue; // alloc cylinder primitive tp=BaseObject::Alloc(Ocylinder); if (!tp) return FALSE; // add phong tag if (!tp->MakeTag(Tphong)) return FALSE; switch (side) { case 0: a=vadr[i].a; b=vadr[i].b; break; case 1: a=vadr[i].b; b=vadr[i].c; break; case 2: a=vadr[i].c; b=vadr[i].d; break; case 3: a=vadr[i].d; b=vadr[i].a; break; } tp->SetName(estr+" "+LongToString(pli->edge[side])); pa = padr[a]*ml; pb = padr[b]*ml; // set object parameters BaseContainer *bc = tp->GetDataInstance(); bc->SetReal(PRIM_CYLINDER_RADIUS,crad); bc->SetReal(PRIM_CYLINDER_HEIGHT,Len(pb-pa)); bc->SetReal(PRIM_AXIS,4); bc->SetLong(PRIM_CYLINDER_CAPS,FALSE); bc->SetLong(PRIM_CYLINDER_HSUB,1); bc->SetLong(PRIM_CYLINDER_SEG,sub); // place cylinder at edge center tp->SetRelPos((pa+pb)*0.5); // build edge matrix m.v3=!(pb-pa); RectangularSystem(m.v3,&m.v1,&m.v2); tp->SetRelRot(MatrixToHPB(m, tp->GetRotationOrder())); // insert as last object under main tp->InsertUnderLast(main); } } } else { // check if polygonal geometry has to be built tp = BuildPolyHull(ToPoly(op),ml,srad,crad,sub,hh->GetLOD(),&n,bt); if (tp) { tp->SetName(op->GetName()); tp->InsertUnderLast(main); // check if isoparm geometry has to be built if (hh->GetBuildFlags()&BUILDFLAGS_ISOPARM) { LineObject *ip = BuildIsoHull(ToPoly(op),ml,srad,crad,sub,hh->GetLOD(),&n,bt); // isoparm always needs to be set into a polygon object if (ip) tp->SetIsoparm(ip); } } } } for (op=op->GetDown(); op; op=op->GetNext()) if (!Recurse(hh,bt,main,op,ml*op->GetMl(),srad,crad,sub,single)) return FALSE; // check for user break return !bt || !bt->TestBreak(); }