()
| 119 | return div_X; |
| 120 | |
| 121 | def main(): |
| 122 | args = parse_args(); |
| 123 | mesh = pymesh.load_mesh(args.input_mesh); |
| 124 | assert(mesh.dim == 3); |
| 125 | assert(mesh.vertex_per_face == 3); |
| 126 | |
| 127 | compute_edge_field(mesh); |
| 128 | assert(mesh.has_attribute("edges")); |
| 129 | compute_cotan_field(mesh); |
| 130 | assert(mesh.has_attribute("cotan")); |
| 131 | compute_area_and_normal_field(mesh); |
| 132 | assert(mesh.has_attribute("vertex_area")); |
| 133 | assert(mesh.has_attribute("face_normal")); |
| 134 | |
| 135 | assembler = pymesh.Assembler(mesh); |
| 136 | L = assembler.assemble("laplacian") * -1; |
| 137 | A = assembler.assemble("mass"); |
| 138 | G = assembler.assemble("gradient"); |
| 139 | |
| 140 | t = np.mean(mesh.get_attribute("face_area").ravel()); |
| 141 | rhs = np.zeros(mesh.num_vertices); |
| 142 | rhs[args.source] = 1.0; |
| 143 | |
| 144 | u = scipy.sparse.linalg.spsolve(A - t*L, rhs); |
| 145 | mesh.add_attribute("u"); |
| 146 | mesh.set_attribute("u", u); |
| 147 | |
| 148 | grad_u = (G * u).reshape((-1, 3), order="C"); |
| 149 | grad_u_2 = compute_gradient(mesh, u); |
| 150 | mesh.add_attribute("grad_u"); |
| 151 | mesh.set_attribute("grad_u", grad_u.ravel()); |
| 152 | |
| 153 | X = -grad_u / norm(grad_u, axis=1)[...,np.newaxis]; |
| 154 | mesh.add_attribute("X"); |
| 155 | mesh.set_attribute("X", X.ravel()); |
| 156 | |
| 157 | div_X = compute_divergence(mesh, X); |
| 158 | mesh.add_attribute("div_X"); |
| 159 | mesh.set_attribute("div_X", div_X); |
| 160 | |
| 161 | phi = scipy.sparse.linalg.spsolve(L, div_X); |
| 162 | phi = phi - np.amin(phi); |
| 163 | mesh.add_attribute("phi"); |
| 164 | mesh.set_attribute("phi", phi); |
| 165 | |
| 166 | pymesh.save_mesh(args.output_mesh, mesh, "u", "grad_u", "X", "div_X", "phi"); |
| 167 | |
| 168 | |
| 169 | if __name__ == "__main__": |
no test coverage detected