-
Notifications
You must be signed in to change notification settings - Fork 0
/
femtikz.sty
105 lines (94 loc) · 3.21 KB
/
femtikz.sty
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
\ProvidesPackage{femtikz}[2018/09/24 FEM-TikZ]
\RequirePackage{pgfplots}
%
% Draws one cell that is associated with a Lagrangian finite
% element together with its degrees of freedom and the
% corresponding indices.
%
% To model a numerical grid on a canvas, this function can be
% called multiple times to draw each individual cell.
%
% Must be called inside a tikzpicture environment.
%
% Parameters
% ----------
% #1 : float
% X-coordinate of the cell on the canvas.
% #2 : float
% Y-coordinate of the cell on the canvas.
% #3 : float
% Edge length of the cell.
% #4 : float
% Size/Radius of each node.
% #5 : int
% Order of the Lagrange element associated with this cell.
% #6 : array(string) or {}
% List of indices for each node on the cell.
% This array must be at least of a size that matches the number
% of nodes on this cell.
% Each index will be assigned in the same order as the deal.II
% library enumerates its degrees of freedom.
% (see: https://www.dealii.org/9.0.0/doxygen/deal.II/classFE__Q.html)
% If the argument is left empty, then no indices will be printed.
%
\newcommand*{\LagrangeCell}[6]{{
% -------------------
% auxillary variables
% -------------------
\def\X{#1}
\def\Y{#2}
\def\L{#3}
\def\r{#4}
\def\order{#5}
\def\nodes{#6}
\pgfmathsetmacro\ordermo{\order - 1}
\newcommand*{\parsenode}[1]{
\ifx\nodes\empty\else{\pgfmathparse{\nodes[##1]}\pgfmathresult}\fi
}
% ---------
% cell body
% ---------
\draw (\X,\Y) rectangle (\X+\L,\Y+\L);
% ------------
% vertex nodes
% ------------
\foreach \x in {0,1}
\foreach \y in {0,1}
\fill (\X + \x*\L, \Y + \y*\L) circle (\r);
% place indices individually
\node[anchor=south west] at (\X ,\Y ) {\parsenode{0}};
\node[anchor=south east] at (\X+\L,\Y ) {\parsenode{1}};
\node[anchor=north west] at (\X ,\Y+\L) {\parsenode{2}};
\node[anchor=north east] at (\X+\L,\Y+\L) {\parsenode{3}};
\ifnum \order>1
% ----------
% face nodes
% ----------
\begin{scope}
\clip (\X,\Y) rectangle (\X+\L,\Y+\L);
% west
\foreach \y in {1, ..., \ordermo}
\draw (\X - \r, \Y + \y*\L/\order - \r) rectangle (\X + \r, \Y + \y*\L/\order + \r)
node[pos=0.5, anchor=west] {\parsenode{3 + 0*\ordermo + \y}};
% east
\foreach \y in {1, ..., \ordermo}
\draw (\X+\L - \r, \Y + \y*\L/\order - \r) rectangle (\X+\L + \r, \Y + \y*\L/\order + \r)
node[pos=0.5, anchor=east] {\parsenode{3 + 1*\ordermo + \y}};
% south
\foreach \x in {1, ..., \ordermo}
\draw (\X + \x*\L/\order - \r, \Y - \r) rectangle (\X + \x*\L/\order + \r, \Y + \r)
node[pos=0.5, anchor=south] {\parsenode{3 + 2*\ordermo + \x}};
% north
\foreach \x in {1, ..., \ordermo}
\draw (\X + \x*\L/\order - \r, \Y+\L - \r) rectangle (\X + \x*\L/\order + \r, \Y+\L + \r)
node[pos=0.5, anchor=north] {\parsenode{3 + 3*\ordermo + \x}};
\end{scope}
% ------------
% volume nodes
% ------------
\foreach \x in {1, ..., \ordermo}
\foreach \y in {1, ..., \ordermo}
\draw (\X + \x*\L/\order, \Y + \y*\L/\order) circle (\r)
node[anchor=north] {\parsenode{3 + (3+\y)*\ordermo + \x}};
\fi
}}