How do I move data from one basis/quadrature to another #855
-
cb_p1 = skfem.CellBasis(mesh, skfem.ElementTriP1())
cb_p0 = cb_p1.with_element(skfem.ElementTriP0())
ifb_p1 = skfem.InteriorFacetBasis(mesh, skfem.ElementTriP1())
sigma = cb_p0.zeros()
sigma[cb_p0.get_dofs(elements='a')] = 1
sigma[cb_p0.get_dofs(elements='b')] = 2
sigma[cb_p0.get_dofs(elements='c')] = 3
u = cb_p1.zeros()
@skfem.Functional
def func1(w):
return w.u
@skfem.Functional
def func2(w):
return w.sigma
func1.assemble(cb_p1, u=u) # ok
func2.assemble(cb_p0, sigma=sigma) # ok
func1.assemble(ifb_p1, u=u) # ok, and half of what_i_want (see below)
# func2.assemble(ifb_p1, sigma=sigma) # ValueError: Input array has wrong size.
# func2.assemble(ifb_p1, sigma=cb_p0.interpolate(sigma)) # ValueError: Quadrature mismatch
func2.assemble(ifb_p1, sigma=cb_p1.project(cb_p0.interpolate(sigma))) # No error, but inexact sigma (see plot)
# also tried cb_dg = skfem.CellBasis(mesh, skfem.ElementDG(skfem.ElementTriP1()))
# in place of cb_p0, but cb_dg.zeros().shape != cb_p1.zeros().shape
# I guess because cb_dg and cb_p1 and different basises
fig, ax = plt.subplots(1, 2, figsize=(10,5))
skfem.visuals.matplotlib.plot(cb_p0, sigma, ax=ax[0], cmap='viridis', shading='gouraud')
skfem.visuals.matplotlib.draw(mesh, ax=ax[0])
skfem.visuals.matplotlib.plot(cb_p1, cb_p1.project(cb_p0.interpolate(sigma)), ax=ax[1], cmap='viridis', shading='gouraud')
skfem.visuals.matplotlib.draw(mesh, ax=ax[1]) @skfem.Functional
def what_i_want(w):
return dot(w.n, sigma*grad(u))
what_i_want.assemble(ifb_p1, sigma=sigma, u=u) # ValueError: Input array has wrong size. How can I get the piecewise constant |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 4 replies
-
Try always doing an explicit call to Basis.interpolate() when passing kwargs to Form.assemble(). It will never work automagically if you combine two different bases. |
Beta Was this translation helpful? Give feedback.
-
Supposing I have some continuous def f(x):
return np.sin(x[0]) # for example Then when I write cb1 = CellBasis(mesh, ElementTriP1())
g = cb1.project(f)
Then when I write h = cb1.interpolate(g)
When I'm working with So I can write cb1 = CellBasis(mesh, ElementTriP1())
fb1 = InteriorFacetBasis(mesh, ElementTriP1()) # same basis, different quadrature
g = cb1.project(f)
hc = cb1.interpolate(g)
hf = fb1.interpolate(g) # also works, because g is equally valid in cb1 and fb1. When working with lots of basis, and moving things from P1 and P0 into the same Functional for integration, I'm going to need to use cell + facet basises just like this, one of each, to get everything into a DiscreteField. Care has to be taken to make sure the DiscreteFields are using the same quadrature, even if they come from different basis classes. Forgive me asking questions like this over and over, I keep getting index errors, size mismatch errors, etc, and they all keep coming back to messing up/ mixing up the basis and/or quadrature points. But is my code/ideas in this comment correct? |
Beta Was this translation helpful? Give feedback.
Try always doing an explicit call to Basis.interpolate() when passing kwargs to Form.assemble(). It will never work automagically if you combine two different bases.