303_LaplaceEquation.py 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import igl
  2. V = igl.eigen.MatrixXd()
  3. F = igl.eigen.MatrixXi()
  4. igl.readOFF("../tutorial/shared/camelhead.off",V,F)
  5. # Find boundary edges
  6. E = igl.eigen.MatrixXi()
  7. igl.boundary_facets(F,E);
  8. # Find boundary vertices
  9. b = igl.eigen.MatrixXi()
  10. IA = igl.eigen.MatrixXi()
  11. IC = igl.eigen.MatrixXi()
  12. igl.unique(E,b,IA,IC);
  13. # List of all vertex indices
  14. vall = igl.eigen.MatrixXi()
  15. vin = igl.eigen.MatrixXi()
  16. igl.coloni(0,V.rows()-1,vall)
  17. # List of interior indices
  18. igl.setdiff(vall,b,vin,IA)
  19. # Construct and slice up Laplacian
  20. L = igl.eigen.SparseMatrixd()
  21. L_in_in = igl.eigen.SparseMatrixd()
  22. L_in_b = igl.eigen.SparseMatrixd()
  23. igl.cotmatrix(V,F,L)
  24. igl.slice(L,vin,vin,L_in_in)
  25. igl.slice(L,vin,b,L_in_b)
  26. # Dirichlet boundary conditions from z-coordinate
  27. bc = igl.eigen.MatrixXd()
  28. Z = V.col(2)
  29. igl.slice(Z,b,bc)
  30. # Solve PDE
  31. solver = igl.eigen.SimplicialLLTsparse(-L_in_in)
  32. Z_in = solver.solve(L_in_b*bc)
  33. # slice into solution
  34. igl.slice_into(Z_in,vin,Z)
  35. # Alternative, short hand
  36. mqwf = igl.min_quad_with_fixed_data()
  37. # Linear term is 0
  38. B = igl.eigen.MatrixXd()
  39. B.setZero(V.rows(),1);
  40. # Empty constraints
  41. Beq = igl.eigen.MatrixXd()
  42. Aeq = igl.eigen.SparseMatrixd()
  43. # Our cotmatrix is _negative_ definite, so flip sign
  44. igl.min_quad_with_fixed_precompute(-L,b,Aeq,True,mqwf)
  45. igl.min_quad_with_fixed_solve(mqwf,B,bc,Beq,Z)
  46. # Pseudo-color based on solution
  47. C = igl.eigen.MatrixXd()
  48. igl.jet(Z,True,C)
  49. # Plot the mesh with pseudocolors
  50. viewer = igl.viewer.Viewer()
  51. viewer.data.set_mesh(V, F)
  52. viewer.core.show_lines = False
  53. viewer.data.set_colors(C)
  54. viewer.launch()