| 237 | } |
| 238 | |
| 239 | ZSparseMatrix Assembler2D::getBdLaplacianMatrix() { |
| 240 | typedef Eigen::Triplet<double> T; |
| 241 | std::vector<T> triplets; |
| 242 | |
| 243 | size_t num_bdv = m_mesh->getNbrBoundaryNodes(); |
| 244 | size_t num_bdf = m_mesh->getNbrBoundaryFaces(); |
| 245 | |
| 246 | // Compute lumped mass |
| 247 | VectorF lumped_mass(num_bdv); |
| 248 | for (size_t i=0; i<num_bdv; i++) { |
| 249 | VectorI neighbor_faces = m_mesh->getBoundaryNodeAdjacentBoundaryFaces(i); |
| 250 | assert(neighbor_faces.size() == 2); |
| 251 | |
| 252 | double total_weight = |
| 253 | m_mesh->getBoundaryFaceArea(neighbor_faces[0]) + |
| 254 | m_mesh->getBoundaryFaceArea(neighbor_faces[1]); |
| 255 | lumped_mass[i] = 0.5 * total_weight; |
| 256 | } |
| 257 | |
| 258 | // Compute laplacian matrix. |
| 259 | for (size_t i=0; i<num_bdf; i++) { |
| 260 | VectorI face = m_mesh->getBoundaryFace(i); |
| 261 | assert(face.size() == 2); |
| 262 | |
| 263 | double l = m_mesh->getBoundaryFaceArea(i); |
| 264 | size_t v1 = m_mesh->getBoundaryIndex(face[0]); |
| 265 | size_t v2 = m_mesh->getBoundaryIndex(face[1]); |
| 266 | double weight = 1.0 / l; |
| 267 | triplets.push_back(T(v1, v1, -weight / lumped_mass[v1])); |
| 268 | triplets.push_back(T(v1, v2, weight / lumped_mass[v1])); |
| 269 | triplets.push_back(T(v2, v1, weight / lumped_mass[v2])); |
| 270 | triplets.push_back(T(v2, v2, -weight / lumped_mass[v2])); |
| 271 | } |
| 272 | |
| 273 | Eigen::SparseMatrix<double> Lb = Eigen::SparseMatrix<double>(num_bdv, num_bdv); |
| 274 | Lb.setFromTriplets(triplets.begin(), triplets.end()); |
| 275 | return ZSparseMatrix(Lb); |
| 276 | } |
nothing calls this directly
no test coverage detected