def set_basis(order, basis_name): ''' Sets the basis class given the basis_name string argument Inputs: ------- order: solution order basis_name: name of the basis function we wish to instantiate as a class Outputs: -------- basis: instantiated basis class Raise: ------ If the basis class is not defined, returns a NotImplementedError ''' if BasisType[basis_name] == BasisType.LagrangeSeg: basis = basis_defs.LagrangeSeg(order) elif BasisType[basis_name] == BasisType.LegendreSeg: basis = basis_defs.LegendreSeg(order) elif BasisType[basis_name] == BasisType.LagrangeQuad: basis = basis_defs.LagrangeQuad(order) elif BasisType[basis_name] == BasisType.LegendreQuad: basis = basis_defs.LegendreQuad(order) elif BasisType[basis_name] == BasisType.LagrangeTri: basis = basis_defs.LagrangeTri(order) elif BasisType[basis_name] == BasisType.HierarchicH1Tri: basis = basis_defs.HierarchicH1Tri(order) else: raise NotImplementedError return basis
def test_legendre_spacetime_stiffnessmatrix_spacedir_phys(dt, order): ''' This test compares the analytical solution of the space-time stiffness matrix in space to the computed one. ''' basis = basis_defs.LegendreSeg(order) basis_st = basis_defs.LegendreQuad(order) mesh = mesh_common.mesh_1D(num_elems=1, xmin=0., xmax=1.) # Set quadrature basis.set_elem_quadrature_type("GaussLegendre") basis.set_face_quadrature_type("GaussLegendre") basis_st.set_elem_quadrature_type("GaussLegendre") basis_st.set_face_quadrature_type("GaussLegendre") mesh.gbasis.set_elem_quadrature_type("GaussLegendre") mesh.gbasis.set_face_quadrature_type("GaussLegendre") # Get stiffness matrix in space SMS = basis_st_tools.get_stiffness_matrix_ader(mesh, basis, basis_st, order, dt, elem_ID=0, grad_dir=0, physical_space=True) ''' Reference: Dumbser, M., Enaux, C., and Toro, E. JCP 2008 Vol. 227, Issue 8, Pgs: 3971 - 4001 Appendix B Note: We multiply by 4 here because (unlike Dumbser's paper), we multiply by the inverse jacobian to account for non-ideal meshes See the Quail documentation (Section for ADER-DG: space-time predictor step where the K matrices are defined) ''' if order == 1: expected = 4.0 * np.array([[0., 2., 0., 0.], [0., 0., 0., 0.], [0., 0., 0., 2. / 3.], [0., 0., 0., 0.]]) elif order == 2: expected = 4.0 * np.array([[0., 2., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 2., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 2. / 3., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 2. / 3., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 2. / 5., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 2. / 5.], [0., 0., 0., 0., 0., 0., 0., 0., 0.]]) # Assert np.testing.assert_allclose(SMS.transpose(), expected, rtol, atol)
def test_legendre_spacetime_stiffnessmatrix_timedir(dt, order): ''' This test compares the analytical solution of the space-time stiffness matrix in time to the computed one. ''' basis = basis_defs.LegendreSeg(order) basis_st = basis_defs.LegendreQuad(order) mesh = mesh_common.mesh_1D(num_elems=1, xmin=-1., xmax=1.) # Set quadrature basis.set_elem_quadrature_type("GaussLegendre") basis.set_face_quadrature_type("GaussLegendre") basis_st.set_elem_quadrature_type("GaussLegendre") basis_st.set_face_quadrature_type("GaussLegendre") mesh.gbasis.set_elem_quadrature_type("GaussLegendre") mesh.gbasis.set_face_quadrature_type("GaussLegendre") # Get stiffness matrix in time SMT = basis_st_tools.get_stiffness_matrix_ader(mesh, basis, basis_st, order, dt, elem_ID=0, grad_dir=-1, physical_space=False) ''' Reference: Dumbser, M., Enaux, C., and Toro, E. JCP 2008 Vol. 227, Issue 8, Pgs: 3971 - 4001 Appendix B ''' # Multiply by 2.0 caused by reference element shift [0, 1] -> [-1, 1] if order == 1: expected = 2.0 * np.array([[0., 0., 0., 0.], [0., 0., 0., 0.], [2., 0., 0., 0.], [0., 2. / 3., 0., 0.]]) elif order == 2: expected = 2.0 * np.array([[0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0.], [2., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 2. / 3., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 2. / 5., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 2., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 2. / 3., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 2. / 5., 0., 0., 0.]]) # Assert np.testing.assert_allclose(SMT, expected, rtol, atol)
def test_temporal_flux_ader_tn(order): ''' This test compares the analytical solution of the space-time temporal flux evaluated at t^{n} to the computed one. ''' basis = basis_defs.LegendreSeg(order) basis_st = basis_defs.LegendreQuad(order) mesh = mesh_common.mesh_1D(num_elems=1, xmin=-1., xmax=1.) # Set quadrature basis.set_elem_quadrature_type("GaussLegendre") basis.set_face_quadrature_type("GaussLegendre") basis_st.set_elem_quadrature_type("GaussLegendre") basis_st.set_face_quadrature_type("GaussLegendre") mesh.gbasis.set_elem_quadrature_type("GaussLegendre") mesh.gbasis.set_face_quadrature_type("GaussLegendre") # Get flux matrices in time FTR = basis_st_tools.get_temporal_flux_ader(mesh, basis_st, basis, order, physical_space=False) ''' Reference: Dumbser, M., Enaux, C., and Toro, E. JCP 2008 Vol. 227, Issue 8, Pgs: 3971 - 4001 Appendix B ''' # Multiply by 2.0 caused by reference element shift [0, 1] -> [-1, 1] if order == 1: expected = 2.0 * np.array([[1., 0.], [0., 1. / 3.], [-1., 0.], [0., -1. / 3.]]) elif order == 2: expected = 2.0 * np.array( [[1., 0., 0.], [0., 1. / 3., 0.], [0., 0., 1. / 5.], [-1, 0., 0.], [0., -1. / 3., 0.], [0., 0., -1. / 5.], [1., 0., 0], [0., 1. / 3., 0.], [0., 0., 1. / 5.]]) # Assert np.testing.assert_allclose(FTR, expected, rtol, atol)
def get_legendre_basis_2D(xq, p, basis_val=None, basis_ref_grad=None): ''' Calculates the 2D Legendre basis functions Inputs: ------- xq: coordinate of current node [nq, ndims] p: order of polynomial space Outputs: -------- basis_val: evaluated basis [nq, nb] basis_ref_grad: evaluated physical gradient of basis [nq, nb, ndims] ''' nq = xq.shape[0] if basis_ref_grad is not None: gradx = np.zeros((nq, p + 1, 1)) grady = np.zeros_like(gradx) else: gradx = None grady = None # Always need basis_val valx = np.zeros((nq, p + 1)) valy = np.zeros_like(valx) legendre_seg = basis_defs.LegendreSeg(p) get_legendre_basis_1D(xq[:, 0], p, valx, gradx) get_legendre_basis_1D(xq[:, 1], p, valy, grady) if basis_val is not None: for i in range(nq): basis_val[i, :] = np.reshape(np.outer(valx[i, :], \ valy[i, :]), (-1, ), 'F') if basis_ref_grad is not None: for i in range(nq): basis_ref_grad[i, :, 0] = np.reshape(np.outer(gradx[i, :, 0], \ valy[i, :]), (-1, ), 'F') basis_ref_grad[i, :, 1] = np.reshape(np.outer(valx[i, :], \ grady[i, :, 0]), (-1, ), 'F')