PRAgMaTIc  master
maximal_example.py
Go to the documentation of this file.
1 ### this a testcase for use with DOLFIN/FEniCS and PRAgMaTIc
2 ### by Kristian Ejlebjerg Jensen, January 2014, Imperial College London
3 ### the purpose of the test case is to
4 ### 1. derive a forcing term that gives rise to an oscilatting function with a shock (see Gerards pragmatic article)
5 ### 2. solve a poisson equation with the forcing term using 2D anisotropic adaptivity
6 ### 3. plot the numerical solution, the analitical solution and the difference between them
7 ### the error level(eta), the time and period of the function as well the number of solition<->adaptation iterations
8 ### are optional input parameters.
9 
10 from dolfin import *
11 from adaptivity import metric_pnorm, adapt
12 from pylab import loglog, hold, show, axis, box, figure, tricontourf, triplot, colorbar, savefig, title, get_cmap, xlabel, ylabel
13 from pylab import plot as pyplot
14 from numpy import array
15 from sympy import Symbol, diff, Subs
16 from sympy import sin as pysin
17 from sympy import atan2 as pyatan
18 from numpy import log as pylog
19 from numpy import exp as pyexp2
20 set_log_level(INFO+1)
21 #parameters["allow_extrapolation"] = True
22 
23 def maximal_example(eta_list = array([0.001]), Nadapt=5, timet=1., period=2*pi):
24  ### CONSTANTS
25 
26  ### SETUP SOLUTION
27  #testsol = '0.1*sin(50*x+2*pi*t/T)+atan(-0.1/(2*x - sin(5*y+2*pi*t/T)))';
28  sx = Symbol('sx'); sy = Symbol('sy'); sT = Symbol('sT'); st = Symbol('st'); spi = Symbol('spi')
29  testsol = 0.1*pysin(50*sx+2*spi*st/sT)+pyatan(-0.1,2*sx - pysin(5*sy+2*spi*st/sT))
30  ddtestsol = str(diff(testsol,sx,sx)+diff(testsol,sy,sy)).replace('sx','x[0]').replace('sy','x[1]').replace('spi','pi')
31 
32  # replacing **P with pow(,P)
33  ddtestsol = ddtestsol.replace("(2*x[0] - sin(5*x[1] + 2*pi*st/sT))**2","pow(2*x[0] - sin(5*x[1] + 2*pi*st/sT),2.)")
34  ddtestsol = ddtestsol.replace("cos(5*x[1] + 2*pi*st/sT)**2","pow(cos(5*x[1] + 2*pi*st/sT),2.)")
35  ddtestsol = ddtestsol.replace("(pow(2*x[0] - sin(5*x[1] + 2*pi*st/sT),2.) + 0.01)**2","pow((pow(2*x[0] - sin(5*x[1] + 2*pi*st/sT),2.) + 0.01),2.)")
36  ddtestsol = ddtestsol.replace("(1 + 0.01/pow(2*x[0] - sin(5*x[1] + 2*pi*st/sT),2.))**2","pow(1 + 0.01/pow(2*x[0] - sin(5*x[1] + 2*pi*st/sT),2.),2.)")
37  ddtestsol = ddtestsol.replace("(2*x[0] - sin(5*x[1] + 2*pi*st/sT))**5","pow(2*x[0] - sin(5*x[1] + 2*pi*st/sT),5.)")
38  #insert values
39  ddtestsol = ddtestsol.replace('sT',str(period)).replace('st',str(timet))
40  testsol = str(testsol).replace('sx','x[0]').replace('sy','x[1]').replace('spi','pi').replace('sT',str(period)).replace('st',str(timet))
41  ddtestsol = "-("+ddtestsol+")"
42 
43  error_list = []; dof_list = []
44  for eta in eta_list:
45  meshsz = 40
46  ### SETUP MESH
47  # mesh = RectangleMesh(0.4,-0.1,0.6,0.3,1*meshsz,1*meshsz,"left/right") #shock
48  # mesh = RectangleMesh(-0.75,-0.3,-0.3,0.5,1*meshsz,1*meshsz,"left/right") #waves
49  mesh = RectangleMesh(-1.5,-0.25,0.5,0.75,1*meshsz,1*meshsz,"left/right") #shock+waves
50 
51  def boundary(x):
52  return near(x[0],mesh.coordinates()[:,0].min()) or near(x[0],mesh.coordinates()[:,0].max()) \
53  or near(x[1],mesh.coordinates()[:,1].min()) or near(x[1],mesh.coordinates()[:,1].max())
54  # PERFORM ONE ADAPTATION ITERATION
55  for iii in range(Nadapt):
56  startTime = time()
57  V = FunctionSpace(mesh, "CG" ,2); dis = TrialFunction(V); dus = TestFunction(V); u = Function(V)
58  # R = interpolate(Expression(ddtestsol),V)
59  a = inner(grad(dis), grad(dus))*dx
60  L = Expression(ddtestsol)*dus*dx #
61  bc = DirichletBC(V, Expression(testsol), boundary)
62  solve(a == L, u, bc)
63  soltime = time()-startTime
64 
65  startTime = time()
66  H = metric_pnorm(u, eta, max_edge_ratio=50, CG0H=3, p=4)
67  metricTime = time()-startTime
68  if iii != Nadapt-1:
69  mesh = adapt(H)
70  TadaptTime = time()-startTime
71  L2error = errornorm(Expression(testsol), u, degree_rise=4, norm_type='L2')
72  printstr = "%5.0f elements, %0.0e L2error, adapt took %0.0f %% of the total time, (%0.0f %% of which was the metric calculation)" \
73  % (mesh.num_cells(),L2error,TadaptTime/(TadaptTime+soltime)*100,metricTime/TadaptTime*100)
74  if len(eta_list) == 1:
75  print(printstr)
76  else:
77  error_list.append(L2error); dof_list.append(len(u.vector().array()))
78  print(printstr)
79 
80  if len(dof_list) > 1:
81  dof_list = array(dof_list); error_list = array(error_list)
82  figure()
83  loglog(dof_list,error_list,'.b-',linewidth=2,markersize=16); xlabel('Degree of freedoms'); ylabel('L2 error')
84 # # PLOT MESH
85 # figure()
86  coords = mesh.coordinates().transpose()
87 # triplot(coords[0],coords[1],mesh.cells(),linewidth=0.1)
88 # #savefig('mesh.png',dpi=300) #savefig('mesh.eps');
89 
90  figure() #solution
91  testf = interpolate(Expression(testsol),FunctionSpace(mesh,'CG',1))
92  vtx2dof = vertex_to_dof_map(FunctionSpace(mesh, "CG" ,1))
93  zz = testf.vector().array()[vtx2dof]
94  hh=tricontourf(coords[0],coords[1],mesh.cells(),zz,100)
95  colorbar(hh)
96  #savefig('solution.png',dpi=300) #savefig('solution.eps');
97 
98  figure() #analytical solution
99  testfe = interpolate(u,FunctionSpace(mesh,'CG',1))
100  zz = testfe.vector().array()[vtx2dof]
101  hh=tricontourf(coords[0],coords[1],mesh.cells(),zz,100)
102  colorbar(hh)
103  #savefig('analyt.png',dpi=300) #savefig('analyt.eps');
104 
105  figure() #error
106  zz -= testf.vector().array()[vtx2dof]; zz[zz==1] -= 1e-16
107  hh=tricontourf(mesh.coordinates()[:,0],mesh.coordinates()[:,1],mesh.cells(),zz,100,cmap=get_cmap('binary'))
108  colorbar(hh)
109 
110  hold('on'); triplot(mesh.coordinates()[:,0],mesh.coordinates()[:,1],mesh.cells(),color='r',linewidth=0.5); hold('off')
111  axis('equal'); box('off'); title('error')
112  show()
113 
114 if __name__=="__main__":
115 # maximal_example()
116  maximal_example(eta_list=0.02*pyexp2(-array(range(9))*pylog(2)/2))
def metric_pnorm
Definition: adaptivity.py:535