diff --git a/src/ScalarEq/rhs.jl b/src/ScalarEq/rhs.jl
index 75100c42b3a8369bd1470fe804dc7319af3a2d23..8f4f038abe838aee08e9f4da3d0be00f1815e35e 100644
--- a/src/ScalarEq/rhs.jl
+++ b/src/ScalarEq/rhs.jl
@@ -268,21 +268,54 @@ end
 
 
 function rhs!(env, mesh::Mesh1d, P::Project, hrsc::Nothing)
+  if mesh.element.kind === :modal_bspline2
+    modal_rhs!(env, mesh, P, hrsc)
+  else
+    nodal_rhs!(env, mesh, P, hrsc)
+  end
+end
 
-  @unpack cache, mesh = env
-  @unpack equation = P
 
-  @unpack flx_u, src_u   = get_static_variables(cache)
-  @unpack u              = get_dynamic_variables(cache)
-  @unpack rhs_u          = get_rhs_variables(cache)
-  @unpack nflx_u, bdry_u = get_bdry_variables(cache)
+function nodal_rhs!(env, mesh::Mesh1d, P::Project, hrsc::Nothing)
+  @unpack flx_u, src_u   = get_static_variables(mesh)
+  @unpack u              = get_dynamic_variables(mesh)
+  @unpack rhs_u          = get_rhs_variables(mesh)
+  @unpack nflx_u, bdry_u = get_bdry_variables(mesh)
 
   dg1d.interpolate_face_data!(mesh, u, bdry_u)
-  broadcast_volume!(flux_source, equation, mesh)
-  broadcast_faces!(llf_1d, equation, mesh)
-  # broadcast_bdry!(bdryllf_1d, equation, P.bdrycond, mesh)
+  broadcast_volume!(flux_source, P.equation, mesh)
+  broadcast_faces!(llf_1d, P.equation, mesh)
 
   compute_rhs_weak_form!(rhs_u, flx_u, src_u, nflx_u, mesh)
+  return
+end
+
+
+function modal_rhs!(env, mesh::Mesh1d, P::Project, hrsc::Nothing)
+  @unpack flx_u, src_u,
+          u_modal, flx_u_modal,
+          src_u_modal    = get_static_variables(mesh)
+  @unpack u              = get_dynamic_variables(mesh)
+  @unpack rhs_u          = get_rhs_variables(mesh)
+  @unpack nflx_u, bdry_u = get_bdry_variables(mesh)
+
+  u_modal .= u
+  for (v_u, v_u_modal) in zip(eachcell(mesh,u),eachcell(mesh,u_modal))
+    mul!(v_u, P.prms.V_bspline, v_u_modal)
+  end
+
+  dg1d.interpolate_face_data!(mesh, u, bdry_u)
+  broadcast_volume!(flux_source, P.equation, mesh)
+  broadcast_faces!(llf_1d, P.equation, mesh)
+
+  for (v_flx_u, v_flx_u_modal) in zip(eachcell(mesh,flx_u),eachcell(mesh,flx_u_modal))
+    mul!(v_flx_u_modal, P.prms.invV_bspline, v_flx_u)
+  end
+  for (v_src_u, v_src_u_modal) in zip(eachcell(mesh,src_u),eachcell(mesh,src_u_modal))
+    mul!(v_src_u_modal, P.prms.invV_bspline, v_src_u)
+  end
+  compute_rhs_weak_form!(rhs_u, flx_u_modal, src_u_modal, nflx_u, mesh)
+  u .= u_modal
 
   return
 end
diff --git a/src/ScalarEq/setup.jl b/src/ScalarEq/setup.jl
index 690f9b41c51a3d5d41f12405602125516820e6f9..7e85208e48a900fb8ecbf442ecc736491f85eab9 100644
--- a/src/ScalarEq/setup.jl
+++ b/src/ScalarEq/setup.jl
@@ -14,10 +14,16 @@ function Project(env::Environment, mesh::Mesh1d, prms)
   analyze_error = prms["ScalarEq"]["analyze_error"]
   analyze_error_norm = prms["ScalarEq"]["analyze_error_norm"]
   V_bernstein = dg1d.Bernstein.vandermonde_matrix(mesh.element.z)
+  if mesh.element isa DGElement && mesh.element.kind === :modal_bspline2
+    V_bspline = dg1d.Bspline.vandermonde_matrix(mesh.element.z, mesh.element.bs)
+    invV_bspline = pinv(V_bspline)
+  else
+    V_bspline, invV_bspline = nothing, nothing
+  end
   fixedprms = (; bernstein, av_derivative_scheme, av_drag, hrsc, muscl_omega,
                  slope_limiter_method, slope_limiter_tvb_M,
                  av_recompute_substeps,
-                 V_bernstein,
+                 V_bernstein, V_bspline, invV_bspline,
                  analyze_error, analyze_error_norm)
 
   # construct Project
