int main(int argc, char* argv[]) { init_workers(); if(_my_rank == 0) cout << "Twitter SCC" << endl; twitter(); if (_my_rank == 0) cout << "LJ SCC" << endl; LJ(); //pregel_tosccgraphformat("/pullgel/twitter","/scc/twitter"); //pregel_tosccgraphformat("/pullgel/LJ","/scc/LJ"); worker_finalize(); return 0; }
int main(){ // new random seed each time, for velocities and placement seed(); const flt Vs = Natoms * pow(sigma, NDIM) * M_PI_2 / NDIM; const flt L = pow(Vs / phi, OVERNDIM); cout << "Using L = " << L << "\n"; // Create the bounding box (sides of length L), and a "vector" of Natoms atoms boost::shared_ptr<OriginBox> obox(new OriginBox(L)); boost::shared_ptr<AtomVec> atomptr(new AtomVec(Natoms, 1.0)); AtomVec & atoms = *atomptr; // LJ Interaction // We'll cut it off at 2.5σ, and have a NeighborList out to 1.4 times that boost::shared_ptr<NListed<EpsSigCutAtom, LennardJonesCutPair> > LJ(new NListed<EpsSigCutAtom, LennardJonesCutPair>(obox, atomptr, 0.4*(sigcut*sigma))); boost::shared_ptr<NeighborList> nl = LJ->neighbor_list(); // ^ this is the Interaction // Note that NListed is a class template; its an Interaction that // takes various structs as template parameters, and turns them into // a neighbor Interaction // See Interaction.hpp for a whole bunch of them // Also note that the NeighborList is not the same as the // "neighborlisted" Interaction; multiple interactions can use the // same NeighborList // Now we run through all the atoms, set their positions / velocities, // and add them to the LJ Interaction (i.e., to the neighbor list) for (uint i=0; i < atoms.size(); i++){ if((i+1) % 50 == 0) cout << (Natoms - (i+1)) / 50 << ", "; cout.flush(); // we track energy to see if things are overlapping flt E0 = LJ->energy(*obox); atoms[i].x = obox->rand_loc(); // random location in the box atoms[i].v = rand_vec(); // from a Gaussian atoms[i].f = Vec::Zero(); atoms[i].a = Vec::Zero(); // Add it to the Lennard-Jones potential LJ->add(EpsSigCutAtom(atoms.get_id(i), epsilon, sigma, sigcut)); // force an update the NeighborList, so we can get an accurate energy nl->update_list(true); // If we're overlapping too much, try a new location while(LJ->energy(*obox) > E0 + epsilon/2.0){ atoms[i].x = obox->rand_loc(); // random location in the box nl->update_list(true); } } cout << "Starting. Neighborlist contains " << nl->numpairs() << " / " << (atoms.size()*(atoms.size()-1))/2 << " pairs.\n"; //Now we make our "Collection" CollectionVerlet collec = CollectionVerlet(boost::static_pointer_cast<Box>(obox), atomptr, dt); // This is very important! Otherwise the NeighborList won't update! collec.add_tracker(nl); // And add the Interaction collec.add_interaction(LJ); // subtract off center of mass velocity, and set a total energy collec.reset_com_velocity(); collec.scale_velocities_to_energy(Natoms / 4.0); // We'll put the energies to stdout and the coordinates to a new file. // VMD is good for 3D visualization purposes, and it can read .xyz files // see 'writefile' function ofstream outfile; outfile.open("LJatoms.xyz", ios::out); writefile(outfile, atoms, *obox); //Print out total energy, kinetic_energy energy, and potential energy cout << "E: " << collec.energy() << " K: " << collec.kinetic_energy() << " U: " << LJ->energy(*obox) << "\n"; // Run the simulation! And every _ steps, write a frame to the .xyz // file and print out the energies again for(uint i=0; i<500; i++){ for(uint j=0; j<1000; j++){ collec.timestep(); } writefile(outfile, atoms, *obox); cout << (500-i) << " E: " << collec.energy() << " K: " << collec.kinetic_energy() << " U: " << LJ->energy(*obox) << "\n"; } // Unnecessary extra: // Write a "tcl" file with the box boundaries // the "tcl" file is made specifically for VMD ofstream pbcfile; pbcfile.open("LJatoms-pbc.tcl", ios::out); pbcfile << "set cell [pbc set {"; for(uint j=0; j<NDIM; j++){ pbcfile << obox->box_shape()[j] << " "; } pbcfile << "} -all];\n"; pbcfile << "pbc box -toggle -center origin -color red;\n"; // Now you should be able to run "vmd -e LJatoms-pbc.tcl LJatoms.xyz" // and it will show you the movie and also the bounding box // if you have .vmdrc in that same directory, you should also be able // to toggle the box with the "b" button cout << "Done. Neighborlist contains " << nl->numpairs() << " / " << (atoms.size()*(atoms.size()-1))/2 << " pairs.\n"; };
IGL_INLINE bool igl::lu_lagrange( const Eigen::SparseMatrix<T> & ATA, const Eigen::SparseMatrix<T> & C, Eigen::SparseMatrix<T> & L, Eigen::SparseMatrix<T> & U) { #if EIGEN_VERSION_AT_LEAST(3,0,92) #if defined(_WIN32) #pragma message("lu_lagrange has not yet been implemented for your Eigen Version") #else #warning lu_lagrange has not yet been implemented for your Eigen Version #endif return false; #else // number of unknowns int n = ATA.rows(); // number of lagrange multipliers int m = C.cols(); assert(ATA.cols() == n); if(m != 0) { assert(C.rows() == n); if(C.nonZeros() == 0) { // See note above about empty columns in C fprintf(stderr,"Error: lu_lagrange() C has columns but no entries\n"); return false; } } // Check that each column of C has at least one entry std::vector<bool> has_entry; has_entry.resize(C.cols(),false); // Iterate over outside for(int k=0; k<C.outerSize(); ++k) { // Iterate over inside for(typename Eigen::SparseMatrix<T>::InnerIterator it (C,k); it; ++it) { has_entry[it.col()] = true; } } for(int i=0;i<(int)has_entry.size();i++) { if(!has_entry[i]) { // See note above about empty columns in C fprintf(stderr,"Error: lu_lagrange() C(:,%d) has no entries\n",i); return false; } } // Cholesky factorization of ATA //// Eigen fails if you give a full view of the matrix like this: //Eigen::SparseLLT<SparseMatrix<T> > ATA_LLT(ATA); Eigen::SparseMatrix<T> ATA_LT = ATA.template triangularView<Eigen::Lower>(); Eigen::SparseLLT<Eigen::SparseMatrix<T> > ATA_LLT(ATA_LT); Eigen::SparseMatrix<T> J = ATA_LLT.matrixL(); //if(!ATA_LLT.succeeded()) if(!((J*0).eval().nonZeros() == 0)) { fprintf(stderr,"Error: lu_lagrange() failed to factor ATA\n"); return false; } if(m == 0) { // If there are no constraints (C is empty) then LU decomposition is just L // and L' from cholesky decomposition L = J; U = J.transpose(); }else { // Construct helper matrix M Eigen::SparseMatrix<T> M = C; J.template triangularView<Eigen::Lower>().solveInPlace(M); // Compute cholesky factorizaiton of M'*M Eigen::SparseMatrix<T> MTM = M.transpose() * M; Eigen::SparseLLT<Eigen::SparseMatrix<T> > MTM_LLT(MTM.template triangularView<Eigen::Lower>()); Eigen::SparseMatrix<T> K = MTM_LLT.matrixL(); //if(!MTM_LLT.succeeded()) if(!((K*0).eval().nonZeros() == 0)) { fprintf(stderr,"Error: lu_lagrange() failed to factor MTM\n"); return false; } // assemble LU decomposition of Q Eigen::Matrix<int,Eigen::Dynamic,1> MI; Eigen::Matrix<int,Eigen::Dynamic,1> MJ; Eigen::Matrix<T,Eigen::Dynamic,1> MV; igl::find(M,MI,MJ,MV); Eigen::Matrix<int,Eigen::Dynamic,1> KI; Eigen::Matrix<int,Eigen::Dynamic,1> KJ; Eigen::Matrix<T,Eigen::Dynamic,1> KV; igl::find(K,KI,KJ,KV); Eigen::Matrix<int,Eigen::Dynamic,1> JI; Eigen::Matrix<int,Eigen::Dynamic,1> JJ; Eigen::Matrix<T,Eigen::Dynamic,1> JV; igl::find(J,JI,JJ,JV); int nnz = JV.size() + MV.size() + KV.size(); Eigen::Matrix<int,Eigen::Dynamic,1> UI(nnz); Eigen::Matrix<int,Eigen::Dynamic,1> UJ(nnz); Eigen::Matrix<T,Eigen::Dynamic,1> UV(nnz); UI << JJ, MI, (KJ.array() + n).matrix(); UJ << JI, (MJ.array() + n).matrix(), (KI.array() + n).matrix(); UV << JV, MV, KV*-1; igl::sparse(UI,UJ,UV,U); Eigen::Matrix<int,Eigen::Dynamic,1> LI(nnz); Eigen::Matrix<int,Eigen::Dynamic,1> LJ(nnz); Eigen::Matrix<T,Eigen::Dynamic,1> LV(nnz); LI << JI, (MJ.array() + n).matrix(), (KI.array() + n).matrix(); LJ << JJ, MI, (KJ.array() + n).matrix(); LV << JV, MV, KV; igl::sparse(LI,LJ,LV,L); } return true; #endif }
void igl::crouzeix_raviart_cotmatrix( const Eigen::MatrixBase<DerivedV> & V, const Eigen::MatrixBase<DerivedF> & F, const Eigen::MatrixBase<DerivedE> & E, const Eigen::MatrixBase<DerivedEMAP> & EMAP, Eigen::SparseMatrix<LT> & L) { // number of rows const int m = F.rows(); // Element simplex size const int ss = F.cols(); // Mesh should be edge-manifold assert(F.cols() != 3 || is_edge_manifold(F)); typedef Eigen::Matrix<LT,Eigen::Dynamic,Eigen::Dynamic> MatrixXS; MatrixXS C; cotmatrix_entries(V,F,C); Eigen::MatrixXi F2E(m,ss); { int k =0; for(int c = 0;c<ss;c++) { for(int f = 0;f<m;f++) { F2E(f,c) = k++; } } } // number of entries inserted per facet const int k = ss*(ss-1)*2; std::vector<Eigen::Triplet<LT> > LIJV;LIJV.reserve(k*m); Eigen::VectorXi LI(k),LJ(k),LV(k); // Compensation factor to match scales in matlab version double factor = 2.0; switch(ss) { default: assert(false && "unsupported simplex size"); case 3: factor = 4.0; LI<<0,1,2,1,2,0,0,1,2,1,2,0; LJ<<1,2,0,0,1,2,0,1,2,1,2,0; LV<<2,0,1,2,0,1,2,0,1,2,0,1; break; case 4: factor *= -1.0; LI<<0,3,3,3,1,2,1,0,1,2,2,0,0,3,3,3,1,2,1,0,1,2,2,0; LJ<<1,0,1,2,2,0,0,3,3,3,1,2,0,3,3,3,1,2,1,0,1,2,2,0; LV<<2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1; break; } for(int f=0;f<m;f++) { for(int c = 0;c<k;c++) { LIJV.emplace_back( EMAP(F2E(f,LI(c))), EMAP(F2E(f,LJ(c))), (c<(k/2)?-1.:1.) * factor *C(f,LV(c))); } } L.resize(E.rows(),E.rows()); L.setFromTriplets(LIJV.begin(),LIJV.end()); }