void destroyHaloExchange(HaloExchange** haloExchange) { (*haloExchange)->destroy((*haloExchange)->parms); comdFree((*haloExchange)->parms); comdFree(*haloExchange); *haloExchange = NULL; }
/// This is the function that does the heavy lifting for the /// communication of halo data. It is called once for each axis and /// sends and receives two message. Loading and unloading of the /// buffers is in the hands of the sub-class virtual functions. /// /// \param [in] iAxis Axis index. /// \param [in, out] data Pointer to data that will be passed to the load and /// unload functions void exchangeData(HaloExchange* haloExchange, void* data, int iAxis) { enum HaloFaceOrder faceM = 2*iAxis; enum HaloFaceOrder faceP = faceM+1; char* sendBufM = comdMalloc(haloExchange->bufCapacity); char* sendBufP = comdMalloc(haloExchange->bufCapacity); char* recvBufM = comdMalloc(haloExchange->bufCapacity); char* recvBufP = comdMalloc(haloExchange->bufCapacity); int nSendM = haloExchange->loadBuffer(haloExchange->parms, data, faceM, sendBufM); int nSendP = haloExchange->loadBuffer(haloExchange->parms, data, faceP, sendBufP); int nbrRankM = haloExchange->nbrRank[faceM]; int nbrRankP = haloExchange->nbrRank[faceP]; int nRecvM, nRecvP; startTimer(commHaloTimer); nRecvP = sendReceiveParallel(sendBufM, nSendM, nbrRankM, recvBufP, haloExchange->bufCapacity, nbrRankP); nRecvM = sendReceiveParallel(sendBufP, nSendP, nbrRankP, recvBufM, haloExchange->bufCapacity, nbrRankM); stopTimer(commHaloTimer); haloExchange->unloadBuffer(haloExchange->parms, data, faceM, nRecvM, recvBufM); haloExchange->unloadBuffer(haloExchange->parms, data, faceP, nRecvP, recvBufP); comdFree(recvBufP); comdFree(recvBufM); comdFree(sendBufP); comdFree(sendBufM); }
void destroyHashTable(HashTable** hashTable) { if (! hashTable) return; if (! *hashTable) return; comdFree((*hashTable)->offset); comdFree(*hashTable); *hashTable = NULL; }
void destroyForceExchange(void* vparms) { ForceExchangeParms* parms = (ForceExchangeParms*) vparms; for (int ii=0; ii<6; ++ii) { comdFree(parms->sendCells[ii]); comdFree(parms->recvCells[ii]); } }
void destroyAtomsExchange(void* vparms) { AtomExchangeParms* parms = (AtomExchangeParms*) vparms; for (int ii=0; ii<6; ++ii) { comdFree(parms->pbcFactor[ii]); comdFree(parms->cellList[ii]); } }
void destroyLinkCells(LinkCell** boxes) { if (! boxes) return; if (! *boxes) return; comdFree((*boxes)->nAtoms); comdFree(*boxes); *boxes = NULL; return; }
void destroyInterpolationObject(InterpolationObject** a) { if ( ! a ) return; if ( ! *a ) return; if ( (*a)->values) { (*a)->values--; comdFree((*a)->values); } comdFree(*a); *a = NULL; return; }
/// Free all the memory associated with Neighborlist void destroyNeighborListGpu(NeighborListGpu** neighborList) { if (! neighborList) return; if (! *neighborList) return; comdFree((*neighborList)->list); comdFree((*neighborList)->nNeighbors); cudaFree((*neighborList)->lastR.x); cudaFree((*neighborList)->lastR.y); cudaFree((*neighborList)->lastR.z); comdFree((*neighborList)); *neighborList = NULL; return; }
void destroyAtoms(Atoms *atoms) { freeMe(atoms,gid); freeMe(atoms,iSpecies); freeMe(atoms,r); freeMe(atoms,p); freeMe(atoms,f); freeMe(atoms,U); comdFree(atoms); }
void ljDestroy(BasePotential** inppot) { if ( ! inppot ) return; LjPotential* pot = (LjPotential*)(*inppot); if ( ! pot ) return; comdFree(pot); *inppot = NULL; return; }
/// frees all data associated with *ps and frees *ps void destroySimulation(SimFlat** ps) { if ( ! ps ) return; SimFlat* s = *ps; if ( ! s ) return; BasePotential* pot = s->pot; if ( pot) pot->destroy(&pot); destroyLinkCells(&(s->boxes)); destroyAtoms(s->atoms); destroyHaloExchange(&(s->atomExchange)); comdFree(s->species); comdFree(s->domain); comdFree(s); *ps = NULL; return; }
void ljDestroy(BasePotential **inppot) { if (!inppot) { return ; } LjPotential *pot = (LjPotential *)( *inppot); if (!pot) { return ; } comdFree(pot); *inppot = ((void *)0); return ; }
void eamDestroy(BasePotential** pPot) { if ( ! pPot ) return; EamPotential* pot = *(EamPotential**)pPot; if ( ! pot ) return; destroyInterpolationObject(&(pot->phi)); destroyInterpolationObject(&(pot->rho)); destroyInterpolationObject(&(pot->f)); destroyHaloExchange(&(pot->forceExchange)); comdFree(pot); *pPot = NULL; return; }
/// frees all data associated with *ps and frees *ps void destroySimulation(SimFlat** ps) { if ( ! ps ) return; SimFlat* s = *ps; if ( ! s ) return; BasePotential* pot = s->pot; //if ( pot)//UNCOMMENT pot->destroy(&pot); free(pot);//???? destroyLinkCells(&(s->boxes)); destroyAtoms(s->atoms); destroyHaloExchange(&(s->atomExchange)); free(s->atoms); comdFree(s); *ps = NULL; return; }
/// Reads potential data from a funcfl file and populates /// corresponding members and InterpolationObjects in an EamPotential. /// /// funcfl is a file format for tabulated potential functions used by /// the original EAM code DYNAMO. A funcfl file contains an EAM /// potential for a single element. /// /// The contents of a funcfl file are: /// /// | Line Num | Description /// | :------: | :---------- /// | 1 | comments /// | 2 | elem amass latConstant latType /// | 3 | nrho drho nr dr rcutoff /// | 4 | embedding function values F(rhobar) starting at rhobar=0 /// | ... | (nrho values. Multiple values per line allowed.) /// | x' | electrostatic interation Z(r) starting at r=0 /// | ... | (nr values. Multiple values per line allowed.) /// | y' | electron density values rho(r) starting at r=0 /// | ... | (nr values. Multiple values per line allowed.) /// /// Where: /// - elem : atomic number for this element /// - amass : atomic mass for this element in AMU /// - latConstant : lattice constant for this elemnent in Angstroms /// - lattticeType : lattice type for this element (e.g. FCC) /// - nrho : number of values for the embedding function, F(rhobar) /// - drho : table spacing for rhobar /// - nr : number of values for Z(r) and rho(r) /// - dr : table spacing for r in Angstroms /// - rcutoff : potential cut-off distance in Angstroms /// /// funcfl format stores the "electrostatic interation" Z(r). This needs to /// be converted to the pair potential phi(r). /// using the formula /// \f[phi = Z(r) * Z(r) / r\f] /// NB: phi is not defined for r = 0 /// /// Z(r) is in atomic units (i.e., sqrt[Hartree * bohr]) so it is /// necesary to convert to eV. /// /// F(rhobar) is in eV. /// void eamReadFuncfl(EamPotential* pot, const char* dir, const char* potName) { char tmp[4096]; sprintf(tmp, "%s/%s", dir, potName); FILE* potFile = fopen(tmp, "r"); if (potFile == NULL) fileNotFound("eamReadFuncfl", tmp); // line 1 fgets(tmp, sizeof(tmp), potFile); char name[3]; sscanf(tmp, "%s", name); strcpy(pot->name, name); // line 2 int nAtomic; double mass, lat; char latticeType[8]; fgets(tmp,sizeof(tmp),potFile); sscanf(tmp, "%d %le %le %s", &nAtomic, &mass, &lat, latticeType); pot->atomicNo = nAtomic; pot->lat = lat; pot->mass = mass*amuToInternalMass; // file has mass in AMU. strcpy(pot->latticeType, latticeType); // line 3 int nRho, nR; double dRho, dR, cutoff; fgets(tmp,sizeof(tmp),potFile); sscanf(tmp, "%d %le %d %le %le", &nRho, &dRho, &nR, &dR, &cutoff); pot->cutoff = cutoff; real_t x0 = 0.0; // tables start at zero. // allocate read buffer int bufSize = MAX(nRho, nR); real_t* buf = comdMalloc(bufSize * sizeof(real_t)); // read embedding energy for (int ii=0; ii<nRho; ++ii) fscanf(potFile, FMT1, buf+ii); pot->f = initInterpolationObject(nRho, x0, dRho, buf); // read Z(r) and convert to phi(r) for (int ii=0; ii<nR; ++ii) fscanf(potFile, FMT1, buf+ii); for (int ii=1; ii<nR; ++ii) { real_t r = x0 + ii*dR; buf[ii] *= buf[ii] / r; buf[ii] *= hartreeToEv * bohrToAngs; // convert to eV } buf[0] = buf[1] + (buf[1] - buf[2]); // linear interpolation to get phi[0]. pot->phi = initInterpolationObject(nR, x0, dR, buf); // read electron density rho for (int ii=0; ii<nR; ++ii) fscanf(potFile, FMT1, buf+ii); pot->rho = initInterpolationObject(nR, x0, dR, buf); comdFree(buf); /* printPot(pot->f, "funcflDataF.txt"); */ /* printPot(pot->rho, "funcflDataRho.txt"); */ /* printPot(pot->phi, "funcflDataPhi.txt"); */ }
/// Reads potential data from a setfl file and populates /// corresponding members and InterpolationObjects in an EamPotential. /// /// setfl is a file format for tabulated potential functions used by /// the original EAM code DYNAMO. A setfl file contains EAM /// potentials for multiple elements. /// /// The contents of a setfl file are: /// /// | Line Num | Description /// | :------: | :---------- /// | 1 - 3 | comments /// | 4 | ntypes type1 type2 ... typen /// | 5 | nrho drho nr dr rcutoff /// | F, rho | Following line 5 there is a block for each atom type with F, and rho. /// | b1 | ielem(i) amass(i) latConst(i) latType(i) /// | b2 | embedding function values F(rhobar) starting at rhobar=0 /// | ... | (nrho values. Multiple values per line allowed.) /// | bn | electron density, starting at r=0 /// | ... | (nr values. Multiple values per line allowed.) /// | repeat | Return to b1 for each atom type. /// | phi | phi_ij for (1,1), (2,1), (2,2), (3,1), (3,2), (3,3), (4,1), ..., /// | p1 | pair potential between type i and type j, starting at r=0 /// | ... | (nr values. Multiple values per line allowed.) /// | repeat | Return to p1 for each phi_ij /// /// Where: /// - ntypes : number of element types in the potential /// - nrho : number of points the embedding energy F(rhobar) /// - drho : table spacing for rhobar /// - nr : number of points for rho(r) and phi(r) /// - dr : table spacing for r in Angstroms /// - rcutoff : cut-off distance in Angstroms /// - ielem(i) : atomic number for element(i) /// - amass(i) : atomic mass for element(i) in AMU /// - latConst(i) : lattice constant for element(i) in Angstroms /// - latType(i) : lattice type for element(i) /// /// setfl format stores r*phi(r), so we need to converted to the pair /// potential phi(r). In the file, phi(r)*r is in eV*Angstroms. /// NB: phi is not defined for r = 0 /// /// F(rhobar) is in eV. /// void eamReadSetfl(EamPotential* pot, const char* dir, const char* potName) { char tmp[4096]; sprintf(tmp, "%s/%s", dir, potName); FILE* potFile = fopen(tmp, "r"); if (potFile == NULL) fileNotFound("eamReadSetfl", tmp); // read the first 3 lines (comments) fgets(tmp, sizeof(tmp), potFile); fgets(tmp, sizeof(tmp), potFile); fgets(tmp, sizeof(tmp), potFile); // line 4 fgets(tmp, sizeof(tmp), potFile); int nElems; sscanf(tmp, "%d", &nElems); if( nElems != 1 ) notAlloyReady("eamReadSetfl"); //line 5 int nRho, nR; double dRho, dR, cutoff; // The same cutoff is used by all alloys, NB: cutoff = nR * dR is redundant fgets(tmp, sizeof(tmp), potFile); sscanf(tmp, "%d %le %d %le %le", &nRho, &dRho, &nR, &dR, &cutoff); pot->cutoff = cutoff; // **** THIS CODE IS RESTRICTED TO ONE ELEMENT // Per-atom header fgets(tmp, sizeof(tmp), potFile); int nAtomic; double mass, lat; char latticeType[8]; sscanf(tmp, "%d %le %le %s", &nAtomic, &mass, &lat, latticeType); pot->atomicNo = nAtomic; pot->lat = lat; pot->mass = mass * amuToInternalMass; // file has mass in AMU. strcpy(pot->latticeType, latticeType); // allocate read buffer int bufSize = MAX(nRho, nR); real_t* buf = comdMalloc(bufSize * sizeof(real_t)); real_t x0 = 0.0; // Read embedding energy F(rhobar) for (int ii=0; ii<nRho; ++ii) fscanf(potFile, FMT1, buf+ii); pot->f = initInterpolationObject(nRho, x0, dRho, buf); // Read electron density rho(r) for (int ii=0; ii<nR; ++ii) fscanf(potFile, FMT1, buf+ii); pot->rho = initInterpolationObject(nR, x0, dR, buf); // Read phi(r)*r and convert to phi(r) for (int ii=0; ii<nR; ++ii) fscanf(potFile, FMT1, buf+ii); for (int ii=1; ii<nR; ++ii) { real_t r = x0 + ii*dR; buf[ii] /= r; } buf[0] = buf[1] + (buf[1] - buf[2]); // Linear interpolation to get phi[0]. pot->phi = initInterpolationObject(nR, x0, dR, buf); comdFree(buf); // write to text file for comparison, currently commented out /* printPot(pot->f, "SetflDataF.txt"); */ /* printPot(pot->rho, "SetflDataRho.txt"); */ /* printPot(pot->phi, "SetflDataPhi.txt"); */ }
CoMD_return CoMD_lib(CoMD_input *inputStruct) { // Prolog //profileStart(totalTimer); //initSubsystems(); //Command cmd = parseCommandLine(argc, argv); Command cmd = parseInputStruct(inputStruct); //Ignore stressSuffix for now SimFlat* sim = initSimulation(cmd); Validate* validate = initValidate(sim); // atom counts, energy // This is the CoMD main loop const int nSteps = sim->nSteps; const int printRate = sim->printRate; double avgStress[9]; int stressi; int iStep; for(stressi=0;stressi<9;stressi++) avgStress[stressi]=0; for (iStep=0; iStep<nSteps;iStep++) { sumAtoms(sim); //Find and intercept these to write to the struct //printThings(sim, iStep, getElapsedTime(timestepTimer)); printTensor(iStep, sim->defInfo->stress); timestep(sim, 1, sim->dt); if(iStep>500){ for(stressi=0;stressi<9;stressi++) avgStress[stressi]+=sim->defInfo->stress[stressi]/(nSteps-500); } } sumAtoms(sim); //Find and intercept //printThings(sim, iStep, getElapsedTime(timestepTimer)); CoMD_return retVal = printStuff(iStep, sim, avgStress); // Epilog //validateResult(validate, sim); //profileStop(totalTimer); /* if (sim->pot->dfEmbed!=NULL) { free(sim->pot->dfEmbed); sim->pot->dfEmbed=NULL; } if (sim->pot->rhobar!=NULL) { free(sim->pot->rhobar); sim->pot->rhobar=NULL; } if (sim->pot->forceExchangeData!=NULL) { free(sim->pot->forceExchangeData); sim->pot->forceExchangeData=NULL; }*/ destroySimulation(&sim); comdFree(validate); //finalizeSubsystems();//??? //destroyParallel(); //??? return retVal; }
int main(int argc, char** argv) { // Prolog initParallel(&argc, &argv); profileStart(totalTimer); initSubsystems(); timestampBarrier("Starting Initialization\n"); yamlAppInfo(yamlFile); yamlAppInfo(screenOut); Command cmd = parseCommandLine(argc, argv); printCmdYaml(yamlFile, &cmd); printCmdYaml(screenOut, &cmd); SimFlat* sim = initSimulation(cmd); printSimulationDataYaml(yamlFile, sim); printSimulationDataYaml(screenOut, sim); Validate* validate = initValidate(sim); // atom counts, energy timestampBarrier("Initialization Finished\n"); timestampBarrier("Starting simulation\n"); // This is the CoMD main loop const int nSteps = sim->nSteps; const int printRate = sim->printRate; int iStep = 0; profileStart(loopTimer); for (; iStep<nSteps;) { startTimer(commReduceTimer); sumAtoms(sim); stopTimer(commReduceTimer); printThings(sim, iStep, getElapsedTime(timestepTimer)); startTimer(timestepTimer); timestep(sim, printRate, sim->dt); stopTimer(timestepTimer); iStep += printRate; } profileStop(loopTimer); sumAtoms(sim); printThings(sim, iStep, getElapsedTime(timestepTimer)); timestampBarrier("Ending simulation\n"); // Epilog validateResult(validate, sim); profileStop(totalTimer); printPerformanceResults(sim->atoms->nGlobal); printPerformanceResultsYaml(yamlFile); destroySimulation(&sim); comdFree(validate); finalizeSubsystems(); timestampBarrier("CoMD Ending\n"); destroyParallel(); return 0; }