I am attempting to illustrate a mapping from an isoparametric space to a parent (x-y) space for a variety of finite element types. Here we consider the simplest case of a three noded triangular element. In the isoparametric space the triangle has nodes at {{1,0},{0,1},{0,1}}
with interpolating functions n1=\xi
n2=\eta
n3=1-\xi-\eta
. The isoparametric space maps to the parent space by
x=N1*x1=N2*x2+N3*x3, and y=N1*y1+N2*y2+N3*y3
Where xi is the x coordinate of the i-th node.
I am currently plotting this with the following code:
Step 1: Define interpolating functions and nodal positions in the isoparametric and parent spaces
n1lintri[x_, y_] := x
n2lintri[x_, y_] := y
n3lintri[x_, y_] := 1 - x - y
xltar = 1; yltar = 0;
xltbr = 0; yltbr = 1;
xltcr = 0; yltcr = 0;
xlta = 4; ylta = 3;
xltb = 1; yltb = 2;
xltc = 3; yltc = 1;
Step 2: Define domain to plot over
domain = Region[Triangle[{{0, 0}, {1, 0}, {0, 1}}]];
Step 3: Create parametric plot of isoparametric and parent domains and list of nodal points
lintri1 =
ParametricPlot[{
xltar n1lintri[x, y] + xltbr n2lintri[x, y] +
xltcr n3lintri[x, y],
yltar n1lintri[x, y] + yltbr n2lintri[x, y] +
yltcr n3lintri[x, y]}, {x, y} \[Element] domain, Frame -> False,
Axes -> False];
lintri1points = {{xltar, yltar}, {xltbr, yltbr}, {xltcr, yltcr}};
lintri2 =
ParametricPlot[{
xlta n1lintri[x, y] + xltb n2lintri[x, y] + xltc n3lintri[x, y],
ylta n1lintri[x, y] + yltb n2lintri[x, y] +
yltc n3lintri[x, y]}, {x, y} \[Element] domain, Frame -> False];
lintri2points = {{xlta, ylta}, {xltb, yltb}, {xltc, yltc}};
Step 4: Plot
Labeled[Show[lintri1,
ListPlot[lintri1points, PlotStyle -> {Red, PointSize[Large]},
Frame -> False], Axes -> True, AxesOrigin -> {0, 0},
PlotRange -> All], {Style["\[Xi]", 18, Black, Bold],
Style["\[Eta]", 18, Black, Bold]}, {Bottom, Left}]
Labeled[Show[lintri2,
ListPlot[lintri2points, PlotStyle -> {Red, PointSize[Large]},
Frame -> False], Axes -> True, AxesOrigin -> {0, 0},
PlotRange -> All], {Style["x", 18, Black, Bold],
Style["y", 18, Black, Bold]}, {Bottom, Left}]
Which yields the following
I would like to add labels numbering each node (in red) numbered sequentially with an offset so that the number is not on top of the node. For example
As elements can have many nodes I would prefer to not manually prescribe to offset for each label.
For a higher order element the corresponding code would be
Step 1:
n1quadtri[x_, y_] := x (2 x - 1)
n2quadtri[x_, y_] := y (2 y - 1)
n3quadtri[x_, y_] := (1 - x - y) (2 (1 - x - y) - 1)
n4quadtri[x_, y_] := 4 x y
n5quadtri[x_, y_] := 4 y (1 - x - y)
n6quadtri[x_, y_] := 4 (1 - x - y) x
xqtar = 1; yqtar = 0;
xqtbr = 0; yqtbr = 1;
xqtcr = 0; yqtcr = 0;
xqtdr = 0.5; yqtdr = 0.5;
xqter = 0; yqter = 0.5;
xqtfr = 0.5; yqtfr = 0;
xqta = 1; yqta = 0;
xqtb = 0; yqtb = 1;
xqtc = 0; yqtc = 0;
xqtd = 0.75; yqtd = 0.75;
xqte = 0.25; yqte = 0.5;
xqtf = 0.5; yqtf = 0;
Step 2:
domain = Region[Triangle[{{0, 0}, {1, 0}, {0, 1}}]];
Step 3:
quadtri1 =
ParametricPlot[{
xqtar n1quadtri[x, y] + xqtbr n2quadtri[x, y] +
xqtcr n3quadtri[x, y] + xqtdr n4quadtri[x, y] +
xqter n5quadtri[x, y] + xqtfr n6quadtri[x, y],
yqtar n1quadtri[x, y] + yqtbr n2quadtri[x, y] +
yqtcr n3quadtri[x, y] + yqtdr n4quadtri[x, y] +
yqter n5quadtri[x, y] + yqtfr n6quadtri[x, y]}, {x,
y} \[Element] domain, Frame -> False, Axes -> False];
quadtri1points = {{xqtar, yqtar}, {xqtbr, yqtbr}, {xqtcr,
yqtcr}, {xqtdr, yqtdr}, {xqter, yqter}, {xqtfr, yqtfr}};
quadtri2 =
ParametricPlot[{
xqta n1quadtri[x, y] + xqtb n2quadtri[x, y] +
xqtc n3quadtri[x, y] + xqtd n4quadtri[x, y] +
xqte n5quadtri[x, y] + xqtf n6quadtri[x, y],
yqta n1quadtri[x, y] + yqtb n2quadtri[x, y] +
yqtc n3quadtri[x, y] + yqtd n4quadtri[x, y] +
yqte n5quadtri[x, y] + yqtf n6quadtri[x, y]}, {x, y} \[Element]
domain, Frame -> False, Axes -> False];
quadtri2points = {{xqta, yqta}, {xqtb, yqtb}, {xqtc, yqtc}, {xqtd,
yqtd}, {xqte, yqte}, {xqtf, yqtf}};
Step 4:
Labeled[Show[quadtri1,
ListPlot[quadtri1points, PlotStyle -> {Red, PointSize[Large]},
Frame -> False], Axes -> True, AxesOrigin -> {0, 0},
PlotRange -> All], {Style["\[Xi]", 18, Black, Bold],
Style["\[Eta]", 18, Black, Bold]}, {Bottom, Left}]
Labeled[Show[quadtri2,
ListPlot[quadtri2points, PlotStyle -> {Red, PointSize[Large]},
Frame -> False], Axes -> True, AxesOrigin -> {0, 0},
PlotRange -> All], {Style["x", 18, Black, Bold],
Style["y", 18, Black, Bold]}, {Bottom, Left}]
Which yields
Which would ideally be labelled as
Any help would be appreciated.
Axes
versus a 2-sidedFrame
--is there a reason for axes as opposed to a frame? And should the labels be placed within the axes/frame, or outside of the defined region? Which takes precedent? kglr provides a nice answer below which you can likely modify to sate your needs. $\endgroup$