void StVKStiffnessMatrix::GetStiffnessMatrixTopology(SparseMatrix ** stiffnessMatrixTopology)
{
  int numVertices = volumetricMesh->getNumVertices();

  int * vertices = (int*) malloc (sizeof(int) * numElementVertices);

  // build skeleton of sparseMatrix
  SparseMatrixOutline * emptyMatrix = new SparseMatrixOutline(3 * numVertices);
  for (int el=0; el < volumetricMesh->getNumElements(); el++)
  {
    //if(el % 100 == 1)
      //printf(".");

    for(int ver=0; ver<numElementVertices; ver++)
      vertices[ver] = volumetricMesh->getVertexIndex(el, ver);

    for (int i=0; i<numElementVertices; i++)
      for (int j=0; j<numElementVertices; j++)
      {
        for(int k=0; k<3; k++)
          for(int l=0; l<3; l++)
          {
            // only add the entry if both vertices are free (non-fixed)
            // the corresponding elt is in row 3*i+k, column 3*j+l
            emptyMatrix->AddEntry( 3*vertices[i]+k, 3*vertices[j]+l, 0.0 );
          }
      }
  }
  //printf("\n");

  *stiffnessMatrixTopology = new SparseMatrix(emptyMatrix);
  delete(emptyMatrix);

  free(vertices);
}
void GenerateMassMatrix::computeMassMatrix(
  VolumetricMesh * volumetricMesh, SparseMatrix ** massMatrix, bool inflate3Dim)
{
  int n = volumetricMesh->getNumVertices();
  int numElementVertices = volumetricMesh->getNumElementVertices();
  double * buffer = (double*) malloc (sizeof(double) * numElementVertices * numElementVertices);

  SparseMatrixOutline * massMatrixOutline;
  if (!inflate3Dim)
  {
    massMatrixOutline = new SparseMatrixOutline(n);
    for(int el=0; el <volumetricMesh->getNumElements(); el++)
    {
      volumetricMesh->computeElementMassMatrix(el, buffer);
      for(int i=0; i < numElementVertices; i++)
        for(int j=0; j < numElementVertices; j++)
        {
          massMatrixOutline->AddEntry(volumetricMesh->getVertexIndex(el,i),volumetricMesh->getVertexIndex(el,j),  buffer[numElementVertices * j + i]);
        }
    }
  }
  else
  {
    massMatrixOutline = new SparseMatrixOutline(3*n);
    for(int el=0; el <volumetricMesh->getNumElements(); el++)
    {
      volumetricMesh->computeElementMassMatrix(el, buffer);
      for(int i=0; i < numElementVertices; i++)
        for(int j=0; j < numElementVertices; j++)
        {
          double entry = buffer[numElementVertices * j + i];
          int indexi = volumetricMesh->getVertexIndex(el,i);
          int indexj = volumetricMesh->getVertexIndex(el,j);
          massMatrixOutline->AddEntry(3*indexi+0, 3*indexj+0, entry);
          massMatrixOutline->AddEntry(3*indexi+1, 3*indexj+1, entry);
          massMatrixOutline->AddEntry(3*indexi+2, 3*indexj+2, entry);
        }
    }
  }

  (*massMatrix) = new SparseMatrix(massMatrixOutline);
  delete(massMatrixOutline);

  free(buffer);
}
void CorotationalLinearFEM::GetStiffnessMatrixTopology(SparseMatrix ** stiffnessMatrixTopology)
{
  SparseMatrixOutline * emptyMatrix = new SparseMatrixOutline(3 * numVertices);

  int numElements = tetMesh->getNumElements();
  for (int el=0; el < numElements; el++)
  {
    int vtxIndex[4];
    for(int vtx=0; vtx<4; vtx++)
      vtxIndex[vtx] = tetMesh->getVertexIndex(el, vtx);

    for (int i=0; i<4; i++)
      for (int j=0; j<4; j++)
      {
        // add 3x3 block corresponding to pair of vertices (i,j)
        for(int k=0; k<3; k++)
          for(int l=0; l<3; l++)
            emptyMatrix->AddEntry(3 * vtxIndex[i] + k, 3 * vtxIndex[j] + l, 0.0);
      }
  }

  *stiffnessMatrixTopology = new SparseMatrix(emptyMatrix);
  delete(emptyMatrix);
}
Beispiel #4
0
//static int iter=0;
void cgd(Mesh & m)
{
  int height=11*m.t.size()+6*m.v.size();
//  int height=2*m.t.size()+3*m.v.size();
//  int width = 3*(m.v.size());
  int width = 3*(m.v.size()+m.t.size());
  //nvar=m.v.size();
  std::cout << "compute mesh info\n";
  nvar=m.v.size()+m.t.size();
  std::vector<Plane>plane;
  get_plane(m,plane);
  add_v4(m);
  std::vector<Mat3>mat;
  vmat(m,mat);
  m.adjlist();

  CCS ccs;
  std::vector<double >b;
  std::cout << "compute matrix rows info\n";
  //b for smoothness matrix is 0
  //smooth_mat(m,mat,wS,ccs);
  vert_smooth_mat(m,wS,ccs,b);
  identity_mat(m, mat, wI, ccs , b);
  vertex_mat(m,wV0,ccs,b);
  planar_mat(m,plane,wPt,ccs);
  b.resize(height,0.0);
  SparseCCS* s = new SparseCCS(width, height, &ccs.vals[0], &ccs.rowInds[0], &ccs.colPtr[0]);
  SparseCCS* st = s->transposed();
  std::cout << "compute AA^T\n";
  SparseCCS* sst=s->multiply_LM(*st);
  SparseMatrixOutline *outline = new SparseMatrixOutline(width);
//printAB(ccs,b,0);
  double * ATb= s->operator* (&b[0]);

//  int rowcnt=sst->rows_count();
  int colcnt=sst->columns_count();
  const real * vals=sst->values();
  const int * row_indices=sst->row_indices();
  const int * col_pointers=sst->column_pointers();
  for(int ii=0; ii<colcnt; ii++) {
    for(int jj=col_pointers[ii]; jj<col_pointers[ii+1]; jj++) {
      outline->AddEntry(row_indices[jj],ii,vals[jj]);
    }
  }
  // delete s;
  delete st;
  delete sst;
  std::cout << "matrix assembly\n";
  SparseMatrix A(outline);
  delete outline;

  std::cout << "lin solve\n";
  CGSolver solver(&A);
  double * x=new double [width];
  vertex2arr(m,x);

  double eps = 1E-6;
  int maxIter = 50;

  int verbose = 0;
   int ret = solver.SolveLinearSystemWithJacobiPreconditioner(x, ATb, eps, maxIter, verbose);//
  //if(ret<0) {
  //  printf("optimization error\n");
  // }

  A.CheckLinearSystemSolution(x,ATb);
  printf("\n");
  array2vertex(x,m);

  delete []x;
  delete []ATb;
}