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); }
//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; }