// Copyright 2013 - Christian Schüller 2013, schuellc@inf.ethz.ch // Interactive Geometry Lab - ETH Zurich #include "Dirichlet_LIMSolver3D.h" #include "TetrahedronMesh.h" #define IGL_HEADER_ONLY #include "igl/adjacency_matrix.h" #include "igl/cotmatrix.h" #include "igl/massmatrix.h" Dirichlet_LIMSolver3D::Dirichlet_LIMSolver3D() { } Dirichlet_LIMSolver3D::~Dirichlet_LIMSolver3D() { } void Dirichlet_LIMSolver3D::debugOutput(std::stringstream& info) { std::cout << "LP:" << info.str() << "\n"; } void Dirichlet_LIMSolver3D::prepareProblemData(std::vector& hessRowIdx, std::vector& hessColIdx) { const int numNodes = mesh->InitalVertices->rows(); const int numTets = mesh->Tetrahedra->rows(); Eigen::SparseMatrix tempL; Eigen::SparseMatrix M; igl::massmatrix(*mesh->InitalVertices,*mesh->Tetrahedra,igl::MASSMATRIX_TYPE_BARYCENTRIC, M); igl::cotmatrix(*mesh->InitalVertices, *mesh->Tetrahedra,tempL); tempL *= -1; // Create L matrix L.resize(numVariables,numVariables); std::vector > triplets; for (int k=0;k::InnerIterator it(tempL,k);it;++it) { int row = 3*it.row(); int col = 3*it.col(); triplets.push_back(Eigen::Triplet(row,col,it.value())); triplets.push_back(Eigen::Triplet(row+1,col+1,it.value())); triplets.push_back(Eigen::Triplet(row+2,col+2,it.value())); } } L.setFromTriplets(triplets.begin(), triplets.end()); TetrahedronVertexIdx.resize(12,mesh->Tetrahedra->rows()); for (int k=0;k::InnerIterator it(L,k);it;++it) { int row = it.row(); int col = it.col(); // std::sort for upper triangule matrix if(row <= col) { hessRowIdx.push_back(row); hessColIdx.push_back(col); } } } } double Dirichlet_LIMSolver3D::computeFunction(const Eigen::Matrix& x) { // laplacian energy function f(v) = (v-p)'L(v-p) Eigen::VectorXd vv0 = x-initialNodes; return Divider * 0.5 * vv0.transpose() * L * vv0; } void Dirichlet_LIMSolver3D::computeGradient(const Eigen::Matrix& x, Eigen::Matrix& grad) { // laplacian grad = L * (x-initialNodes) * Divider; } void Dirichlet_LIMSolver3D::computeHessian(const Eigen::Matrix& x, const Eigen::Matrix& hess) { // laplacian int numElem = 0; for (int k=0;k::InnerIterator it(L,k);it;++it) { if(it.row() <= it.col()) *hess[numElem++] = it.value() * Divider; } } }