-
I think after #823 I've solved my problem of calculatring a weak from skfem import *
from skfem.helpers import div, dot
import ex17
@BilinearForm
def vector_mass(sigma, tau, w):
return dot(sigma, tau)
@LinearForm
def linf(tau, w):
return - w["phi"] * div(tau)
mesh, conductivity = ex17.basis0.mesh.to_meshtri(ex17.conductivity)
basis = CellBasis(mesh, ElementTriRT0())
indicator = (conductivity == conductivity.max()).astype(float)
M = vector_mass.assemble(basis)
rhs = linf.assemble(basis, phi=basis.with_element(ElementTriP0()).interpolate(indicator))
sigma = solve(M, rhs) There's an intriguing use of side-effects in a |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 21 replies
-
You should be able to do Basis.refinterp and then apply plt.quiver or similar. Should there be such a functionality in skfem.visuals.matplotlib? |
Beta Was this translation helpful? Give feedback.
-
Tangential idea: in the example, the quadrilateral mesh from ex17 was split into a triangular mesh mesh, conductivity = ex17.basis0.mesh.to_meshtri(ex17.conductivity) as we don't have |
Beta Was this translation helpful? Give feedback.
-
The normals and their feet are attributes of a interfacial_facets = np.intersect1d(
*(basis0.mesh.t2f[:, s] for s in basis0.mesh.subdomains.values())
)
fbasis = FacetBasis(
basis0.mesh,
basis0.elem,
facets=interfacial_facets,
quadrature=(np.full((1, 1), 0.5), np.ones(1)),
)
plot(basis0.mesh, indicator, ax=draw(basis0.mesh)).quiver(
*fbasis.global_coordinates().value.squeeze(),
*fbasis.normals.value.squeeze() * sigma[interfacial_facets]
).axes.get_figure().savefig(Path(__file__).with_suffix(".png")) |
Beta Was this translation helpful? Give feedback.
-
Am I understanding And this is useful, for example, in an electromagnetics problem where And in this example |
Beta Was this translation helpful? Give feedback.
-
By the way, you can (ab)use def plot_query_points(x, ax, style, label):
ax.plot(x[0], x[1], style, label=label)
plt.subplots(figsize=(5,5))
skfem.visuals.matplotlib.draw(mesh, ax=plt.gca())
basis_p1.get_dofs(facets=lambda x: plot_query_points(x, plt.gca(), 'or', 'facets'))
basis_p1.get_dofs(elements=lambda x: plot_query_points(x, plt.gca(), 'ob', 'elements'))
plt.legend()
|
Beta Was this translation helpful? Give feedback.
-
So I have written a script adapting ex37 from Tet to Quad (and flipping the sign of the source term for convenience) and plotted side-by-side the RT0 fluxes and refinterp-ed vectors. d866851/docs/examples/ex37quad.py. I'm thinking of the flux density as minus the gradient but wanted to have the arrows pointing inwards for a tidier figure; hence the flip in sign of the solution. The centre is now a minimum, attracting flux, with the gradient pointing outwards. It's working O. K. but doesn't look quite right in one respect: the RT0 DoF facet-fluxes look exactly as I would expect them to but some of the interpolated vectors aren't pointing the right way, I mean the ones that are one square in diagonally from the corners. |
Beta Was this translation helpful? Give feedback.
So I have written a script adapting ex37 from Tet to Quad (and flipping the sign of the source term for convenience) and plotted side-by-side the RT0 fluxes and refinterp-ed vectors. d866851/docs/examples/ex37quad.py.
I'm thinking of the flux density as minus the gradient but wanted to have the arrows pointing inwards for a tidier figure; hence the flip in sign of the solution. The centre is now a minimum, attracting flux, with the gradient pointing outwards.
It's working O. K. but doesn't look quite right in one respect: the RT0 DoF facet-fluxes look exactly as I would expect them to but some of the interpolated vectors aren't pointing the right way, I mean the ones that are one square …