47 The python interface to PRAgMaTIc (Parallel anisotRopic Adaptive Mesh
48 ToolkIt) provides anisotropic mesh adaptivity for meshes of
49 simplexes. The target applications are finite element and finite
50 volume methods although the it can also be used as a lossy compression
51 algorithm for data (e.g. image compression). It takes as its input the
52 mesh and a metric tensor field which encodes desired mesh element size
56 import ctypes, ctypes.util, numpy, scipy.sparse, scipy.sparse.linalg
57 from numpy
import array, zeros, ones, any, arange, isnan
58 from numpy.linalg
import eig
as pyeig
61 __all__ = [
"_libpragmatic",
62 "InvalidArgumentException",
64 "NotImplementedException",
82 _libpragmatic = ctypes.cdll.LoadLibrary(
"libpragmatic.so")
84 raise LibraryException(
"Failed to load libpragmatic.so")
87 class RefineExpression(Expression):
88 def eval(self, value, x):
89 value[:] =
M(x) * (factor * factor)
91 def value_shape(self):
94 space = M.function_space()
95 M2 = interpolate(RefineExpression(), space)
96 name =
"mesh_metric_refined_x%.6g" % factor
102 class EdgeLengthExpression(Expression):
103 def eval(self, value, x):
106 evals, evecs = numpy.linalg.eig(mat)
107 value[:] = 1.0 / numpy.sqrt(evals)
109 def value_shape(self):
111 e = interpolate(EdgeLengthExpression(), VectorFunctionSpace(M.function_space().
mesh(),
"CG", 1))
112 name =
"%s_edge_lengths" % M.name()
127 coords = mesh.coordinates()
129 v1 = coords[cells[:,1],:]-coords[cells[:,0],:]
130 v2 = coords[cells[:,2],:]-coords[cells[:,0],:]
131 v3 = coords[cells[:,3],:]-(coords[cells[:,0],:]+coords[cells[:,1],:]+coords[cells[:,2],:])/3.
132 crossprod = array([v1[:,1]*v2[:,2]-v1[:,2]*v2[:,1], \
133 v1[:,2]*v2[:,0]-v1[:,0]*v2[:,2], \
134 v1[:,0]*v2[:,1]-v1[:,1]*v2[:,0]]).T
135 badcells = (crossprod*v3).sum(1)>0
136 tri = cells.flatten()
137 R = range(0,4*ntri,4); m1 = ones(ntri,dtype=numpy.int64)
138 tri = array([tri[R+badcells],tri[R+m1-badcells],tri[R+2*m1],tri[R+3*m1]])
139 fac = array([tri[0],tri[1],tri[2],tri[3],\
140 tri[1],tri[0],tri[3],tri[2],\
141 tri[3],tri[2],tri[1],tri[0]]).reshape([3,ntri*4])
144 Cgood = (C[0,:] == 0)*(C[0,:] == 1)+(C[1,:] == 1)*(C[0,:] == 2)+(C[1,:] == 2)*(C[0,:] == 0)
147 fac = fac.transpose().flatten()
148 fac = array([fac[R*3+C[0,:]],fac[R*3+C[1,:]],fac[R*3+C[2,:]]])
150 I2 = numpy.argsort(array(zip(fac[0,:],fac[1,:],fac[2,:]),dtype=[(
'e1',int),(
'e2',int),(
'e3',int)]),order=[
'e1',
'e2',
'e3'])
153 d = array([any(fac[:,0] != fac[:,1])] +\
154 (any((fac[:,range(1,ntri*4-1)] != fac[:,range(2,ntri*4)]),0) *\
155 any((fac[:,range(1,ntri*4-1)] != fac[:,range(0,ntri*4-2)]),0)).tolist() +\
156 [any(fac[:,ntri*4-1] != fac[:,ntri*4-2])])
160 fac = fac.transpose().flatten()
161 bfaces = array([fac[R*3+Cgood[I2[d]]],fac[R*3+Cinv[I2[d]]],fac[R*3+2]]).transpose()
163 v1 = coords[bfaces[:,1],:]-coords[bfaces[:,0],:]
164 v2 = coords[bfaces[:,2],:]-coords[bfaces[:,0],:]
165 n = array([v1[:,1]*v2[:,2]-v1[:,2]*v2[:,1], \
166 v1[:,2]*v2[:,0]-v1[:,0]*v2[:,2], \
167 v1[:,0]*v2[:,1]-v1[:,1]*v2[:,0]]).T
168 n = n/numpy.sqrt(n[:,0]**2+n[:,1]**2+n[:,2]**2).repeat(3).reshape([len(n),3])
170 IDs = zeros(len(n), dtype = numpy.intc)
173 IDs[nn] = IDs.max() + 1
174 I = arange(0,len(IDs))
175 notnset = I != nn * ones(len(I),dtype=numpy.int64)
176 dists = abs(n[notnset,0]*(coords[bfaces[notnset,0],0] - ones(sum(notnset))*coords[bfaces[nn,0],0])+\
177 n[notnset,1]*(coords[bfaces[notnset,0],1] - ones(sum(notnset))*coords[bfaces[nn,0],1])+\
178 n[notnset,2]*(coords[bfaces[notnset,0],2] - ones(sum(notnset))*coords[bfaces[nn,0],2])) < 1e-12
179 angles = ones(sum(notnset))-abs(n[notnset,0]*n[nn,0]+n[notnset,1]*n[nn,1]+n[notnset,2]*n[nn,2])<1e-12
180 IDs[I[notnset][angles*dists]] = IDs[nn]
181 if all(IDs != zeros(len(IDs),dtype=numpy.int64)):
182 info(
"Found %i co-linear faces" % IDs.max())
187 bfaces_pair = zip(bfaces[:,0],bfaces[:,1],bfaces[:,2])
200 coords = mesh.coordinates()
202 v1 = coords[cells[:,1],:]-coords[cells[:,0],:]
203 v2 = coords[cells[:,2],:]-coords[cells[:,0],:]
204 badcells = v1[:,0]*v2[:,1]-v1[:,1]*v2[:,0]>0
205 tri = cells.flatten()
206 R = range(0,3*ntri,3); m1 = ones(ntri,dtype=numpy.int64)
207 tri = array([tri[R+badcells],tri[R+m1-badcells],tri[R+2*m1]])
208 edg = array([tri[0],tri[1],tri[2],\
209 tri[1],tri[2],tri[0]]).reshape([2,ntri*3])
213 edg = edg.transpose().flatten()
214 edg = array([edg[R*2+C[0,:]],edg[R*2+C[1,:]]])
216 I2 = numpy.argsort(array(zip(edg[0,:],edg[1,:]),dtype=[(
'e1',int),(
'e2',int)]),order=[
'e1',
'e2'])
219 d = array([any(edg[:,0] != edg[:,1])] +\
220 (any((edg[:,range(1,ntri*3-1)] != edg[:,range(2,ntri*3)]),0) *\
221 any((edg[:,range(1,ntri*3-1)] != edg[:,range(0,ntri*3-2)]),0)).tolist() +\
222 [any(edg[:,ntri*3-1] != edg[:,ntri*3-2])])
226 edg = edg.transpose().flatten()
227 bfaces = array([edg[R*2+C[0,I2[d]]],edg[R*2+C[1,I2[d]]]]).transpose()
229 t = coords[bfaces[:,0],:]-coords[bfaces[:,1],:]
230 t = t/numpy.sqrt(t[:,0]**2+t[:,1]**2).repeat(2).reshape([len(t),2])
232 IDs = zeros(len(t), dtype = numpy.intc)
235 IDs[n] = IDs.max() + 1
236 I = arange(0,len(IDs))
237 notnset = I != n * ones(len(I),dtype=numpy.int64)
238 dists = abs(t[notnset,1]*(coords[bfaces[notnset,0],0] - ones(sum(notnset))*coords[bfaces[n,0],0])-\
239 t[notnset,0]*(coords[bfaces[notnset,0],1] - ones(sum(notnset))*coords[bfaces[n,0],1])) < 1e-12
240 angles = ones(sum(notnset))-abs(t[notnset,0]*t[n,0]+t[notnset,1]*t[n,1])<1e-12
241 IDs[I[notnset][angles*dists]] = IDs[n]
242 if all(IDs != zeros(len(IDs),dtype=numpy.int64)):
243 info(
"Found %i co-linear edges" % IDs.max())
250 def set_mesh(n_xy, n_enlist, mesh=None, dx=None, debugon=False):
265 ed.open(n_mesh, len(n_xy), len(n_xy))
266 ed.init_vertices(nvtx)
268 for i
in range(nvtx):
269 ed.add_vertex(i, n_xy[0,i])
270 ed.init_cells(len(n_enlist)/2)
271 for i
in range(len(n_enlist)/2):
272 ed.add_cell(i, n_enlist[i * 2], n_enlist[i * 2 + 1])
274 for i
in range(nvtx):
275 ed.add_vertex(i, n_xy[0,i], n_xy[1,i])
276 ed.init_cells(len(n_enlist)/3)
277 for i
in range(len(n_enlist)/3):
278 ed.add_cell(i, n_enlist[i * 3], n_enlist[i * 3 + 1], n_enlist[i * 3 + 2])
280 for i
in range(nvtx):
281 ed.add_vertex(i, n_xy[0,i], n_xy[1,i], n_xy[2,i])
282 ed.init_cells(len(n_enlist)/4)
283 for i
in range(len(n_enlist)/4):
284 ed.add_cell(i, n_enlist[i * 4], n_enlist[i * 4 + 1], n_enlist[i * 4 + 2], n_enlist[i * 4 + 3])
286 info(
"mesh definition took %0.1fs (not vectorized)" % (time()-startTime))
287 if debugon==
True and dx
is not None:
289 area = assemble(interpolate(Constant(1.0),FunctionSpace(mesh,
'DG',0)) * dx)
290 n_area = assemble(interpolate(Constant(1.0),FunctionSpace(n_mesh,
'DG',0)) * dx)
291 err = abs(area - n_area)
292 info(
"Donor mesh area : %.17e" % area)
293 info(
"Target mesh area: %.17e" % n_area)
294 info(
"Change : %.17e" % err)
295 info(
"Relative change : %.17e" % (err / area))
297 assert(err < 2.0e-11 * area)
308 gdim = metric.function_space().ufl_element().cell().geometric_dimension()
309 targetN = assemble(sqrt(det(metric))*dx)
312 fak = (targetN/maxN)**(gdim/2)
313 metric.vector().set_local(metric.vector().array()/fak)
314 info(
'metric coarsened to meet target node number')
317 def adapt(metric, bfaces=None, bfaces_IDs=None, debugon=True, eta=1e-2, grada=None, maxN=None):
344 mesh = metric.function_space().
mesh()
347 if metric.function_space().ufl_element().num_sub_elements() == 0:
350 if metric.function_space().ufl_element().degree() == 0
and metric.function_space().ufl_element().family()[0] ==
'D':
351 metric = project(metric, TensorFunctionSpace(mesh,
"CG", 1))
353 if grada
is not None:
359 targetN = assemble(sqrt(det(metric))*dx)
361 info(
"target mesh has %0.0f nodes" % targetN)
363 warning(
"target mesh has %0.0f nodes" % targetN)
365 space = metric.function_space()
366 element = space.ufl_element()
369 if not (mesh.geometry().dim() == 2
or mesh.geometry().dim() == 3)\
370 or not (element.cell().geometric_dimension() == 2 \
371 or element.cell().geometric_dimension() == 3) \
372 or not (element.cell().topological_dimension() == 2 \
373 or element.cell().topological_dimension() == 3) \
374 or not element.family() ==
"Lagrange" \
375 or not element.degree() == 1:
378 nodes = array(range(0,mesh.num_vertices()),dtype=numpy.intc)
380 coords = mesh.coordinates()
383 if element.cell().geometric_dimension() == 2:
390 if element.cell().geometric_dimension() == 3:
392 cells = array(cells,dtype=numpy.intc)
398 if dolfin.__version__ !=
'1.2.0':
399 dof2vtx = vertex_to_dof_map(FunctionSpace(mesh,
"CG" ,1))
401 dof2vtx = FunctionSpace(mesh,
'CG',1).dofmap().vertex_to_dof_map(mesh).argsort()
403 metric_arr = numpy.empty(metric.vector().array().size, dtype = numpy.float64)
404 if element.cell().geometric_dimension() == 2:
405 metric_arr[range(0,metric.vector().array().size,4)] = metric.vector().array()[arange(0,metric.vector().array().size,4)[dof2vtx]]
406 metric_arr[range(1,metric.vector().array().size,4)] = metric.vector().array()[arange(2,metric.vector().array().size,4)[dof2vtx]]
407 metric_arr[range(2,metric.vector().array().size,4)] = metric.vector().array()[arange(2,metric.vector().array().size,4)[dof2vtx]]
408 metric_arr[range(3,metric.vector().array().size,4)] = metric.vector().array()[arange(3,metric.vector().array().size,4)[dof2vtx]]
410 metric_arr[range(0,metric.vector().array().size,9)] = metric.vector().array()[arange(0,metric.vector().array().size,9)[dof2vtx]]
411 metric_arr[range(1,metric.vector().array().size,9)] = metric.vector().array()[arange(3,metric.vector().array().size,9)[dof2vtx]]
412 metric_arr[range(2,metric.vector().array().size,9)] = metric.vector().array()[arange(6,metric.vector().array().size,9)[dof2vtx]]
413 metric_arr[range(3,metric.vector().array().size,9)] = metric.vector().array()[arange(3,metric.vector().array().size,9)[dof2vtx]]
414 metric_arr[range(4,metric.vector().array().size,9)] = metric.vector().array()[arange(4,metric.vector().array().size,9)[dof2vtx]]
415 metric_arr[range(5,metric.vector().array().size,9)] = metric.vector().array()[arange(7,metric.vector().array().size,9)[dof2vtx]]
416 metric_arr[range(6,metric.vector().array().size,9)] = metric.vector().array()[arange(6,metric.vector().array().size,9)[dof2vtx]]
417 metric_arr[range(7,metric.vector().array().size,9)] = metric.vector().array()[arange(7,metric.vector().array().size,9)[dof2vtx]]
418 metric_arr[range(8,metric.vector().array().size,9)] = metric.vector().array()[arange(8,metric.vector().array().size,9)[dof2vtx]]
419 info(
"Beginning PRAgMaTIc adapt")
420 info(
"Initialising PRAgMaTIc ...")
421 NNodes = ctypes.c_int(x.shape[0])
423 NElements = ctypes.c_int(cells.shape[0])
425 if element.cell().geometric_dimension() == 2:
426 _libpragmatic.pragmatic_2d_init(ctypes.byref(NNodes),
427 ctypes.byref(NElements),
432 _libpragmatic.pragmatic_3d_init(ctypes.byref(NNodes),
433 ctypes.byref(NElements),
438 info(
"Setting surface ...")
439 nfacets = ctypes.c_int(len(bfaces))
440 facets = array(bfaces.flatten(),dtype=numpy.intc)
442 _libpragmatic.pragmatic_set_boundary(ctypes.byref(nfacets),
444 bfaces_IDs.ctypes.data)
446 info(
"Setting metric tensor field ...")
447 _libpragmatic.pragmatic_set_metric(metric_arr.ctypes.data)
449 info(
"Entering adapt ...")
451 _libpragmatic.pragmatic_adapt()
453 info(
"adapt took %0.1fs" % (time()-startTime))
454 n_NNodes = ctypes.c_int()
455 n_NElements = ctypes.c_int()
456 n_NSElements = ctypes.c_int()
458 info(
"Querying output ...")
459 _libpragmatic.pragmatic_get_info(ctypes.byref(n_NNodes),
460 ctypes.byref(n_NElements),
461 ctypes.byref(n_NSElements))
463 if element.cell().geometric_dimension() == 2:
464 n_enlist = numpy.empty(3 * n_NElements.value, numpy.intc)
466 n_enlist = numpy.empty(4 * n_NElements.value, numpy.intc)
468 info(
"Extracting output ...")
469 n_x = numpy.empty(n_NNodes.value)
470 n_y = numpy.empty(n_NNodes.value)
471 if element.cell().geometric_dimension() == 3:
472 n_z = numpy.empty(n_NNodes.value)
473 _libpragmatic.pragmatic_get_coords_3d(n_x.ctypes.data,
477 _libpragmatic.pragmatic_get_coords_2d(n_x.ctypes.data,
480 _libpragmatic.pragmatic_get_elements(n_enlist.ctypes.data)
482 info(
"Finalising PRAgMaTIc ...")
483 _libpragmatic.pragmatic_finalize()
484 info(
"PRAgMaTIc adapt complete")
486 if element.cell().geometric_dimension() == 2:
487 n_mesh =
set_mesh(array([n_x,n_y]),n_enlist,mesh=mesh,dx=dx,debugon=debugon)
489 n_mesh =
set_mesh(array([n_x,n_y,n_z]),n_enlist,mesh=mesh,dx=dx,debugon=debugon)
494 if not isinstance(fields, list):
497 n_space = FunctionSpace(n_mesh,
"CG", 1)
500 n_field = Function(n_space)
501 n_field.rename(field.name(), field.name())
503 coord = numpy.empty(2)
504 nx = interpolate(Expression(
"x[0]"), n_space).vector().array()
505 ny = interpolate(Expression(
"x[1]"), n_space).vector().array()
506 n_field_arr = numpy.empty(n_NNodes.value)
507 for i
in range(n_NNodes.value):
510 field.eval(val, coord)
512 n_field.vector().set_local(n_field_arr)
513 n_field.vector().apply(
"insert")
514 n_fields.append(n_field)
516 if len(n_fields) > 0:
529 eigL = numpy.abs(eigL)
531 out =
sym2asym(H).transpose().flatten()
532 Mp.vector().set_local(out)
535 def metric_pnorm(f, eta, max_edge_length=None, min_edge_length=None, max_edge_ratio=10, p=2, CG1out=False, CG0H=3):
549 mesh = f.function_space().
mesh()
551 if max_edge_ratio
is not None and max_edge_ratio < 1.0:
554 if max_edge_ratio
is not None:
555 max_edge_ratio = max_edge_ratio**2
557 n = mesh.geometry().dim()
559 if f.function_space().ufl_element().degree() == 2
and f.function_space().ufl_element().family() ==
'Lagrange':
561 S = VectorFunctionSpace(mesh,
'DG',1)
562 A = assemble(inner(TrialFunction(S), TestFunction(S))*dx)
563 b = assemble(inner(grad(f), TestFunction(S))*dx)
565 ones_.vector()[:] = 1
566 A_diag = A * ones_.vector()
567 A_diag.set_local(1.0/A_diag.array())
569 gradf.vector()[:] = b * A_diag
571 S = TensorFunctionSpace(mesh,
'DG',0)
572 A = assemble(inner(TrialFunction(S), TestFunction(S))*dx)
573 b = assemble(inner(grad(gradf), TestFunction(S))*dx)
575 ones_.vector()[:] = 1
576 A_diag = A * ones_.vector()
577 A_diag.set_local(1.0/A_diag.array())
579 S = TensorFunctionSpace(mesh,
'DG',0)
580 A = assemble(inner(TrialFunction(S), TestFunction(S))*dx)
581 b = assemble(inner(grad(grad(f)), TestFunction(S))*dx)
583 ones_.vector()[:] = 1
584 A_diag = A * ones_.vector()
585 A_diag.set_local(1.0/A_diag.array())
587 H.vector()[:] = b * A_diag
589 H = project(grad(grad(f)), TensorFunctionSpace(mesh,
"DG", 0))
591 gradf = project(grad(f), VectorFunctionSpace(mesh,
"CG", 1))
592 H = project(sym(grad(gradf)), TensorFunctionSpace(mesh,
"DG", 0))
594 if CG1out
or dolfin.__version__ >=
'1.4.0':
595 H = project(H,TensorFunctionSpace(mesh,
'CG',1))
599 HH[0,:] += DOLFIN_EPS
600 HH[2,:] += DOLFIN_EPS
602 HH[5,:] += DOLFIN_EPS
609 min_eigenvalue = 1e-20; max_eigenvalue = 1e20
610 onesC = ones(eigL.shape)
611 eigL = array([numpy.abs(eigL),onesC*min_eigenvalue]).max(0)
612 eigL = array([numpy.abs(eigL),onesC*max_eigenvalue]).min(0)
614 if max_edge_ratio
is not None:
615 RR = arange(HH.shape[1])
617 I_ = array([
False]).repeat(array(eigL.shape).prod())
618 I_[CC+(RR-1)*eigL.shape[0]] =
True
619 I_ = I_.reshape(eigL.shape)
620 eigL[I_==
False] = array([eigL[I_==
False],eigL[I_].repeat(eigL.shape[0]-1)/max_edge_ratio]).max(0)
625 raise FloatingPointError(
"Eigenvalues are zero")
628 exponent = -1.0/(2*p + n)
629 eigL *= 1./eta*(det**exponent).repeat(eigL.shape[0]).reshape([eigL.shape[1],eigL.shape[0]]).T
636 if max_edge_length
is not None:
637 min_eigenvalue = 1.0/max_edge_length**2
638 if eigL.flatten().min()<min_eigenvalue:
639 info(
'upper bound on element edge length is active')
640 if min_edge_length
is not None:
641 max_eigenvalue = 1.0/min_edge_length**2
642 if eigL.flatten().max()>max_eigenvalue:
643 info(
'lower bound on element edge length is active')
644 eigL = array([eigL,onesC*min_eigenvalue]).max(0)
645 eigL = array([eigL,onesC*max_eigenvalue]).min(0)
649 cbig=zeros((H.vector().array()).size)
650 cbig[cell2dof.flatten()] = Hfinal.transpose().flatten()
651 H.vector().set_local(cbig)
666 cbig = zeros((H1.vector().array()).size)
677 HH = Function(FunctionSpace(H1.function_space().
mesh(),
'DG',0))
678 HH.vector().set_local((eigL2<ones(eigL2.shape)).sum(0)-ones(eigL2.shape[1]))
681 eigL2 = array([eigL2 ,ones(eigL2.shape)]).max(0)
683 eigL2 = array([eigL2, ones(eigL2.shape)]).min(0)
691 cbig[cell2dof.flatten()] = HH.transpose().flatten()
692 H1.vector().set_local(cbig)
699 mesh = H.function_space().
mesh()
700 n = mesh.geometry().dim()
701 if H.function_space().ufl_element().degree() == 0
and H.function_space().ufl_element().family()[0] ==
'D':
703 cell2dof = cell2dof.reshape([mesh.num_cells(),n**2])
705 cell2dof = arange(mesh.num_vertices()*n**2)
706 cell2dof = cell2dof.reshape([mesh.num_vertices(),n**2])
708 H11 = H.vector().array()[cell2dof[:,0]]
709 H12 = H.vector().array()[cell2dof[:,1]]
710 H22 = H.vector().array()[cell2dof[:,3]]
711 return [array([H11,H12,H22]),cell2dof]
713 H11 = H.vector().array()[cell2dof[:,0]]
714 H12 = H.vector().array()[cell2dof[:,1]]
715 H13 = H.vector().array()[cell2dof[:,2]]
716 H22 = H.vector().array()[cell2dof[:,4]]
717 H23 = H.vector().array()[cell2dof[:,5]]
718 H33 = H.vector().array()[cell2dof[:,8]]
719 return [array([H11,H12,H22,H13,H23,H33]),cell2dof]
724 if eigR.shape[0] == 4:
725 return array([eigR[0,:],eigR[2,:],\
726 eigR[1,:],eigR[3,:]])
728 return array([eigR[0,:],eigR[3,:],eigR[6,:],\
729 eigR[1,:],eigR[4,:],eigR[7,:],\
730 eigR[2,:],eigR[5,:],eigR[8,:]])
738 return array([HH[0,:],HH[1,:],\
741 return array([HH[0,:],HH[1,:],HH[3,:],\
742 HH[1,:],HH[2,:],HH[4,:],\
743 HH[3,:],HH[4,:],HH[5,:]])
749 zeron = zeros(eigL.shape[1])
750 if eigL.shape[0] == 2:
751 return array([eigL[0,:],zeron,eigL[1,:]])
753 return array([eigL[0,:],zeron,eigL[1,:],zeron,zeron,eigL[2,:]])
762 inds = array([[0,1],[1,2]])
763 indA = array([[0,1],[2,3]])
765 inds = array([[0,1,3],[1,2,4],[3,4,5]])
766 indA = array([[0,1,2],[3,4,5],[6,7,8]])
769 for i
in range(len(inds)):
770 for j
in range(len(inds)):
771 for m
in range(len(inds)):
772 for n
in range(len(inds)):
775 A[inds[i,n],:] += eigR[indB[i,j],:]*H[inds[j,m],:]*eigR[indA[m,n],:]
785 return array([H[0,:]*eigL[0,:], H[1,:]*numpy.sqrt(eigL[0,:]*eigL[1,:]), \
788 return array([H[0,:]*eigL[0,:], H[1,:]*numpy.sqrt(eigL[0,:]*eigL[1,:]), H[2,:]*eigL[1,:], \
789 H[3,:]*numpy.sqrt(eigL[0,:]*eigL[2,:]), H[4,:]*numpy.sqrt(eigL[2,:]*eigL[1,:]),\
803 onesC = ones(len(H11))
805 if numpy.__version__ <
"1.8.0":
806 lambda1 = 0.5*(H11+H22-numpy.sqrt((H11-H22)**2+4*H12**2))
807 lambda2 = 0.5*(H11+H22+numpy.sqrt((H11-H22)**2+4*H12**2))
808 v1x = ones(len(H11)); v1y = zeros(len(H11))
810 I2 = numpy.abs(lambda1-lambda2)<onesC*tol;
812 I1 = numpy.abs(H12)<onesC*tol
813 lambda1[I1] = H11[I1]
814 lambda2[I1] = H22[I1]
816 nI = (I1==
False)*(I2==
False)
818 v1y[nI] = H11[nI]-lambda1[nI]
819 L1 = numpy.sqrt(v1x**2+v1y**2)
822 eigL = array([lambda1,lambda2])
823 eigR = array([v1x,v1y,-v1y,v1x])
825 Hin = zeros([len(H11),2,2])
826 Hin[:,0,0] = H11; Hin[:,0,1] = H12
827 Hin[:,1,0] = H12; Hin[:,1,1] = H22
832 if numpy.__version__ <
"1.8.0":
833 p1 = H12**2 + H13**2 + H23**2
834 zeroC = zeros(len(H11))
835 eig1 = array(H11); eig2 = array(H22); eig3 = array(H33)
836 v1 = array([onesC, zeroC, zeroC])
837 v2 = array([zeroC, onesC, zeroC])
838 v3 = array([zeroC, zeroC, onesC])
840 nI = (numpy.abs(p1) > tol**2)
842 H11 = H11[nI]; H12 = H12[nI]; H22 = H22[nI];
843 H13 = H13[nI]; H23 = H23[nI]; H33 = H33[nI];
844 q = array((H11+H22+H33)/3.)
847 p2 = (H11-q)**2 + (H22-q)**2 + (H33-q)**2 + 2.*p1
848 p = numpy.sqrt(p2 / 6.)
849 I = array([onesC,zeroC,onesC,zeroC,zeroC,onesC])
850 HH = array([H11,H12,H22,H13,H23,H33])
851 B = (1./p) * (HH-q.repeat(6).reshape(len(H11),6).T*I[:,nI])
853 detB = B[0,:]*B[2,:]*B[5,:]+2*(B[1,:]*B[4,:]*B[3,:])-B[3,:]*B[2,:]*B[3,:]-B[1,:]*B[1,:]*B[5,:]-B[0,:]*B[4,:]*B[4,:]
859 rgood = (rsmall==
False)*(rbig==
False)
860 phi = zeros(len(H11))
861 phi[rsmall] = pi / 3.
863 phi[rgood] = numpy.arccos(r[rgood]) / 3.
865 eig1[nI] = q + 2.*p*numpy.cos(phi)
866 eig3[nI] = q + 2.*p*numpy.cos(phi + (2.*pi/3.))
867 eig2[nI] = array(3.*q - eig1[nI] - eig3[nI])
869 v1[0,nI] = H22*H33 - H23**2 + eig1[nI]*(eig1[nI]-H33-H22)
870 v1[1,nI] = H12*(eig1[nI]-H33)+H13*H23
871 v1[2,nI] = H13*(eig1[nI]-H22)+H12*H23
872 v2[0,nI] = H12*(eig2[nI]-H33)+H23*H13
873 v2[1,nI] = H11*H33 - H13**2 + eig2[nI]*(eig2[nI]-H11-H33)
874 v2[2,nI] = H23*(eig2[nI]-H11)+H12*H13
875 v3[0,nI] = H13*(eig3[nI]-H22)+H23*H12
876 v3[1,nI] = H23*(eig3[nI]-H11)+H13*H12
877 v3[2,nI] = H11*H22 - H12**2 + eig3[nI]*(eig3[nI]-H11-H22)
878 L1 = numpy.sqrt((v1[:,nI]**2).sum(0))
879 L2 = numpy.sqrt((v2[:,nI]**2).sum(0))
880 L3 = numpy.sqrt((v3[:,nI]**2).sum(0))
881 v1[:,nI] /= L1.repeat(3).reshape(len(L1),3).T
882 v2[:,nI] /= L2.repeat(3).reshape(len(L1),3).T
883 v3[:,nI] /= L3.repeat(3).reshape(len(L1),3).T
884 eigL = array([eig1,eig2,eig3])
885 eigR = array([v1[0,:],v1[1,:],v1[2,:],\
886 v2[0,:],v2[1,:],v2[2,:],\
887 v3[0,:],v3[1,:],v3[2,:]])
888 bad = (numpy.abs(
analyt_rot(
fulleig(eigL),eigR)-H).sum(0) > tol) | isnan(eigR).any(0) | isnan(eigL).any(0)
890 log(INFO,
'%0.0f problems in eigendecomposition' % bad.sum())
891 for i
in numpy.where(bad)[0]:
892 [eigL_,eigR_] = pyeig(array([[H[0,i],H[1,i],H[3,i]],\
893 [H[1,i],H[2,i],H[4,i]],\
894 [H[3,i],H[4,i],H[5,i]]]))
896 eigR[:,i] = eigR_.T.flatten()
898 Hin = zeros([len(H11),3,3])
899 Hin[:,0,0] = H11; Hin[:,0,1] = H12; Hin[:,0,2] = H13
900 Hin[:,1,0] = H12; Hin[:,1,1] = H22; Hin[:,1,2] = H23
901 Hin[:,2,0] = H13; Hin[:,2,1] = H23; Hin[:,2,2] = H33
902 if numpy.__version__ >=
"1.8.0":
903 [eigL,eigR] = pyeig(Hin)
905 eigR = eigR.transpose([0,2,1]).reshape([len(H11),array(Hin.shape[1:3]).prod()]).T
925 eigL = numpy.log(eigL)
927 eigL = numpy.sqrt(eigL)
932 elif logexp==
'sqrtinv':
933 eigL = numpy.sqrt(1./eigL)
934 elif logexp==
'sqrinv':
937 eigL = numpy.exp(eigL)
939 error(
'logexp='+logexp+
' is an invalid value')
941 out =
sym2asym(HH).transpose().flatten()
942 Mp.vector().set_local(out)
949 mesh = Mp.function_space().
mesh()
950 element = Mp.function_space().ufl_element()
953 out = Function(FunctionSpace(mesh,element.family(),element.degree()))
954 out.vector().set_local(eigL.min(0))
958 mesh = Mp.function_space().
mesh()
959 element = Mp.function_space().ufl_element()
962 out = Function(TensorFunctionSpace(mesh,element.family(),element.degree()))
963 out.vector().set_local(eigR.transpose().flatten())
976 mesh = Mp.function_space().
mesh()
977 logMp = project(
logexpmetric(Mp),TensorFunctionSpace(mesh,
'CG',1))
997 cell2dof =
c_cell_dofs(mesh,TensorFunctionSpace(mesh,
"DG", 0))
999 coords = mesh.coordinates()
1000 p1 = coords[cells[:,0],:];
1001 p2 = coords[cells[:,1],:];
1002 p3 = coords[cells[:,2],:];
1003 r1 = p1-p2; r2 = p1-p3; r3 = p2-p3
1005 if mesh.geometry().dim() == 3:
1007 p4 = coords[cells[:,3],:];
1008 r4 = p1-p4; r5 = p2-p4; r6 = p3-p4
1009 rall = zeros([p1.shape[0],p1.shape[1],Nedg])
1010 rall[:,:,0] = r1; rall[:,:,1] = r2; rall[:,:,2] = r3;
1011 if mesh.geometry().dim() == 3:
1012 rall[:,:,3] = r4; rall[:,:,4] = r5; rall[:,:,5] = r6
1013 All = zeros([p1.shape[0],Nedg**2])
1014 inds = arange(Nedg**2).reshape([Nedg,Nedg])
1015 for i
in range(Nedg):
1016 All[:,inds[i,0]] = rall[:,0,i]**2; All[:,inds[i,1]] = 2.*rall[:,0,i]*rall[:,1,i]; All[:,inds[i,2]] = rall[:,1,i]**2
1017 if mesh.geometry().dim() == 3:
1018 All[:,inds[i,3]] = 2.*rall[:,0,i]*rall[:,2,i]; All[:,inds[i,4]] = 2.*rall[:,1,i]*rall[:,2,i]; All[:,inds[i,5]] = rall[:,2,i]**2
1019 Ain = zeros([Nedg*2-1,Nedg*p1.shape[0]])
1020 ndia = zeros(Nedg*2-1)
1021 for i
in range(Nedg):
1022 for j
in range(i,Nedg):
1023 iks1 = arange(j,Ain.shape[1],Nedg)
1025 Ain[i,iks1] = All[:,inds[j,j]]
1027 iks2 = arange(j-i,Ain.shape[1],Nedg)
1028 Ain[2*i-1,iks1] = All[:,inds[j-i,j]]
1029 Ain[2*i,iks2] = All[:,inds[j,j-i]]
1033 A = scipy.sparse.spdiags(Ain, ndia, Ain.shape[1], Ain.shape[1]).tocsr()
1034 b = ones(Ain.shape[1])
1035 X = scipy.sparse.linalg.spsolve(A,b)
1037 XX =
sym2asym(X.reshape([mesh.num_cells(),Nedg]).transpose())
1038 M = Function(TensorFunctionSpace(mesh,
"DG", 0))
1039 M.vector().set_local(XX.transpose().flatten()[cell2dof])
1048 eigL = numpy.sqrt(eigL)
1050 MM =
sym2asym(MM).transpose().flatten()
1051 M.vector().set_local(MM[cell2dof.flatten()])
1062 eigL = numpy.sqrt(1./eigL)
1064 MM =
sym2asym(MM).transpose().flatten()
1065 M.vector().set_local(MM[cell2dof.flatten()])
1072 solverp = {
"linear_solver":
"cg",
"preconditioner":
"ilu"}
1074 solverp = {
"linear_solver":
"lu"}
1075 mesh = H.function_space().
mesh()
1076 grada = Constant(grada)
1078 mm2sq = dot(grada*mm2,grada*mm2)
1080 V = TensorFunctionSpace(mesh,
'CG',1); H_trial = TrialFunction(V); H_test = TestFunction(V); Hnew=Function(V)
1081 a = (inner(grad(H_test),dot(mm2sq,grad(H_trial)))+inner(H_trial,H_test))*dx
1082 L = inner(H,H_test)*dx
1083 solve(a==L,Hnew,[], solver_parameters=solverp)
1094 if dolfin.__version__ >=
'1.3.0':
1095 if V.ufl_element().is_cellwise_constant():
1096 return arange(mesh.num_cells()*mesh.coordinates().shape[1]**2)
1098 return arange(mesh.num_vertices()*mesh.coordinates().shape[1]**2)
1102 void cell_dofs(boost::shared_ptr<GenericDofMap> dofmap,
1103 const std::vector<std::size_t>& cell_indices,
1104 std::vector<std::size_t>& dofs)
1107 std::size_t local_dof_size = dofmap->cell_dofs(0).size();
1108 const std::size_t size = cell_indices.size()*local_dof_size;
1110 for (std::size_t i=0; i<cell_indices.size(); i++)
1111 for (std::size_t j=0; j<local_dof_size;j++)
1112 dofs[i*local_dof_size+j] = dofmap->cell_dofs(cell_indices[i])[j];
1115 module = compile_extension_module(code)
1116 return module.cell_dofs(V.dofmap(), arange(mesh.num_cells(), dtype=numpy.uintp))
1119 if __name__==
"__main__":
1122 from minimal_example
import minimal_example
1125 from minimal_example_minell
import check_metric_ellipse
1128 from play_multigrid
import test_refine_metric
1131 from mesh_metric2_example
import test_mesh_metric
1134 from circle_convergence
import circle_convergence
1135 circle_convergence()
1137 from maximal_example
import maximal_example
def consistent_interpolation