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;
}
Example #4
0
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;
}