@@ -126,6 +132,9 @@ function register_equation!(mesh::Mesh1d, P::Project)
       TODO(P.prms.hrsc)
     end
   end
+  if mesh.element isa DGElement && mesh.element.kind === :modal_bspline2
+    register_variables!(mesh.cache, static_variablenames=(:u_modal,:flx_u_modal,:src_u_modal))
+  end
 end
 function register_equation!(mesh::Mesh2d, P::Project)
   register_variables!(mesh.cache,
diff --git a/src/bspline.jl b/src/bspline.jl
index 2ac9014014547b404ef5d0131e9eb67b0b391d29..281336dc93e15b97bf7622234b1521fd436b2006 100644
--- a/src/bspline.jl
+++ b/src/bspline.jl
@@ -108,12 +108,13 @@ end
 function unsafe_interpolate(x::Real, coeffs::AbstractVector, bs::Bspline2)
   @unpack Npts, xs = bs
   @inbounds xl, xr = xs[1], xs[end]
-  xl ≤ x ≤ xr || return 0.0
+  xl == x && return coeffs[1]
+  xr == x && return coeffs[end]
+  xl < x < xr || return 0.0
   o = 2 # offset duplicated bdry knots
   v_xs = view(xs, o .+ (1:Npts))
   ir = searchsortedfirst(v_xs, x)
   il = ir-1
-  il < 1 && return coeffs[1] # x == xl
   is_supp = max(il-1,1):min(ir+1,Npts+1)
   B = 0.0
   @inbounds for i in is_supp
diff --git a/test/IntegrationTests/refs/modal_bspline2_advection_sine/modal_bspline2_advection_sine.toml b/test/IntegrationTests/refs/modal_bspline2_advection_sine/modal_bspline2_advection_sine.toml
new file mode 100644
index 0000000000000000000000000000000000000000..3d670bb74227fed93e1f0d23722e299d208b3a0c
--- /dev/null
+++ b/test/IntegrationTests/refs/modal_bspline2_advection_sine/modal_bspline2_advection_sine.toml
@@ -0,0 +1,21 @@
+[Evolution]
+cfl = 0.5
+tend = 2.2
+
+[ScalarEq]
+analyze_error = true
+equation = "advection"
+id = "sine"
+
+[Output]
+substep_every_iteration = 200
+substep_variables = ["u", "u_err"]
+aligned_ts = "$(collect(range(0.1,2.2,step=0.1)))"
+variables1d = ["u", "u_err"]
+
+[Mesh]
+dg_kind = "modal_bspline2"
+range = [0.0, 1.0]
+k = 30
+basis = "lgl"
+n = 5
diff --git a/test/IntegrationTests/refs/modal_bspline2_advection_sine/output1d.h5 b/test/IntegrationTests/refs/modal_bspline2_advection_sine/output1d.h5
new file mode 100644
index 0000000000000000000000000000000000000000..d0e6758edad6c361ad5196a967dd777fb917170e
Binary files /dev/null and b/test/IntegrationTests/refs/modal_bspline2_advection_sine/output1d.h5 differ
diff --git a/test/IntegrationTests/refs/modal_bspline2_advection_sine/substep_output.h5 b/test/IntegrationTests/refs/modal_bspline2_advection_sine/substep_output.h5
new file mode 100644
index 0000000000000000000000000000000000000000..14ee01b05bc913a144ae5617141275c5929794b4
Binary files /dev/null and b/test/IntegrationTests/refs/modal_bspline2_advection_sine/substep_output.h5 differ
diff --git a/test/IntegrationTests/refs/testconfig.toml b/test/IntegrationTests/refs/testconfig.toml
index b5cdbccf82d11f4257b10818dcd97077dd2bfe0b..f9687bb2450cee77da23cdc94519931fcb9c79f3 100644
--- a/test/IntegrationTests/refs/testconfig.toml
+++ b/test/IntegrationTests/refs/testconfig.toml
@@ -10,6 +10,9 @@ variables1d = [ "u", "u_err" ]
 [modal_bernstein_advection_sine]
 variables1d = [ "u" ]
 
+[modal_bspline2_advection_sine]
+variables1d = [ "u", "u_err" ]
+
 [advection_sine_analysis]
 variables0d = [ "u_err_norm", "u_norm2" ]
 variables1d = [ "u" ]