1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Derivative of Volume of a Closed shell wrt position of the points
5
+ """
6
+
7
+ import vtk as v
8
+ import numpy as np
9
+ import matplotlib .pyplot as plt
10
+
11
+ """
12
+ The input of this class should be a polydata type with consistently labeled
13
+ triangles. It returns volume of the closed mesh formed by the triangles.
14
+ """
15
+ def Vol (poly ):
16
+ cells = poly .GetPolys ()
17
+ cells .InitTraversal ()
18
+ verts = v .vtkIdList ()
19
+ V = 0.0
20
+ while ( cells .GetNextCell ( verts ) ):
21
+ coords = []
22
+ assert ( verts .GetNumberOfIds () == 3 )
23
+ for i in range ( 3 ):
24
+ coords .append ( poly .GetPoint ( verts .GetId (i ) ) )
25
+ a ,b ,c = coords
26
+ V += (1 / 6 )* np .dot ( a , np .cross (b ,c ) )
27
+ return V
28
+
29
+ """
30
+ The input to this class is a polydata object with triangles ordered
31
+ consistently. It returns a Matrix with N rows and 3 columns where N is the
32
+ number of points in the polydata
33
+ """
34
+ def VolDiff (poly ):
35
+ N = poly .GetNumberOfPoints ()
36
+ poly .BuildLinks ()
37
+ Out = np .zeros ( (N ,3 ) )
38
+ cells = poly .GetPolys ()
39
+ cells .InitTraversal ()
40
+ cellPts = v .vtkIdList ()
41
+ while ( cells .GetNextCell (cellPts ) ):
42
+ ida = cellPts .GetId (0 )
43
+ idb = cellPts .GetId (1 )
44
+ idc = cellPts .GetId (2 )
45
+ a = poly .GetPoint ( ida )
46
+ b = poly .GetPoint ( idb )
47
+ c = poly .GetPoint ( idc )
48
+ dVa = np .array ([b [1 ]* c [2 ]- b [2 ]* c [1 ],b [2 ]* c [0 ]- b [0 ]* c [2 ],b [0 ]* c [1 ]- b [1 ]* c [0 ]])
49
+ dVb = np .array ([a [2 ]* c [1 ]- a [1 ]* c [2 ],a [0 ]* c [2 ]- a [2 ]* c [0 ],a [1 ]* c [0 ]- a [0 ]* c [1 ]])
50
+ dVc = np .array ([a [1 ]* b [2 ]- a [2 ]* b [1 ],a [2 ]* b [0 ]- a [0 ]* b [2 ],a [0 ]* b [1 ]- a [1 ]* b [0 ]])
51
+ Out [ida ,:] += (dVa * (1 / 6 ))
52
+ Out [idb ,:] += (dVb * (1 / 6 ))
53
+ Out [idc ,:] += (dVc * (1 / 6 ))
54
+ return Out
55
+
56
+ """
57
+ Consistency test
58
+ """
59
+ sp = v .vtkSphereSource ()
60
+ sp .SetCenter (0.0 ,0.0 ,0.0 )
61
+ sp .SetRadius (1.0 )
62
+ sp .SetThetaResolution (5 )
63
+ sp .SetPhiResolution (5 )
64
+ sp .Update ()
65
+ pd = sp .GetOutput ()
66
+ writer = v .vtkPolyDataWriter ()
67
+ writer .SetFileName ('Sphere.vtk' )
68
+ writer .SetInputData (pd )
69
+ writer .Write ()
70
+
71
+ N = pd .GetNumberOfPoints ()
72
+ hvec = np .logspace (- 7 ,- 2 )
73
+ err = np .zeros (50 )
74
+ dV = VolDiff (pd )
75
+ points = pd .GetPoints ()
76
+ for z in range (50 ):
77
+ h = hvec [z ]
78
+ dVh = np .zeros ((N ,3 ))
79
+ errh = np .zeros (N )
80
+ for i in range (N ):
81
+ pt = np .array (points .GetPoint (i ))
82
+ for j in range (3 ):
83
+ pt [j ] += h
84
+ points .SetPoint (i , pt )
85
+ Vp = Vol (pd )
86
+ pt [j ] += - 2 * h
87
+ points .SetPoint (i , pt )
88
+ Vm = Vol (pd )
89
+ dVh [i ,j ] = (Vp - Vm )/ (2 * h )
90
+ pt [j ] += - 2 * h
91
+ points .SetPoint (i , pt )
92
+ errh [i ] = np .linalg .norm (dV [i ,:] - dVh [i ,:])
93
+ err [z ] = np .max ( errh )
94
+
95
+ fig , ax = plt .subplots ()
96
+ ax .loglog (hvec ,err )
97
+
0 commit comments