11
2+ using Test
23using Gridap
34using GridapEmbedded
45using Gridap. Geometry, Gridap. Arrays
@@ -40,94 +41,109 @@ function generate_mesh(n,R=0.4,x0=0.835)
4041 return cutgeo
4142end
4243
43- n = 12
44- cutgeo = generate_mesh (n)
45- bgmodel = get_background_model (cutgeo)
46-
47- order = 1
48- qdegree = 2 * (order+ 1 )
49-
50- Ω_ac = Triangulation (cutgeo,ACTIVE)
51- V = FESpace (Ω_ac,ReferenceFE (raviart_thomas,Float64,order); conformity= :Hdiv )
52- Q = FESpace (Ω_ac,ReferenceFE (lagrangian,Float64,order); conformity= :L2 )
53- X = MultiFieldFESpace ([V,Q])
54-
55- ptopo = PatchTopology (get_grid_topology (bgmodel), get_aggregates (cutgeo))
56- Ωp = PatchTriangulation (bgmodel, ptopo)
57- dΩp = Measure (Ωp, qdegree)
58-
59- Wd = FESpaces. PatchFESpace (bgmodel,Ωp,Float64,order;space= :RT )
60- Πd = projection_operator (ptopo, V, Wd, Ωp, dΩp)
61- W0 = FESpaces. PatchFESpace (bgmodel,Ωp,Float64,order;space= :Q )
62- Π0 = projection_operator (ptopo, Q, W0, Ωp, dΩp)
63- Π0div = div_projection_operator (ptopo, V, W0, Ωp, dΩp)
64-
65- Ω = Triangulation (cutgeo,PHYSICAL)
66- Ω_cut = Triangulation (cutgeo,CUT_IN)
67- Γ = EmbeddedBoundary (cutgeo)
68- Γu = EmbeddedBoundary (cutgeo, " disk" ," domain" )
69- Γp = EmbeddedBoundary (cutgeo, " plane" ," domain" )
44+ function driver (n,order,u_exact,p_exact,η= 1.0 ,γ= 10.0 ,τ= 10.0 )
45+ cutgeo = generate_mesh (n)
46+ bgmodel = get_background_model (cutgeo)
47+ qdegree = 2 * (order+ 1 )
48+
49+ Ω_ac = Triangulation (cutgeo,ACTIVE)
50+ V = FESpace (Ω_ac,ReferenceFE (raviart_thomas,Float64,order); conformity= :Hdiv )
51+ Q = FESpace (Ω_ac,ReferenceFE (lagrangian,Float64,order); conformity= :L2 )
52+ X = MultiFieldFESpace ([V,Q])
53+
54+ ptopo = PatchTopology (get_grid_topology (bgmodel), get_aggregates (cutgeo))
55+ Ωp = PatchTriangulation (bgmodel, ptopo)
56+
57+ Ω = Triangulation (cutgeo,PHYSICAL)
58+ Γu = EmbeddedBoundary (cutgeo, " disk" ," domain" )
59+ Γp = EmbeddedBoundary (cutgeo, " plane" ," domain" )
60+
61+ dΩ = Measure (Ω, qdegree)
62+ dΩp = Measure (Ωp, qdegree)
63+ dΓu = Measure (Γu, 2 * qdegree)
64+ dΓp = Measure (Γp, 2 * qdegree)
65+
66+ Wd = FESpaces. PatchFESpace (bgmodel,Ωp,Float64,order;space= :RT )
67+ Πd = projection_operator (ptopo, V, Wd, Ωp, dΩp)
68+ W0 = FESpaces. PatchFESpace (bgmodel,Ωp,Float64,order;space= :Q )
69+ Π0 = projection_operator (ptopo, Q, W0, Ωp, dΩp)
70+ Π0div = div_projection_operator (ptopo, V, W0, Ωp, dΩp)
71+
72+ f (x) = η* u_exact (x) + ∇ (p_exact)(x)
73+ g (x) = - (∇⋅ u_exact)(x)
74+
75+ h = γ/ n
76+ n_Γu = get_normal_vector (Γu)
77+ n_Γp = get_normal_vector (Γp)
78+ a (u,v) = ∫ (η* (u⋅ v))dΩ + ∫ (h* (u⋅ n_Γu)* (v⋅ n_Γu))dΓu
79+ b (u,q) = ∫ (- (∇⋅ u)* q)dΩ
80+ btilde (u,q) = b (u,q) + ∫ ((u⋅ n_Γu)* q)dΓu
81+ l ((v,q)) = ∫ (v⋅ f + g⋅ q)dΩ + ∫ (h* (v⋅ n_Γu)⋅ (u_exact⋅ n_Γu))dΓu - ∫ ((v⋅ n_Γp)* p_exact)dΓp
82+
83+ sd (u,v) = ∫ (τ* (u⋅ v))dΩp
84+ s0 (p,q) = ∫ (τ* p* q)dΩp
85+
86+ function weakform (x,y)
87+ u, p = x
88+ v, q = y
89+ Πu, Πv = Πd (u), Πd (v)
90+ Πp, Πq = Π0 (p), Π0 (q)
91+ divu, divv = ∇⋅ u, ∇⋅ v
92+ Πdivu, Πdivv = Π0div (u), Π0div (v)
93+ Xp = FESpaces. PatchFESpace (X,ptopo)
94+ data = FESpaces. collect_and_merge_cell_matrix_and_vector (
95+ (X, X , a (u,v) + btilde (v,p) + b (u,q) + sd (u,v) - s0 (divu,q) - s0 (divv,p), l (y)),
96+ (X, Xp , s0 (divu,Πq) + s0 (Πdivv,p) - sd (u,Πv), DomainContribution ()),
97+ (Xp, X , s0 (Πdivu,q) + s0 (divv,Πp) - sd (Πu,v), DomainContribution ()),
98+ (Xp, Xp, sd (Πu,Πv) - s0 (Πdivu,Πq) - s0 (Πdivv,Πp), DomainContribution ()),
99+ )
100+ assem = SparseMatrixAssembler (X,X)
101+ A, B = assemble_matrix_and_vector (assem,data)
102+ return AffineFEOperator (X,X,A,B)
103+ end
104+
105+ op = weakform (get_trial_fe_basis (X),get_fe_basis (X))
106+ uh, ph = solve (op)
107+
108+ eu = uh- u_exact
109+ ep = ph- p_exact
110+ l2_err_u = sqrt (sum (∫ ( eu ⋅ eu )dΩ))
111+ l2_err_p = sqrt (sum (∫ ( ep ⋅ ep )dΩ))
112+
113+ return cutgeo, uh, ph, l2_err_u, l2_err_p
114+ end
70115
71- dΩ = Measure (Ω, qdegree)
72- dΩ_cut = Measure (Ω_cut, qdegree)
73- dΓ = Measure (Γ, 2 * qdegree)
74- dΓu = Measure (Γu, 2 * qdegree)
75- dΓp = Measure (Γp, 2 * qdegree)
116+ function convergence (ns,order,u_exact,p_exact)
117+ l2_u = zeros (Float64,length (ns))
118+ l2_p = zeros (Float64,length (ns))
119+ for (i,n) in enumerate (ns)
120+ _, _, _, l2_u[i], l2_p[i] = driver (n,order,u_exact,p_exact)
121+ end
122+ slope_u = log .(l2_u[1 : end - 1 ]. / l2_u[2 : end ]) ./ log .(ns[2 : end ]. / ns[1 : end - 1 ])
123+ slope_p = log .(l2_p[1 : end - 1 ]. / l2_p[2 : end ]) ./ log .(ns[2 : end ]. / ns[1 : end - 1 ])
124+ return l2_u, l2_p, slope_u, slope_p
125+ end
76126
77- η = 1.0
127+ # Manufactured solution
78128u_exact (x) = VectorValue (x[1 ], - x[2 ])
79129p_exact (x) = x[1 ] + x[2 ]
80- f (x) = η* u_exact (x) + ∇ (p_exact)(x)
81- g (x) = - (∇⋅ u_exact)(x)
82-
83- γ = 10.0 * (1 / n)
84- n_Γu = get_normal_vector (Γu)
85- n_Γp = get_normal_vector (Γp)
86- a (u,v) = ∫ (η* (u⋅ v))dΩ + ∫ (γ* (u⋅ n_Γu)* (v⋅ n_Γu))dΓu
87- b (u,q) = ∫ (- (∇⋅ u)* q)dΩ
88- btilde (u,q) = b (u,q) + ∫ ((u⋅ n_Γu)* q)dΓu
89- l ((v,q)) = ∫ (v⋅ f + g⋅ q)dΩ + ∫ (γ* (v⋅ n_Γu)⋅ (u_exact⋅ n_Γu))dΓu - ∫ ((v⋅ n_Γp)* p_exact)dΓp
90-
91- τ = 1.0
92- sd (u,v) = ∫ (τ* (u⋅ v))dΩp
93- s0 (p,q) = ∫ (τ* p* q)dΩp
94-
95- function weakform (x,y)
96- u, p = x
97- v, q = y
98- Πu, Πv = Πd (u), Πd (v)
99- Πp, Πq = Π0 (p), Π0 (q)
100- divu, divv = ∇⋅ u, ∇⋅ v
101- Πdivu, Πdivv = Π0div (u), Π0div (v)
102- Xp = FESpaces. PatchFESpace (X,ptopo)
103- data = FESpaces. collect_and_merge_cell_matrix_and_vector (
104- (X, X , a (u,v) + btilde (v,p) + b (u,q) + sd (u,v) - s0 (divu,q) - s0 (divv,p), l (y)),
105- (X, Xp , s0 (divu,Πq) + s0 (Πdivv,p) - sd (u,Πv), DomainContribution ()),
106- (Xp, X , s0 (Πdivu,q) + s0 (divv,Πp) - sd (Πu,v), DomainContribution ()),
107- (Xp, Xp, sd (Πu,Πv) - s0 (Πdivu,Πq) - s0 (Πdivv,Πp), DomainContribution ()),
108- )
109- assem = SparseMatrixAssembler (X,X)
110- A, B = assemble_matrix_and_vector (assem,data)
111- return AffineFEOperator (X,X,A,B)
112- end
113-
114- op = weakform (get_trial_fe_basis (X),get_fe_basis (X))
115- uh, ph = solve (op)
130+ cutgeo, uh, ph, l2_err_u, l2_err_p = driver (8 ,1 ,u_exact,p_exact)
131+ @test l2_err_u < 1.e-10
132+ @test l2_err_p < 1.e-10
116133
117- eu = uh- u_exact
118- ep = ph- p_exact
119- l2_err_u = sqrt (sum (∫ ( eu ⋅ eu )dΩ))
120- l2_err_p = sqrt (sum (∫ ( ep ⋅ ep )dΩ))
134+ u_conv (x) = VectorValue (x[1 ] + sin (π* x[2 ]), - x[2 ] + sin (π* x[1 ]))
135+ p_conv (x) = sin (π* x[1 ]) - sin (π* x[2 ])
136+ l2_u, l2_p, su, sp = convergence ([8 ,16 ,32 ,64 ],1 ,u_conv,p_conv)
121137
122138writevtk (
123- Ω, " hdiv_cut " ; append= false ,
139+ Ω, " darcy_BGP_mixed " ; append= false ,
124140 cellfields= [
125- " uh" => uh," ph" => ph," u_exact" => u_exact," p_exact" => p_exact," eu" => eu," ep" => ep
141+ " uh" => uh," ph" => ph," u_exact" => u_exact," p_exact" => p_exact,
142+ " eu" => uh- u_exact," ep" => ph- p_exact
126143 ],
127144)
128145
129- aggregates = get_aggregates (cutgeo)
130- cell_to_agg = flatten_partition (aggregates,num_cells (bgmodel))
146+ cell_to_agg = flatten_partition (get_aggregates (cutgeo),num_cells (bgmodel))
131147writevtk (
132148 Triangulation (bgmodel), " aggregates" ; append= false ,
133149 celldata = [" agg" => cell_to_agg]
@@ -139,9 +155,8 @@ function normal_at_centroid(Γ)
139155 return n (x)
140156end
141157
142- writevtk (
143- Γ, " boundary" ; append= false ,
144- )
158+ Γu = EmbeddedBoundary (cutgeo, " disk" ," domain" )
159+ Γp = EmbeddedBoundary (cutgeo, " plane" ," domain" )
145160writevtk (
146161 Γu, " boundary_u" ; append= false , celldata= [" n" => normal_at_centroid (Γu)]
147162)
0 commit comments