@@ -337,50 +337,87 @@ def test_node_reduction(actx_factory):
337337
338338# {{{ test_stretch_factor
339339
340- def make_simplex_mesh (order ):
340+ def make_stretch_mesh (order , cls ):
341341 vertices = np .array ([
342342 [- 1 , - 1 , 0 ], [1 , - 1 , 0 ], [- 1 , 1 , 0 ], [1 , 1 , 0 ], [3 , - 1 , 0 ], [3 , 1 , 0 ],
343343 ], dtype = np .float64 ).T
344- vertex_indices = np .array ([
345- (0 , 1 , 2 ), (1 , 3 , 2 ),
346- (1 , 4 , 3 ), (4 , 5 , 3 ),
347- ], dtype = np .int32 )
348344
349- from meshmode .mesh import SimplexElementGroup
345+ import meshmode .mesh as mm
346+ if issubclass (cls , mm .SimplexElementGroup ):
347+ vertex_indices = np .array ([
348+ (0 , 1 , 2 ), (1 , 3 , 2 ),
349+ # (1, 4, 3), (4, 5, 3),
350+ ], dtype = np .int32 )
351+ elif issubclass (cls , mm .TensorProductElementGroup ):
352+ vertex_indices = np .array ([
353+ (0 , 1 , 2 , 3 ),
354+ # (1, 4, 3, 5)
355+ ], dtype = np .int32 )
356+ else :
357+ raise ValueError
358+
350359 from meshmode .mesh .generation import make_group_from_vertices
351360 grp = make_group_from_vertices (
352361 vertices , vertex_indices , order ,
353362 unit_nodes = None ,
354- group_cls = SimplexElementGroup )
363+ group_cls = cls )
355364
356- from meshmode .mesh import Mesh
357- return Mesh (vertices , [grp ], is_conforming = True )
365+ return mm .Mesh (vertices , [grp ], is_conforming = True )
358366
359367
360- def make_square_mesh (order ):
361- vertices = np .array ([
362- [- 1 , - 1 , 0 ], [1 , - 1 , 0 ], [- 1 , 1 , 0 ], [1 , 1 , 0 ],
363- [3 , - 1 , 0 ], [3 , 1 , 0 ],
364- ], dtype = np .float64 ).T
365- vertex_indices = np .array ([
366- (0 , 1 , 2 , 3 ), (1 , 4 , 3 , 5 )
367- ], dtype = np .int32 )
368+ def make_torus_mesh (order , cls , a = 2.0 , b = 1.0 , n_major = 12 , n_minor = 6 ):
369+ u , v = np .mgrid [0 :2 * np .pi :2 * np .pi / n_major , 0 :2 * np .pi :2 * np .pi / n_minor ]
370+
371+ x = np .cos (u ) * (a + b * np .cos (v ))
372+ y = np .sin (u ) * (a + b * np .cos (v ))
373+ z = b * np .sin (v )
374+ del u , v
375+
376+ vertices = (
377+ np .vstack ((x [np .newaxis ], y [np .newaxis ], z [np .newaxis ]))
378+ .transpose (0 , 2 , 1 ).copy ().reshape (3 , - 1 ))
379+
380+ def idx (i , j ):
381+ return (i % n_major ) + (j % n_minor ) * n_major
382+
383+ import meshmode .mesh as mm
384+ # i, j = 0, 0
385+ i , j = 0 , n_minor // 3
386+ if issubclass (cls , mm .SimplexElementGroup ):
387+ vertex_indices = [
388+ (idx (i , j ), idx (i + 1 , j ), idx (i , j + 1 )),
389+ (idx (i + 1 , j ), idx (i + 1 , j + 1 ), idx (i , j + 1 )),
390+ ]
391+ elif issubclass (cls , mm .TensorProductElementGroup ):
392+ vertex_indices = [(idx (i , j ), idx (i + 1 , j ), idx (i , j + 1 ), idx (i + 1 , j + 1 ))]
393+ else :
394+ raise TypeError (f"unsupported 'group_cls': { cls } " )
368395
369- from meshmode .mesh import TensorProductElementGroup
370396 from meshmode .mesh .generation import make_group_from_vertices
397+ vertex_indices = np .array (vertex_indices , dtype = np .int32 )
371398 grp = make_group_from_vertices (
372399 vertices , vertex_indices , order ,
373- unit_nodes = None ,
374- group_cls = TensorProductElementGroup )
400+ group_cls = cls )
401+
402+ # NOTE: project the nodes back to the torus surface
403+ u = np .arctan2 (grp .nodes [1 ], grp .nodes [0 ])
404+ v = np .arctan2 (
405+ grp .nodes [2 ],
406+ grp .nodes [0 ] * np .cos (u ) + grp .nodes [1 ] * np .sin (u ) - a )
375407
376- from meshmode .mesh import Mesh
377- return Mesh (vertices , [grp ], is_conforming = True )
408+ nodes = np .empty_like (grp .nodes )
409+ nodes [0 ] = np .cos (u ) * (a + b * np .cos (v ))
410+ nodes [1 ] = np .sin (u ) * (a + b * np .cos (v ))
411+ nodes [2 ] = b * np .sin (v )
412+
413+ return mm .Mesh (vertices , [grp .copy (nodes = nodes )], is_conforming = True )
378414
379415
380416def make_simplex_stretch_factors (ambient_dim ):
381417 from pytential .symbolic .primitives import \
382418 _equilateral_parametrization_derivative_matrix
383419 equi_pder = _equilateral_parametrization_derivative_matrix (ambient_dim )
420+ # equi_pder = sym.parametrization_derivative_matrix(ambient_dim, ambient_dim - 1)
384421 equi_form1 = sym .cse (equi_pder .T @ equi_pder , "pd_mat_jtj" )
385422
386423 from pytential .symbolic .primitives import _small_mat_eigenvalues
@@ -406,16 +443,29 @@ def test_stretch_factor(actx_factory, order, visualize=False):
406443 actx = actx_factory ()
407444
408445 def wobble (x ):
446+ rx , ry = 2 , 0.5
447+ theta = np .pi / 4
448+
409449 result = np .empty_like (x )
410- result [0 ] = x [0 ]
411- result [1 ] = x [1 ]
412- result [2 ] = np .sin (x [1 ]) * np .sin (x [0 ])
450+ result [0 ] = rx * (np .cos (theta ) * x [0 ] - np .sin (theta ) * x [1 ])
451+ result [1 ] = np .sin (ry * (np .sin (theta ) * x [0 ] + np .cos (theta ) * x [1 ]))
452+ result [2 ] = x [2 ]
453+ # result[2] = np.sin(x[1]) * np.sin(x[0])
413454
414455 return result
415456
416- from meshmode .mesh .processing import map_mesh
417- square_mesh = map_mesh (make_square_mesh (order ), wobble )
418- simplex_mesh = map_mesh (make_simplex_mesh (order ), wobble )
457+ from meshmode .mesh import SimplexElementGroup , TensorProductElementGroup
458+ if True :
459+ square_mesh = make_torus_mesh (order , TensorProductElementGroup )
460+ simplex_mesh = make_torus_mesh (order , SimplexElementGroup )
461+ else :
462+ from meshmode .mesh .processing import map_mesh
463+ square_mesh = map_mesh (
464+ make_stretch_mesh (order , TensorProductElementGroup ),
465+ wobble )
466+ simplex_mesh = map_mesh (
467+ make_stretch_mesh (order , SimplexElementGroup ),
468+ wobble )
419469
420470 from meshmode .discretization import Discretization
421471 import meshmode .discretization .poly_element as mpoly
@@ -429,6 +479,14 @@ def wobble(x):
429479 q0 , q1 = bind (square_discr ,
430480 make_quad_stretch_factors (square_discr .ambient_dim ))(actx )
431481
482+ # s0 = (1 + (np.sqrt(3) / 4) / 4) * s0
483+ # s1 = (1 + (np.sqrt(3) / 4) / 4) * s1
484+
485+ print (actx .to_numpy (actx .np .min (s0 ))[()], actx .to_numpy (actx .np .max (s0 ))[()])
486+ print (actx .to_numpy (actx .np .min (q0 ))[()], actx .to_numpy (actx .np .max (q0 ))[()])
487+ print (actx .to_numpy (actx .np .min (s1 ))[()], actx .to_numpy (actx .np .max (s1 ))[()])
488+ print (actx .to_numpy (actx .np .min (q1 ))[()], actx .to_numpy (actx .np .max (q1 ))[()])
489+
432490 if not visualize :
433491 return
434492
@@ -450,13 +508,10 @@ def wobble(x):
450508
451509 xi = simplex_discr .groups [0 ].unit_nodes
452510 for name , sv in zip (["s0" , "s1" ], [s0 , s1 ]):
453- sv0 = actx .to_numpy (sv [0 ])[0 ].ravel ()
454- sv1 = actx .to_numpy (sv [0 ])[0 ].ravel ()
455- print (sv0 , sv1 )
511+ sv = actx .to_numpy (sv [0 ])[0 ].ravel ()
456512
457513 ax = fig .gca ()
458- im = ax .tricontourf (xi [0 ], xi [1 ], sv0 , levels = 32 )
459- im = ax .tricontourf (- xi [0 ], - xi [1 ], sv1 , levels = 32 )
514+ im = ax .tricontourf (xi [0 ], xi [1 ], sv , levels = 32 )
460515 fig .colorbar (im , ax = ax )
461516 fig .savefig (f"stretch_factor_simplex_{ order :02d} _{ name } " )
462517 fig .clf ()
@@ -468,7 +523,6 @@ def wobble(x):
468523 xi = square_discr .groups [0 ].unit_nodes
469524 for name , sv in zip (["q0" , "q1" ], [q0 , q1 ]):
470525 sv = actx .to_numpy (sv [0 ])[0 ]
471- print (sv )
472526
473527 ax = fig .gca ()
474528 im = ax .tricontourf (xi [0 ], xi [1 ], sv , levels = 32 )
0 commit comments