1+ from os import path
2+
13from fenics import *
2- from ffc .plot import PointSecondDerivative
34from mshr import *
4- from os import path
55
6- def navier_stokes (mesh , boundaries , nu , pin , pout , inflow_marker , outflow_marker , no_slip_marker ):
76
8- # discrete function space
7+ def navier_stokes (mesh , boundaries , nu , pin , pout , inflow_marker , outflow_marker , no_slip_marker ):
8+ # discrete function space
99 P2 = VectorElement ("Lagrange" , mesh .ufl_cell (), 2 )
1010 P1 = FiniteElement ("Lagrange" , mesh .ufl_cell (), 1 )
1111
1212 TH = MixedElement ([P2 , P1 ])
13- W = FunctionSpace (mesh , TH )
13+ W = FunctionSpace (mesh , TH )
1414
1515 up = Function (W )
16- (u ,p ) = split (up )
17- (v ,q ) = TestFunctions (W )
16+ (u , p ) = split (up )
17+ (v , q ) = TestFunctions (W )
1818
1919 # boundary conditions
20- bcu_noslip = DirichletBC (W .sub (0 ), Constant ((0.0 ,0.0 ,0.0 )), boundaries , no_slip_marker [0 ])
21-
22- dx = Measure ('dx' , domain = mesh )
23- ds = Measure ('ds' , domain = mesh , subdomain_data = boundaries )
20+ bcu_noslip = DirichletBC (W .sub (0 ), Constant ((0.0 , 0.0 , 0.0 )), boundaries , no_slip_marker [0 ])
21+
22+ dx = Measure ('dx' , domain = mesh )
23+ ds = Measure ('ds' , domain = mesh , subdomain_data = boundaries )
24+
25+ n = FacetNormal (mesh )
26+ nu = Constant (nu )
27+ f = Constant ((0 , 0 , 0 ))
2428
25- n = FacetNormal (mesh )
26- nu = Constant (nu )
27- f = Constant ((0 ,0 ,0 ))
29+ a = Constant (0.5 * nu ) * inner (D (u ), D (v )) * dx
30+ a += - div (v ) * p * dx + q * div (u ) * dx + dot (dot (u , nabla_grad (u )), v ) * dx
2831
29- a = Constant (0.5 * nu )* inner (D (u ), D (v ))* dx
30- a += - div (v )* p * dx + q * div (u )* dx + dot (dot (u , nabla_grad (u )),v )* dx
31-
32- L = dot (f , v )* dx
32+ L = dot (f , v ) * dx
3333
3434 for im in inflow_marker :
35- a += - Constant (nu )* dot (nabla_grad (u )* n , v )* ds (im )
36- L += - Constant (pin )* dot (n ,v ) * ds (im )
37-
35+ a += - Constant (nu ) * dot (nabla_grad (u ) * n , v ) * ds (im )
36+ L += - Constant (pin ) * dot (n , v ) * ds (im )
37+
3838 for om in outflow_marker :
39- a += - Constant (nu )* dot (nabla_grad (u )* n , v )* ds (om )
40- L += - Constant (pout )* dot (n ,v ) * ds (om )
39+ a += - Constant (nu ) * dot (nabla_grad (u ) * n , v ) * ds (om )
40+ L += - Constant (pout ) * dot (n , v ) * ds (om )
4141
42-
43- # solve
42+ # solve
4443 F = a - L
45- dF = derivative (F ,up )
44+ dF = derivative (F , up )
4645
47- PETScOptions .set ("mat_mumps_icntl_4" , 1 ) # level of printing from the solver (0-4)
48- PETScOptions .set ("mat_mumps_icntl_14" , 300 ) # percentage increase in the working space wrt memory
49- problem = NonlinearVariationalProblem (F , up , bcu_noslip , dF )
46+ PETScOptions .set ("mat_mumps_icntl_4" , 1 ) # level of printing from the solver (0-4)
47+ PETScOptions .set ("mat_mumps_icntl_14" , 300 ) # percentage increase in the working space wrt memory
48+ problem = NonlinearVariationalProblem (F , up , bcu_noslip , dF )
5049 solver = NonlinearVariationalSolver (problem )
5150 prm = solver .parameters
5251 prm ['newton_solver' ]['absolute_tolerance' ] = 5E-8
@@ -60,34 +59,37 @@ def navier_stokes(mesh, boundaries, nu, pin, pout, inflow_marker, outflow_marker
6059
6160 return u , p
6261
62+
6363def make_pipe_mesh (radius , nelem ):
6464 # define a cylinder domain
65- cylinder = Cylinder (Point (0 ,0 , 0 ), Point (1 ,0 , 0 ), radius ,radius )
65+ cylinder = Cylinder (Point (0 , 0 , 0 ), Point (1 , 0 , 0 ), radius , radius )
6666 geometry = cylinder
6767 # define the mesh
6868 mesh = generate_mesh (geometry , nelem )
69- boundaries = MeshFunction ('size_t' , mesh , mesh .topology ().dim ()- 1 )
69+ boundaries = MeshFunction ('size_t' , mesh , mesh .topology ().dim () - 1 )
7070 boundaries .set_all (0 )
71+
7172 # mark the inflow, outflow and the walls
7273 class Noslip (SubDomain ):
7374 def inside (self , x , on_boundary ):
74- return on_boundary and x [1 ]** 2 + x [2 ]** 2 > 0.95 * radius ** 2
75+ return on_boundary and x [1 ] ** 2 + x [2 ] ** 2 > 0.95 * radius ** 2
76+
7577 class Inflow (SubDomain ):
7678 def inside (self , x , on_boundary ):
77- return on_boundary and near (x [0 ],0 )
79+ return on_boundary and near (x [0 ], 0 )
7880
7981 class Outflow (SubDomain ):
8082 def inside (self , x , on_boundary ):
81- return on_boundary and near (x [0 ],1 )
83+ return on_boundary and near (x [0 ], 1 )
8284
8385 velocity = Noslip ()
8486 velocity .mark (boundaries , 1 )
8587
8688 pressure_inflow = Inflow ()
87- pressure_inflow .mark (boundaries ,2 )
89+ pressure_inflow .mark (boundaries , 2 )
8890
8991 pressure_outflow = Outflow ()
90- pressure_outflow .mark (boundaries ,3 )
92+ pressure_outflow .mark (boundaries , 3 )
9193 return mesh , boundaries
9294
9395
@@ -113,38 +115,38 @@ def D(u):
113115 grad_u = grad (u )
114116 return grad_u + grad_u .T
115117
116- if __name__ == '__main__' :
117- pin = 2.0
118+
119+ if __name__ == '__main__' :
120+ pin = 2.0
118121 pout = 1.0
119- mu = 1.0
120- radius = 1.0
122+ mu = 1.0
123+ radius = 1.0
121124 nelem = 15
122125
123126 poise_case = 0
124127 artery_case = 1
125128
126129 if poise_case :
127- # Make pipe mesh so we can solve for Poiseuille flow
128- mesh , boundaries = make_pipe_mesh (radius , nelem )
129- inflow_marker = [2 ]
130- outflow_marker = [3 ]
131- no_slip_marker = [1 ]
130+ # Make pipe mesh so we can solve for Poiseuille flow
131+ mesh , boundaries = make_pipe_mesh (radius , nelem )
132+ inflow_marker = [2 ]
133+ outflow_marker = [3 ]
134+ no_slip_marker = [1 ]
132135
133136 if artery_case :
134- # Get artery mesh
135- case_names = ["C0015_healthy" , "C0015_terminal" , "C0019" , "C0065_healthy" , "C0065_saccular" ]
136- case = 3
137- mesh_name = path .join ("models" , case_names [case ] + ".xml.gz" )
138- mesh = Mesh (mesh_name )
139- boundaries = MeshFunction ("size_t" , mesh , mesh .geometry ().dim () - 1 , mesh .domains ())
140- inflow_marker , outflow_marker , no_slip_marker = get_marker_ids (case )
137+ # Get artery mesh
138+ case_names = ["C0015_healthy" , "C0015_terminal" , "C0019" , "C0065_healthy" , "C0065_saccular" ]
139+ case = 3
140+ mesh_name = path .join ("models" , case_names [case ] + ".xml.gz" )
141+ mesh = Mesh (mesh_name )
142+ boundaries = MeshFunction ("size_t" , mesh , mesh .geometry ().dim () - 1 , mesh .domains ())
143+ inflow_marker , outflow_marker , no_slip_marker = get_marker_ids (case )
141144
142145 # Solve for NS flow in mesh domain
143- u ,p = navier_stokes (mesh , boundaries , mu , pin , pout , inflow_marker , outflow_marker , no_slip_marker )
144-
146+ u , p = navier_stokes (mesh , boundaries , mu , pin , pout , inflow_marker , outflow_marker , no_slip_marker )
145147
146- file = File ("Plots/u.pvd" )
148+ file = File ("Plots/u.pvd" )
147149 file << u
148150
149- file = File ("Plots/p.pvd" )
151+ file = File ("Plots/p.pvd" )
150152 file << p
0 commit comments