Mat3d ReducedStVKCubatureForceModel::computeDs(const double *reduced_pos) const {//reduced dis is 12*1 for each element Mat3d Ds(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0); for(int i=0;i<3;++i) { Ds[0][i]=reduced_pos[3*i]-reduced_pos[9]; Ds[1][i]=reduced_pos[3*i+1]-reduced_pos[10]; Ds[2][i]=reduced_pos[3*i+2]-reduced_pos[11]; } return Ds; }
void MeshTransferer::computeS0grad() { int nfaces = S0.faces.nrow; S0grad.resize(nfaces); Ds.resize(nfaces); for(int j=0;j<nfaces;++j) { // assign the reshaped gradient to the j-th row of Sgrad[i] auto S0ij_d = triangleGradient2(S0, j); S0grad[j] = S0ij_d.first; Ds(j) = S0ij_d.second; } }
Mat3d ReducedStVKCubatureForceModel::computeElasticDs(const double *ele_deformed_pos) const {//reduced dis is 12*1 for each element Mat3d Ds(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0); for(int i=0;i<3;++i) { // Ds[0][i]=ele_deformed_pos[3*i]-ele_deformed_pos[9]; // Ds[1][i]=ele_deformed_pos[3*i+1]-ele_deformed_pos[10]; // Ds[2][i]=ele_deformed_pos[3*i+2]-ele_deformed_pos[11]; for(int j=0;j<3;++j) Ds[j][i]=ele_deformed_pos[3*i+j]-ele_deformed_pos[9+j]; } // std::cout<<"ele_deformed_pos:\n"; // for(int i=0;i<12;++i) // { // std::cout<<ele_deformed_pos[i]<<"\n"; // } return Ds; }
std::vector<int> mpsxx::compress_qc_mpos ( const std::vector<int>& groups, std::vector<std::vector<btas::QSTArray<double,4,fermion>>>& mpos, std::vector<std::vector<btas::QSTArray<double,4,fermion>>>& comp) { const size_t MAXBUF = 200; size_t ig; std::set<int> ng(groups.begin(),groups.end()); comp.resize(ng.size()); std::vector<std::vector<size_t>> Ds(ng.size()); std::cout << "\t\tThere are " << ng.size() << " groups to be separatory compressed." << std::endl; ig = 0; for(auto it = ng.begin(); it != ng.end(); ++it, ++ig) { int label = *it; std::cout << "\t\tCompressing operator group " << label << std::endl; size_t t = 0; for(; t < groups.size() && groups[t] != label; ++t); size_t ngen = 1; size_t nbuf = 1; comp[ig].swap(mpos[t]); ++t; size_t norb = comp[ig].size(); for(; t < groups.size(); ++t) { if(groups[t] == label) { ++ngen; { btas::QSTArray<double,4,fermion> temp(comp[ig][0]); comp[ig][0].clear(); btas::IVector<3> traceIdx = {0,1,2}; btas::QSTdsum(temp,mpos[t][0],traceIdx,comp[ig][0]); } for(size_t s = 1; s < norb-1; ++s) { btas::QSTArray<double,4,fermion> temp(comp[ig][s]); comp[ig][s].clear(); btas::IVector<2> traceIdx = {1,2}; btas::QSTdsum(temp,mpos[t][s],traceIdx,comp[ig][s]); } { btas::QSTArray<double,4,fermion> temp(comp[ig][norb-1]); comp[ig][norb-1].clear(); btas::IVector<3> traceIdx = {1,2,3}; btas::QSTdsum(temp,mpos[t][norb-1],traceIdx,comp[ig][norb-1]); } // deallocation std::vector<btas::QSTArray<double,4,fermion>>().swap(mpos[t]); if(++nbuf >= MAXBUF) { std::cout << "\t\t\tdo compress mpos up to " << std::setw(6) << t << std::endl; Ds[ig] = compress_mpos_cycle(comp[ig]); std::cout << "\t\t\t"; for(size_t s = 0; s < Ds[ig].size(); ++s) std::cout << Ds[ig][s] << ":"; std::cout << std::endl; nbuf = 1; } } } // if(nbuf > 1) Ds[ig] = compress_mpos_cycle(comp[ig]); std::cout << "\t\t\t"; for(size_t s = 0; s < Ds[ig].size(); ++s) std::cout << Ds[ig][s] << ":"; std::cout << ":compressed by " << ngen << " terms." << std::endl; } std::cout << "\t\tCheck boundary size..." << std::endl; ig = 0; for(auto it = ng.begin(); it != ng.end(); ++it, ++ig) { std::cout << "\t\t\t"; for(size_t s = 0; s < Ds[ig].size(); ++s) std::cout << Ds[ig][s] << ":"; std::cout << ":group = " << *it << std::endl; } return std::vector<int>(ng.begin(),ng.end()); }
BasicMesh MeshTransferer::transfer(const vector<PhGUtils::Matrix3x3d> &S1grad) { if( !(S0set && T0set) ) { throw "S0 or T0 not set."; } auto &S = S1grad; auto &T = T0grad; int nfaces = S0.faces.nrow; int nverts = S0.verts.nrow; // assemble sparse matrix A int nrowsA = nfaces * 3; int nsv = stationary_vertices.size(); int nrowsC = nsv; int nrows = nrowsA + nrowsC; int ncols = nverts; int ntermsA = nfaces*9; int ntermsC = stationary_vertices.size(); int nterms = ntermsA + ntermsC; SparseMatrix A(nrows, ncols, nterms); // fill in the deformation gradient part for(int i=0, ioffset=0;i<nfaces;++i) { /* * Ai: * 1 2 3 4 5 ... nfaces*3 * 1 2 3 4 5 ... nfaces*3 * 1 2 3 4 5 ... nfaces*3 * Ai = reshape(Ai, 1, nfaces*9) * * Aj = reshape(repmat(S0.faces', 3, 1), 1, nfaces*9) * Av = reshape(cell2mat(T)', 1, nfaces*9) */ int *f = S0.faces.rowptr(i); auto Ti = T[i]; A.append(ioffset, f[0], Ti(0)); A.append(ioffset, f[1], Ti(1)); A.append(ioffset, f[2], Ti(2)); ++ioffset; A.append(ioffset, f[0], Ti(3)); A.append(ioffset, f[1], Ti(4)); A.append(ioffset, f[2], Ti(5)); ++ioffset; A.append(ioffset, f[0], Ti(6)); A.append(ioffset, f[1], Ti(7)); A.append(ioffset, f[2], Ti(8)); ++ioffset; } // fill in the lower part of A, stationary vertices part for(int i=0;i<nsv;++i) { A.append(nrowsA+i, stationary_vertices[i], 1); } ofstream fA("A.txt"); fA<<A; fA.close(); // fill in c matrix DenseMatrix c(nrows, 3); for(int i=0;i<3;++i) { for(int j=0, joffset=0;j<nfaces;++j) { auto &Sj = S[j]; c(joffset, i) = Sj(0, i); ++joffset; c(joffset, i) = Sj(1, i); ++joffset; c(joffset, i) = Sj(2, i); ++joffset; } } for(int i=0;i<3;++i) { for(int j=0, joffset=nrowsA;j<nsv;++j,++joffset) { auto vj = T0.verts.rowptr(stationary_vertices[j]); c(joffset, i) = vj[i]; } } cholmod_sparse *G = A.to_sparse(); cholmod_sparse *Gt = cholmod_transpose(G, 2, global::cm); // compute GtD // just multiply Dsi to corresponding elemenets double *Gtx = (double*)Gt->x; const int* Gtp = (const int*)(Gt->p); for(int i=0;i<nrowsA;++i) { int fidx = i/3; for(int j=Gtp[i];j<Gtp[i+1];++j) { Gtx[j] *= Ds(fidx); } } // compute GtDG cholmod_sparse *GtDG = cholmod_ssmult(Gt, G, 0, 1, 1, global::cm); GtDG->stype = 1; // compute GtD * c cholmod_dense *GtDc = cholmod_allocate_dense(ncols, 3, ncols, CHOLMOD_REAL, global::cm); double alpha[2] = {1, 0}; double beta[2] = {0, 0}; cholmod_sdmult(Gt, 0, alpha, beta, c.to_dense(), GtDc, global::cm); // solve for GtDG \ GtDc cholmod_factor *L = cholmod_analyze(GtDG, global::cm); cholmod_factorize(GtDG, L, global::cm); cholmod_dense *x = cholmod_solve(CHOLMOD_A, L, GtDc, global::cm); // make a copy of T0 BasicMesh Td = T0; // change the vertices with x double *Vx = (double*)x->x; for(int i=0;i<nverts;++i) { Td.verts(i, 0) = Vx[i]; Td.verts(i, 1) = Vx[i+nverts]; Td.verts(i, 2) = Vx[i+nverts*2]; } // release memory cholmod_free_sparse(&G, global::cm); cholmod_free_sparse(&Gt, global::cm); cholmod_free_sparse(&GtDG, global::cm); cholmod_free_dense(&GtDc, global::cm); cholmod_free_factor(&L, global::cm); cholmod_free_dense(&x, global::cm); return Td; }