Вы находитесь на странице: 1из 29

G

Graphic
Utilities

G1

Appendix G: GRAPHIC UTILITIES

TABLE OF CONTENTS
Page

G.1.
G.2.

G.3.

Introduction
Hex8 Element Plotting Module
G.2.1.
Usage . . . . . . . . .
G.2.2.
Source Code . . . . . . .
G.2.3.
Individual Element Example Plots
G.2.4.
Multiple Element Example Plots
Hex20 Element Plotting Module
G.3.1.
Usage . . . . . . . . .
G.3.2.
Source Code . . . . . . .
G.3.3.
Individual Element Example Plots

G2

. .
.
.
.

.
. .
.
. .

. .
.
. .
.

.
. .
.
. .

. .
.
. .
.

.
. .
.
. .

. .
.
. .
.

. . . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .

G3
G3
G4
G14
G14
G14
G15
G18
G28
G28

G.2

HEX8 ELEMENT PLOTTING MODULE

G.1. Introduction
This Appendix collects a set of application-independent graphic utilities organized as Mathematica
modules. By application independent is meant that these modules are reusable across different
FEM application programs that do not necessarily simulate structures.
G.2. Hex8 Element Plotting Module
The Mathematica module PlotHex8Elem produces plots of the 8-node hexahedron finite element
described in Chapter 11. The module aims to provide a comprehensive set of plotting options to
display an individual element of that particular configuration.
Although the module can display multiple elements, it is not recommended for showing a finite
element mesh because PlotHex8Elem focuses on local (intrinsic) element properties. As a matter
of fact, such multiple elements need not be connected in any way, as they would be in a mesh. That
lack of restrictions has some practical uses, for example to illustrate initial and final configurations
of the same element. Another module, called PlotHex8Mesh and described in Section ?, is more
suitable for plotting a hexahedral mesh.
PlotHex8Elem
Driver that generates plot
stream by interpreting
"plotwhat" commands,
and displays or saves
plot image

PlotHex8Faces

PlotHex8Lines

Draws Hex8 faces


as regular mesh of
color filled polygons
with edge lines

Draws lines (e.g.,


hexahedron edges)
joining two end points
of given location

PlotHex8Points

PlotHex8Options

PlotHex8Macro

Hex8CarInterp

Draws points at given


locations and places
labels nearby (point or
label may be omitted)

Injects plotting options


that affect downstream
colors, point size, line
thickness and labels,
into the plot stream.

Expands a macro
command keyword into
sequence of low-level
instructions

Returns x,y,z given


,, using iso-P
shape functions of
Hex8 element

Figure G.1. Organization of PlotHex8 graphics module.

The overall organization is diagrammed in Figure ?. Module PlotHex8Elem is actually a driver


that interprets an array of plot what commands, and calls subordinate modules PlotHex8Faces,
PlotHex8Lines, PlotHex8Points, PlotHex8Options, and PlotHex8Macro as appropriate
to construct the plot stream. Another subordinate module, Hex8CarInterp, is called by
PlotHex8Faces, PlotHex8Lines, and PlotHex8Points to map natural to Cartesian coordinates using the Hex8 shape functions. Once all instructions are processed, the plot image is created
using the built in Show function. The image is either output to the screen, or returned as a list,
according to input specifications.
In this Section the abbreviation pt denotes a printer point, which is a length dimension of
0.35146 mm = 0.013837 inches = (1/72.27) inches. This is a unit traditionally used in typography as well as (currently) in computer graphics. Typical dimensions specified in pt are line
thicknesses, point sizes and label font sizes.1
1

Do not confuse point which is a distinguished element location such as a nodal point (a corner in Hex8) or a Gauss

G3

Appendix G: GRAPHIC UTILITIES

G.2.1. Usage
The module may be invoked in either of two ways:
PlotHex8[xyzhex,plotwhat,plotspecs]
phex= PlotHex8[xyzhex,plotwhat,plotspecs]

(G.1)

The first form outputs a plot image to the screen. The second form displays no image but places the
plot object into phex as function return. A logical flag provided in argument plotspecs determines
the appropriate calling form, as described below.
The arguments are:
xyzhex

To plot an individual element: nodal coordinates stored node-by-node as a 83


matrix: { { x1,y1,z1 },{ x2,y2,z2 },{ x3,y3,z3 }, . . . { x8,y8,z8 } }.
To plot m > 1 elements: stack their nodal coordinate matrices in a m 8 3
three dimensional list: { xyzhex1,. . .,xyzhexm }. Elements stored in the list
may be totally independent of each other.

plotwhat

A list of commands specifying what is to be plotted. The list may include


commands of three types.
Macro commands. A character string that collectively represents a sequence
of lower level commands. For example: "faces" produces a plot of all
element faces and is equivalent to a list of six more detailed commands:
{ " ",-1 },{ " ",1 },{ "",-1 },{ "",1 },{ "",-1 },{ "",1 }. Available
macro commands are listed in Table ?.
Low-level commands. These specify only individual action, such as : plot a
point, plot a line, insert a label, etc. Low level commands are listed in Table ?.
Options commands. These are used to override default settings such as colors,
line thicknesses, point sizes and label styles. For example, by default points
are show as black disks of 6-pt diameter. To have them displayed in red with
4-pt diameter, say { "pcolor","red" } and { "psize",4 } before entering the
commands to draw those points. Option commands are listed in Table ?. The
last column of this Table gives the default settings.

plotspecs

A list containing the following items:


{ Nsub,boxrat,view,light,imgsiz,showbox,showxyz,plotsave }
which can be used to control the overall appearance of the plot. These items
are described in Table ?.

point, and pt, which is a length dimension.

G4

G.2

HEX8 ELEMENT PLOTTING MODULE

Table G.1. Macro Commands in plotwhat Argument of PlotHex8Elem

Command

What to plot

Equivalent to low-level command sequence

"corners"
or "nodes"

Corner points (element nodes) without


labels

{ 1 },{ 2 },{ 3 },{ 3 },{ 4 },{ 5 },{ 6 },{ 7 },{ 8 }

"diagonals"

Diagonal lines (from each corner to


opposite corner)

{ 1,7 },{ 2,8 },{ 3,5 },{ 4,6 }

"edges" or
"sides"

Edges as straight lines

{ 1,2 },{ 1,4 },{ 1,5 },{ 2,3 },{ 2,6 },{ 3,4 },
{ 3,7 },{ 4,8 },{ 5,6 },{ 5,8 },{ 6,7 },{ 7,8 }

"faces"

All faces using filled polygons, with


{ " ",-1 },{ " ",1 },{ "",-1 },
Nsub subdivisions along each direction. { "",1 },{ "",-1 },{ "",1 }.

"fcenters"

Face center points without labels

{ -1,0,0 },{ 1,0,0 },{ 0,-1,0 },


{ 0,1,0 },{ 0,0,-1 },{ 0,0,1 }

"gp111"

Gauss pt for 111 rule, labeled G1

{ { 0,0,0 },"G1" }

"gp222"

Gauss pts for 222 rule, labeled


G1 through
G8. (In the next column,
= 1/ 3)

{ { - ,- ,- },"G1" },{ { ,- ,- },"G2" },


{ { , ,- },"G3" },{ { - , ,- },"G4" },
{ { - ,- , },"G5" },{ { ,- , },"G6" },
{ { , , },"G7" },{ { - , , },"G8" }

"labcorners" Corner points (element nodes) with


or "labnodes" labels
"labfcent"

Face center points with face labels

{ 1,"1" },{ 2,"2" },{ 3,"3" },{ 4,"4" },


{ 5,"5" },{ 6,"6" },{ 7,"7" },{ 8,"8" }
{ { -1,0,0 },"C1485" },{ { 1,0,0 },"C2376" },
{ { 0,-1,0 },"C1265" },{ { 0,1,0 },"C3487" },
{ { 0,0,-1 },"C1234" },{ { 0,0,1 },"C5678" }

"labnaxes"
Natural axes labels {, , } placed
or "labhaxes" near tips. Axis tips are not plotted
as points.

{ "psize",0 },{ { ,0,0 }," " },


{ { 0,,0 },"" },{ { 0,0, },"" },
in which = 1.5 by default.

"medians"

Median lines (from each face center


to opposite face center)

{ -1,0,0 },{ 1,0,0 } },{ { 0,-1,0 },


{ 0,1,0 } },{ { 0,0,-1 },{ 0,0,1 }

"medsurf" or
"medplanes"

Median surfaces = 0, = 0,
and = 0

{ { " ",0 },{ "",0 },{ "",0 } }

"naxes" or
"haxes"

Natural axes {, , } without labels.


Tips usually stick outside element.

{ { -1,0,0 },{ ,0,0 } },{ { 0,-1,0 },


{ 0,,0 } },{ { 0,0,-1 },{ 0,0, } },
in which = 1.5 by default.

Axis-tip distances from faces may be adjusted with the { "tips", } option; see Table ?

G5

Appendix G: GRAPHIC UTILITIES

Table G.2. Low-level Commands in plotwhat Argument of PlotHex8Elem


Command

Format

What to plot

{n}

n: integer in range 18

Corner point n, without label

{ n,label }

n: integer in range 18; label: a


character string

Corner point n with label

{ n1,n2 }

n1,n2: integers in range 18

Line joining corners n1 and n2

{m}

m: integer of form 100*n1+n2, with


both n1,n2 integers in range 18.

Same effect as { n1,n2 }.

{ ,, }

,,: numeric values (real, integer


or fraction) of natural coordinates.
Values outside range [1, 1] are OK;
if so point will fall out of element.

Point at location { ,, }, without label

{ { ,, },label }

,,: as in previous case; label:


a character string

Point at location { ,, }, with label.


To suppress point plotting, preceed with
option command { "psize",0 }

{ { 1,1,1 },
{ 2,2,2 } }

{ 1,1,1 } and { 2,2,2 }: :


natural coordinates of two points

Line joining the two points

{ " ",c }

c: coordinate of surface =c

Plot surface =c within element

{ "",c }

c: coordinate of surface =c

Plot surface =c within element

{ "",c }

c: coordinate of surface =c

Plot surface =c within element

If c is outside the range [1, 1], the plotted plane is outside the element, but will be bounded
by the [1, 1] range of of the other two coordinates.

G6

G.2

HEX8 ELEMENT PLOTTING MODULE

Table G.3. Option Commands in plotwhat Argument of PlotHex8Elem


Command

Description

Defaults

{ "fcolor",color }

Set face color for subsequent face plots. Here color


is either a list { R,G,B } of 3 numbers, all in range
[0, 1], which defines a RGB specification, or one of
the following strings: "black", "red", "green",
or "blue". For example: { "fcolor","blue" }
and { "fcolor",{ 0,0,1 } } are equivalent

Mathematica default
for 3D graphics (these
defaulst may vary with
version).

{ "lcolor",color }

Set face color for subsequent line plots. Here color


is as described above.

Black

{ "pcolor",color }

Set face color for subsequent point plots. Here


color is as described above.

Black

{ "style",
{ fontfamily,
fontsize,fontslant } }

Set font style for subsequent labels. Here fontfam


is a string that defines the font family, e.g., "Times",
"Helvetica", or "Courier"; fontsize is a number
defining the font size in printer points; fontslant is
one of the strings "Plain", "Bold" or "Italic".
Strings for fontfamily and fontslant must be
capitalized as per Mathematica naming rules.

Font family: Times,


font size: 14 pt,
font slant: Plain

{ "psize",size }

Value psize specifies the size, in printer pt, of


subsequent point to be plotted. If psize is 0, those
points are not shown. This is handy to show labelsonly at specified locations, omitting points.

Point size: 6 pt

{ "ethick",thickness }

Value thickness specifies the thickness, in printer


points, of edges of subsequent face polygons.

Polygon edge
thickness: 1.25 pt

{ "lthick",thickness }

Value thickness specifies the thickness, in printer


points, of subsequent lines to be plotted; e.g.,
{ "lthick",1.5 }. By line it is meant those
produced by jpining two specified points; for example
edges, medians and diagonals.

Line thickness: 2 pt

{ "offset",
{ x, y, z } }

The list { x, y, z } defines the offset, in {x, y, z}


coordinate units, from a point (actually the point
center) to its respective label. This setting applies to
all subsequent labels until reset.

x= x= z=0.04.

{ "tips", }

Defines ends (tips) of natural axes, as well as labels


positions, drawn with macro commands "naxes"
and "labnaxes" Tips placed at = , = and
= , for axes {, , }, respectively.

= 1.5, whence
axes tips stick 50%
outside element.

Note: The label offset specification in terms of coordinate values is awkward, but unfortunately
Mathematica lacks the ability to specify an absolute distance between graphic objects in points.

G7

Appendix G: GRAPHIC UTILITIES

Table G.4. Items in plotspecs Argument of PlotHex8Elem


Item

Description

Recommended specifications

Nsub

A positive integer that specifies the subdivisions along


each direction when plotting faces or natural-coordinate
surfaces. For example, if Nsub=4, the face or surface will
be rendered with 42 = 16 filled polygons. Since element
faces or surfaces are (possibly warped) quadrilaterals,
polygons are also quadrilaterals.

2 to 4, but may be adjusted for


appearance. If face or surface
is highly warped, a larger Nsub
(e.g., 6 or 8) may be appropriate.

boxrat

A list of three positive numbers that specifies the {x, y, z}


side ratios of the plot bounding box. Set through
the Mathematica 3D graphics option BoxRatios ->
boxrat. If an empty list: { }, the module uses
BoxRatios -> Automatic to specify default settings.

The default { }, which triggers


BoxRatios -> Automatic, often works OK, but plots with high
aspect ratios may require fiddling
with 3 numbers.

view

A list of 3 numeric items that specifies the location in


{x, y, z} space from which the objects plotted are to
be viewed. Set through the Mathematica 3D graphics
option ViewPoint -> view.

Start with a reasonable guess, e.g.,


{ 1,1,1 }, but experimentation will
be usually needed.

light

A specification, usually stated in terms of one of the


built-in functions GrayLevel, Hue or RGBColor, which
sets a level of diffuse isotropic lighting of the plot object.
Set through the 3D graphics option AmbientLight ->
light. For other types of lighting, such as point light
sources, the Show statement within PlotHex8Elem has
to be modified; cf. Remark ?.

GrayLevel[0], but some experimentation may be required. Hue[0]


can also be a useful start. As h in
Hue[h] changes from 0 to 1, the
ambient light color ranges from
red, yellow, green, cyan, blue,
magenta, and back to red.

imgsiz

Width of the plot in printer points. Specified through the


graphics option ImageSize -> imgsiz

300, which is about 4 inches or 10


cm.

showbox

A logical flag. If True, the plot bounding box is drawn


via the 3D graphics option Boxed -> True

False

showxyz

A logical flag. If True, the labeled Cartesian axes are


drawn along the edges of the plot bounding box via the
3D graphics options Axes -> True and AxesLabel
->{ "x","y","z" }.

False

plotsave A logical flag. If True, do not display plot on


screen, but return the plot object as function value from
PlotHex8Elem; see invokation format in (?). Useful for
downstream combining plots from various sources.

G8

False, unless plot is to be merged


downstream with other plots.

G.2

HEX8 ELEMENT PLOTTING MODULE

PlotHex8Elem[xyzhex_,plotwhat_,plotspecs_]:=Module[{i,j,k,m,n,p,e,
ip,n1,n2,np,ne=1,what,w,whead,wlen,kw,w1,w2,w1head,w1len,w2head,w2len,
F,L,P,expMC,Nsub,boxrat,view,light,imgsiz,showbox,showxyz,plotsave,
boxdim,ps,black,red,blue,psizdef=6,ethidef=1.25,lthidef=2,tipsdef=1.5,
styledef={TextStyle->{FontFamily->"Times",FontSize->14,
FontWeight->"Plain"}},offsetdef={0.04,0.04,0.04},plotopt,
axespec=False,axeslab=" ",polyfill,polyedge,lines,points,labels,
optkey,key,dfun,xyzc=xyzhex,mulele,phex,modname="PlotHex8Elem:"},
optkey[key_]:=StringLength[key]>=4&&Length[StringPosition[
validoptkeys,StringTake[key,4]]]>0;
validoptkeys="ethi fcol pcol lcol lthi psiz styl offs tips";
polyfill=polyedge=lines=points=labels={};
plotopt={styledef,psizdef,ethidef,lthidef,offsetdef,tipsdef};
{Nsub,boxrat,view,light,imgsiz,showbox,showxyz,plotsave}=plotspecs;
If [showxyz, axespec=True; axeslab={"x","y","z"}];
{black,red,blue}={RGBColor[0,0,0],RGBColor[1,0,0],RGBColor[0,0,1]};
mulele=Length[Dimensions[xyzhex]]==3; If [mulele, ne=Length[xyzhex]];
np=Length[plotwhat]; If [np<=0,Return[]];
For [e=1,e<=ne,e++, For [ip=1,ip<=np,ip++, p=False; what=plotwhat[[ip]];
whead=Head[what]; wlen=Length[what]; If [mulele, xyzc=xyzhex[[e]]];
If [wlen==0,
If [whead==String,
{{F,L,P},expMC}=PlotHex8Macro[what,plotopt,plotspecs];
If [F>0, {polyfill,polyedge}=PlotHex8Faces[
xyzc,expMC,Nsub,polyfill,polyedge]; p=True];
If [L>0, lines=PlotHex8Lines[xyzc,expMC,L,lines]; p=True];
If [P>0, {points,labels}=PlotHex8Points[
xyzc,expMC,plotopt,points,labels]; p=True];
If [P<0, ps=plotopt[[2]]; plotopt[[2]]=0; {points,labels}=
PlotHex8Points[xyzc,expMC,plotopt,points,labels];
plotopt[[2]]=ps; p=True]];
If [whead==Integer, {points,labels}=PlotHex8Points[
xyzc,{{what}},plotopt,points,labels]; p=True];
];
If [wlen==1, {w1}=what; w1head=Head[w1]; w1len=Length[w1];
If [w1head==Integer,
If [w1>=1&&w1<=8, {points,labels}=PlotHex8Points[
xyzc,{w1},plotopt,points,labels]; p=True];
If [w1>=102&&w1<=807, n1=Floor[w1/100]; n2=w1-100*n1;
lines=PlotHex8Lines[xyzc,{{n1,n2}},1,lines]; p=True]];
If [whead==List&&wlen==3,
{points,labels}=PlotHex8Points[
xyzc,what,plotopt,points,labels]; p=True];
];
If [wlen==2, {w1,w2}=what; w1head=Head[w1]; w1len=Length[w1];
If [w1head==String,
If [optkey[w1],
{plotopt,polyfill,polyedge,lines,points,labels}=
PlotHex8Options[what,{plotopt,polyfill,polyedge,
lines,points,labels}]; p=True];
If [w1==" "||w1==""||w1=="",
{polyfill,polyedge}=PlotHex8Faces[xyzc,{what},
Nsub,polyfill,polyedge]; p=True]];
If [w1head==Integer, w2head=Head[w2];
If [w2head==Integer, lines=PlotHex8Lines[xyzc,{what},
Nsub,lines]; p=True];
If [w2head==String, {points,labels}=PlotHex8Points[
xyzc,{what},plotopt,points,labels]; p=True]];
If [w1head==List, w2head=Head[w2];
If [w2head==List, lines=PlotHex8Lines[xyzc,{what},
Nsub,lines]; p=True];
If [w2head==String, {points,labels}=PlotHex8Points[
xyzc,{what},plotopt,points,labels]; p=True]];
];

Figure G.2. Plot driver module PlotHex8Elem, Part 1.

G9

Appendix G: GRAPHIC UTILITIES


If [wlen==3,
If [whead==List, {points,labels}=PlotHex8Points[
xyzc,{what},plotopt,points,labels]; p=True];
]; If [!p, Print[modname," Illegal command ",what]];
]];
boxdim=Automatic; If [Length[boxrat]==3, boxdim=boxrat];
If [plotsave, phex=Show[Graphics3D[red],polyfill,
Graphics3D[AbsoluteThickness[ethidef]],polyedge,
Graphics3D[black],Graphics3D[AbsoluteThickness[lthidef]],
lines,Graphics3D[black],Graphics3D[AbsolutePointSize[psizdef]],
points,Graphics3D[black],labels,AmbientLight->light,
ViewPoint->view,Axes->axespec,AxesLabel->axeslab,
BoxRatios->boxdim,ImageSize->imgsiz,
PlotRange->All,Boxed->showbox,DisplayFunction->Identity];
ClearAll[xyzc,polyfill,polyedge,sides,points,labels];
Return[phex]];
dfun=$DisplayFunction; If [$VersionNumber>=6.0, dfun=Print];
Show[Graphics3D[red],polyfill,
Graphics3D[AbsoluteThickness[ethidef]],polyedge,
Graphics3D[black],Graphics3D[AbsoluteThickness[lthidef]],
lines,Graphics3D[black],Graphics3D[AbsolutePointSize[psizdef]],
points,Graphics3D[black],labels,AmbientLight->light,
ViewPoint->view,Axes->axespec,AxesLabel->axeslab,
BoxRatios->boxdim,ImageSize->imgsiz,
PlotRange->All,Boxed->showbox,DisplayFunction->dfun];
ClearAll[xyzc,polyfill,polyedge,sides,points,labels];
Return[]];

Figure G.3. Plot driver module PlotHex8Elem, Part 2.

PlotHex8Faces[xyzc_,facelist_,Nsub_,polyfinc_,polyeinc_]:=
Module[ {i,j,kf=Length[polyfinc],ke=Length[polyeinc],
n=Nsub,nf=Length[facelist],if,ic,cval,
am,ap,bm,bp,xyz1,xyz2,xyz3,xyz4,polyfill,polyedge},
If [n<=0||nf<=0, Return[polyfinc,polyeinc]];
polyfill=Join[polyfinc,Table[0,{n^2*nf}]];
polyedge=Join[polyeinc,Table[0,{n^2*nf}]];
For [if=1,if<=nf,if++, {c,cval}=facelist[[if]]; ic=c;
If [Head[c]==String, jc=StringPosition[" ",c];
If [jc=={},Continue[]]; {{ic,ic}}=jc ];
For [i=1,i<=n,i++, am=(2*i-n-2)/n; ap=(2*i-n)/n;
For [j=1,j<=n,j++, bm=(2*j-n-2)/n; bp=(2*j-n)/n;
1= 2= 3= 4=1=2=3=4=1=2=3=4=cval;
If [ic==1, 1=4=N[am]; 2=3=N[ap];
1=2=N[bm]; 3=4=N[bp]];
If [ic==2, 1=4=N[am]; 2=3=N[ap];
1= 2=N[bm]; 3= 4=N[bp]];
If [ic==3, 1= 4=N[am]; 2= 3=N[ap];
1=2=N[bm]; 3=4=N[bp]];
xyz1=Hex8CartInterp[xyzc,{ 1,1,1}];
xyz2=Hex8CartInterp[xyzc,{ 2,2,2}];
xyz3=Hex8CartInterp[xyzc,{ 3,3,3}];
xyz4=Hex8CartInterp[xyzc,{ 4,4,4}];
polyfill[[++kf]]=Graphics3D[Polygon[
{xyz1,xyz2,xyz3,xyz4}]];
polyedge[[++ke]]=Graphics3D[Line[
{xyz1,xyz2,xyz3,xyz4,xyz1}]];
]]];
Return[{polyfill,polyedge}]];

Figure G.4. Module PlotHex8Faces that plots hexahedron faces as well as


constamt-natural-coordinate surfaces.

G10

G.2

HEX8 ELEMENT PLOTTING MODULE

PlotHex8Lines[xyzc_,linelist_,Nsub_,linesinc_]:=Module[
{i,k,nl=Length[linelist],lk,nn, 1, 2,d , beg, end,
xyz1,xyz2,nbeg,nend,n1,n2,lindef,node ,lines=linesinc},
node ={{-1,-1,-1},{1,-1,-1},{1,1,-1},{-1,1,-1},
{-1,-1,1}, {1,-1,1}, {1,1,1}, {-1,1,1}};
For [k=1,k<=nl,k++, lk=linelist[[k]]; nbeg=nend=Null;
If [Length[lk]==2,{nbeg,nend}=lk]; lindef=False;
If [Length[nbeg]==3&&Length[nend]==3,
beg=nbeg; end=nend; lindef=True];
If [Head[nbeg]==Integer&&Head[nend]==Integer,
n1=Min[nbeg,nend]; n2=Max[nbeg,nend];
If [n1>=1&&n1<=20&&n2>=1&&n2<=20, lindef=True;
beg=node [[n1]]; end=node [[n2]];
]];
If [!lindef||Nsub<=0, Return[lines]];
2= beg; d =( end- beg)/Nsub;
For [i=1,i<=Nsub,i++, 1= 2; 2= 1+d ;
xyz1=Hex8CartInterp[xyzc, 1];
xyz2=Hex8CartInterp[xyzc, 2];
AppendTo[lines,Graphics3D[Line[{xyz1,xyz2}]]]];
];
Return[lines]];

Figure G.5. Module PlotHex8Lines that plots lines joining two specified points; for
example hexahedron edges.

PlotHex8Points[xyzc_,pointlist_,plotopt_,pointsinc_,labelsinc_]:=
Module[{ip,np=Length[pointlist],k,pk,pklen,pdef,plab,p ,xyzp,
pdeflen,style,psize,ethik,lthik,offset,points=pointsinc,
labels=labelsinc}, {style,psize,ethik,lthik,offset}=plotopt;
For [k=1,k<=np,k++, pk=pointlist[[k]]; pklen=Length[pk];
If [pklen>3, Continue[]]; pdef=plab=p =Null;
If [pklen==1, {pdef}=pk]; If [pklen==2, {pdef,plab}=pk];
If [pklen==0||pklen==3, pdef=pk]; pdeflen=Length[pdef];
If [pdeflen==0, p=pdef]; If [pdeflen==3, p =pdef];
If [Head[p]==Integer, If[p<1||p>8,Continue[]];
xyzp=xyzc[[p]]];
If [Head[p ]==List, xyzp=Hex8CartInterp[xyzc,p ]];
If [Head[plab]==String, AppendTo[labels,
Graphics3D[Text[plab,xyzp+offset,style]]]];
If [psize>0,
AppendTo[points,Graphics3D[Point[xyzp]]]];
];
Return[{points,labels}]];

Figure G.6. Module PlotHex8Lines that plots specified points (for example, nodes), and
optionally writes labels nearby.

Hex8CartInterp[xyzhex_, _]:=Module[{Ne, v,v,v},


Ne[{ v_,v_,v_}]:=
{(1- v)*(1-v)*(1-v),(1+ v)*(1-v)*(1-v),
(1+ v)*(1+v)*(1-v),(1- v)*(1+v)*(1-v),
(1- v)*(1-v)*(1+v),(1+ v)*(1-v)*(1+v),
(1+ v)*(1+v)*(1+v),(1- v)*(1+v)*(1+v)}/8;
Return[Simplify[Ne[ ].xyzhex]]];

Figure G.7. Module Hex8CartInterp that returns {x, y, z} of a point, given its natural
(hexahedral) coordinates.

G11

Appendix G: GRAPHIC UTILITIES


PlotHex8Options[opt_,graphicsinc_]:=Module[{w1,w2,key14,key24,
w2head,w2len,R,G,B,color,style,psize,ethik,lthik,offset,tips,
plotopt,polyfill,polyedge,lines,points,labels},
{plotopt,polyfill,polyedge,lines,points,labels}=graphicsinc;
{style,psize,ethik,lthik,offset,tips}=plotopt;
{w1,w2}=opt; w2head=Head[w2]; w2len=Length[w2];
key14=StringTake[w1,4]; key24=StringTake[w1,{2,4}];
If [key24=="col", R=G=B=0; color=False;
If [w2head==String,
If [w2=="black", color=True];
If [w2=="red",
color=True; R=1];
If [w2=="green", color=True; G=1];
If [w2=="blue", color=True; B=1]];
If [w2head==List&&w2len==3, color=True; {R,G,B}=w2];
If [key14=="pcol"&&color,
AppendTo[points,Graphics3D[RGBColor[R,G,B]]]];
If [key14=="lcol"&&color,
AppendTo[lines,Graphics3D[RGBColor[R,G,B]]]];
If [key14=="fcol"&&color,
AppendTo[polyfill,Graphics3D[RGBColor[R,G,B]]]]];
If [key14=="psiz", psize=6;
If [w2head==Integer||w2head==Real, psize=w2];
AppendTo[points,Graphics3D[AbsolutePointSize[psize]]]];
If [key14=="ethi", ethik=1.25;
If [w2head==Integer||w2head==Real, ethik=w2];
AppendTo[polyedge,Graphics3D[AbsoluteThickness[ethik]]]];
If [key14=="lthi", lthik=2;
If [w2head==Integer||w2head==Real, lthik=w2];
AppendTo[lines,Graphics3D[AbsoluteThickness[lthik]]]];
If [key14=="tips", tips=1.5;
If [w2head==Integer||w2head==Real, tips=w2]];
If [key14=="styl",
If [w2len==3, style={TextStyle->{FontFamily->w2[[1]],
FontSize->w2[[2]],FontWeight->w2[[3]]}}]];
If [key14=="offs", offset={0.04,0.04,0.04};
If [w2len==3, offset=w2]];
plotopt={style,psize,ethik,lthik,offset,tips};
Return[{plotopt,polyfill,polyedge,lines,points,labels}]];

Figure G.8. Module PlotHex8Options that injects non default options in the plot command stream.

G12

G.2

HEX8 ELEMENT PLOTTING MODULE

PlotHex8Macro[keyw_,plotopt_,plotspecs_]:=Module[{i,node ,
t=plotopt[[6]],Nsub=plotspecs[[1]],FLP={0,0,0},
keylen=StringLength[keyw],kw=Null},
If [keylen<5, Return[{FLP,Null}]]; kw=StringTake[keyw,5];
node ={{-1,-1,-1},{1,-1,-1},{1,1,-1},{-1,1,-1},
{-1,-1,1}, {1,-1,1}, {1,1,1}, {-1,1,1}};
If [kw=="faces", FLP[[1]]=1; Return[{FLP,
{{" ",-1},{" ",1},{"",-1},{"",1},{"",-1},{"",1}}}]];
If [kw=="medsu"||kw=="medpl", FLP[[1]]=1; Return[{FLP,
{{" ",0},{"",0},{"",0}}}]];
If [kw=="edges"||kw=="sides", FLP[[2]]=1; Return[{FLP,
{{1,2},{1,4},{1,5},{2,3},{2,6},{3,4},
{3,7},{4,8},{5,6},{5,8},{6,7},{7,8}} }]];
If [kw=="diago", FLP[[2]]=Nsub; Return[{FLP,
{{1,7},{2,8},{3,5},{4,6}}}]];
If [kw=="naxes"||kw=="haxes", FLP[[2]]=1; Return[{FLP,
{{{-1,0,0},{t,0,0}},{{0,-1,0},{0,t,0}},{{0,0,-1},{0,0,t}}}}]];
If [kw=="media", FLP[[2]]=1; Return[{FLP,{{{-1,0,0},{1,0,0}},
{{0,-1,0},{0,1,0}},{{0,0,-1},{0,0,1}}}}]];
If [kw=="corne"||kw=="nodes", FLP[[3]]=1; Return[{FLP,
Table[{i},{i,8}]}]];
If [kw=="labco"||kw=="labno", FLP[[3]]=1; Return[{FLP,
Table[{i,ToString[i]},{i,8}]}]];
If [kw=="fcent", FLP[[3]]=1; Return[{FLP,
{{-1,0,0},{1,0,0},{0,-1,0},{0,1,0},{0,0,-1},{0,0,1}}}]];
If [kw=="labfc", FLP[[3]]=1; ; Return[{FLP,
{{{-1,0,0},"C1485"},{{1,0,0}, "C2376"},{{0,-1,0},"C1265"},
{{ 0,1,0},"C3487"},{{0,0,-1},"C1234"},{{0,0,1}, "C5678"}}}]];
If [kw=="labna"||kw=="labha", FLP[[3]]=-1; Return[{FLP,
{{{t,0,0}," "},{{0,t,0},""},{{0,0,t},""}}}]];
If [kw=="gp111", FLP[[3]]=1; Return[{FLP,{{{0,0,0},"G1"}}}]];
If [kw=="gp222", FLP[[3]]=1; Return[{FLP,
Table[{N[node [[i]]/Sqrt[3]],"G"<>ToString[i]},{i,8}]}]];
Return[{FLP,Null}]];

Figure G.9. Module PlotHex8Macro that receives a macro command keyword and emits a stream of
equivalent low-level commands.

G13

Appendix G: GRAPHIC UTILITIES

G.2.2. Source Code


A complete listing of PlotHex8 and its subordinate modules is given in Figures ? through ?.
Because of its length, the driver module listing is split into Figures ? and ?. The module notebook
can be downloaded from the Index of Appendix G.
Remark G.1. Implementation Considerations. Some plot options and details are wired in the module. Those

could be externally controlled with additional arguments in the plotspecs argument, but it would be just as
easy (in fact, faster) to go in and change the source code. For example, to pass from the AmbientLight diffuseisotropic lighting to light point sources it would be necessary to modify the Show command options, which is relatively easy. Note that the second Show statement contains a specification, namely, DisplayFunction->dfun,
that is Mathematica version dependent; it was changed in version 6.
Remark G.2. Line Plotting Logic. PlotHex8Elem draws the line joining two specified points as a straight

line in the Cartesian (physical) space if and only if it knows that to be the case. That happens for edges and
medians since mapping from {, , } to {x, y, z} is linear along lines where two hexahedral coordinates are
constant. Aside from that PlotHex8Elem assumes a curved line, and draws it in piecewise linear manner with
Nsub segments. To illustrate, observe that the diagonals displayed in Figure ?(e) are curved. For example,
the diagonal joining corner 1 to the opposite corner 7 has the equation = = in natural (hexahedral)
coordinates; plugging into the iso-P map gives a quadratic parametric form in {x, y, z}.

G.2.3. Individual Element Example Plots


Figure ? shows six sample plots of an individual hexahedron. Its geometry is defined by the node
(corner) coordinate matrix
xyzhex=

{ { 0,0,0 },
{ 0,0,0 }*c,

{ 2,0,0 },
{ 2,0,0 }*c,

{ 2,1,0 },
{ 0,1,0 },
{ 2,1,0 }*c, { 0,1,0 }*c };

(G.2)

in which c is a parameter. This hexahedron has a 21 plane rectangular faces at z = 0 and at z = c.


By setting c=0.4 to 0.4 the upper face is shrunk so the element resembles a truncated pyramid.
The plots of Figure ? are produced by the script listed in Figure ?. Salient features are briefly
described in the figure legend. They are chosen to illustrate some commonly used options.
G.2.4. Multiple Element Example Plots
Figure ? shows two sample plots that comprise multiple elements. That of Figure ?(a) shows 7
configurations of a hexahedron that is rigidly rotated about the z axis by angular increments of
30 , which are applied 6 times for a final total rotation of 180 . The plot is produced by the script
listed in Figure ?. The node coordinates of the 7 configurations are stacked into a 7 8 3 list
called xyzhex supplied as first argument. The following plots specifications are chosen: yields a
poorly scaled plot), view={ 0,6,1.5 }, imgsiz=576, light=GrayLevel[1] (so ambient light is
white), showbox=False, showxyz=True (for this plot type it is convenient to display axes), and
plotsave=False. Only faces and edges are drawn; more features would clutter the display.
The right plot in Figure ?(b) shows three configurations of a element undergoing large translations
and visible warping deformations. In the initial configuration (lower one in plot) the hexahedron
is actually a rectanguar box. This is moved rigidy in the z direction while the element is warped.
The plot is produced by the script listed in Figure ?. In this case the number of face subdivisions
is boosted to Nsub=6 to help in visualizing highly warped faces.
G14

G.3
(a)
6

HEX20 ELEMENT PLOTTING MODULE

(b)

(c)

2
3

(d)

(e)
6

(f)
5

8
7
G5 G8
G6
G7

1.5

0.5

2
0.4

0.3

G1
1

0.2

G4

G2

G3
2

0.1
0

0
0.25

0.5

0.75
1

Figure G.10. Sample plots of an individual Hex8 element, with Nsub=4, boxrat={ 1,1,1 }, view={ 3,2,1.5 },
and imgsiz=300 chosen for all: (a) shows faces, edges and labeled corners; (b) same as (a) except for white
lighting set via light=GrayLevel[1] and corner labels are omitted; (c) shows median faces and labeled natural
axes , , (axis labels slightly moved with Illustrator for better view); (d) shows four natural coordinate surfaces
= c, c = 1, 1/3, 1/3, 1 plus the labeled axis; (e) shows green-colored diagonals (curved because element
has variable metric) and red-colored labeled sample points of the 2 2 2 Gauss rule note that Gauss point fall
on the diagonals; (f) shows all lines (edges and face polygon edges) plotted in black with same thickness of 2.5
pt, ambient light set to yellow via light=Hue[0.2], and labeled {x, y, z} axes drawn along plotting box edges.

xyzhex={{0,0,0}, {2,0,0}, {2,1,0}, {0,1,0},


{0,0,1}*c,{2,0,1}*c,{2,1,1}*c,{0,1,1}*c}/.c->.4;
etaaxis={{0,-1,0},{0,1.5,0}};
Nsub=4; boxrat={1,1,1}; view={3,2,1.5}; showbox=False; imgsiz=300;
light=GrayLevel[0]; showbox=False; showxyz=False; plotsave=False;
plotsp={Nsub,boxrat,view,light,imgsiz,showbox,showxyz,plotsave};
plotspwhite={Nsub,boxrat,view,GrayLevel[1],imgsiz,showbox,showxyz,plotsave};
plotspaxes={Nsub,boxrat,view,Hue[.15],imgsiz,showbox,True,plotsave};
PlotHex8Elem[xyzhex,{"faces","edges","labcorners"},plotsp];
PlotHex8Elem[xyzhex,{"faces","edges","corners"},plotspwhite];
PlotHex8Elem[xyzhex,{"medsurf","edges","naxes","labnaxes"},plotsp];
PlotHex8Elem[xyzhex,{"edges","corners",etaaxis,{"offset",{0.0,0.05,0.0}},
{"psize",0},{{0,1.5,0},""},{"",-1},{"",-1/3},{"",1/3},{"",1}},plotsp];
PlotHex8Elem[xyzhex,{"edges","labcorners",{"lcolor","green"},"diagonals",
{"pcolor","red"},"gp222"},plotsp];
PlotHex8Elem[xyzhex,{{"fcolor","black"},{"ethick",2.5},"faces",
{"lthick",2.5},"edges"},plotspaxes];

Figure G.11. Script to produce the individual element plots of Figure ?.

G15

Appendix G: GRAPHIC UTILITIES

(a)

(b)

y
0

0.5
1
1.5
2

-2
0

4
6
0.1

z
0.075

0.05 z
0.025
0
0
5

-5

4.5
5

x
5.5

Figure G.12. Sample plots that contain multiple Hex8 elements.


RotateHex8[xyzhex_,_]:=Module[{c=Cos[],s=Sin[],
xn,yn,zn,xyzrot=xyzhex},
For [n=1,n<=8,n++,{xn,yn,zn}=xyzrot[[n]];
xyzrot[[n]]={xn*c-yn*s,xn*s+yn*c,zn}];
Return[xyzrot]];
xyzhex1={{a,0,0},{2+a,0,0},{2+a,c,0},{a,c,0},{a,0,b}*f,
{2+a,0,b}*f,{2+a,c,b}*f,{a,c,b}*f}/.{a->4,c->2,b->1/4,f->.4};
xyzhex2=RotateHex8[xyzhex1, Pi/6];
xyzhex3=RotateHex8[xyzhex1, Pi/3];
xyzhex4=RotateHex8[xyzhex1, Pi/2];
xyzhex5=RotateHex8[xyzhex1,2*Pi/3];
xyzhex6=RotateHex8[xyzhex1,5*Pi/6];
xyzhex7=RotateHex8[xyzhex1, Pi];
xyzhex={xyzhex1,xyzhex2,xyzhex3,xyzhex4,xyzhex5,xyzhex6,xyzhex7};
Nsub=3; boxrat={1,1,1/3}; view={0,6,1.5}; showbox=False; imgsiz=576;
light=GrayLevel[1]; showbox=False; showxyz=True; plotsave=False;
plotsp={Nsub,boxrat,view,light,imgsiz,showbox,showxyz,plotsave};
PlotHex8Elem[xyzhex,{{"ethi",1.5},"faces","edges"},plotsp];

Figure G.13. Script to produce the multiple-element plot of Figure ?(a).


WarpHex8[xyzhex_,s_,h_]:=Module[{warp,xyzwrp=xyzhex},
warp={1,-1,1,-1,1,-1,1,-1};
For [n=1,n<=8,n++,{xn,yn,zn}=xyzwrp[[n]];
xyzwrp[[n]]={xn,yn,zn+s*warp[[n]]+h}];
Return[xyzwrp]];
xyzhex1={{a,0,0},{2+a,0,0},{2+a,c,0},{a,c,0},{a,0,b}*f,
{2+a,0,b}*f,{2+a,c,b}*f,{a,c,b}*f}/.{a->4,c->2,b->1/2,f->1};
xyzhex2=WarpHex8[xyzhex1, .3,2];
xyzhex3=WarpHex8[xyzhex1, .6,4];
xyzhex={xyzhex1,xyzhex2,xyzhex3};
Nsub=6; boxrat={1,1,1}; view={1,2,1}; showbox=False; imgsiz=400;
light=GrayLevel[.2]; showbox=False; showxyz=True; plotsave=False;
plotsp={Nsub,boxrat,view,light,imgsiz,showbox,showxyz,plotsave};
PlotHex8Elem[xyzhex,{"faces","edges"},plotsp];

Figure G.14. Script to produce the multiple-element plot of Figure ?(b).

G16

G.3

HEX20 ELEMENT PLOTTING MODULE

G.3. Hex20 Element Plotting Module


The Mathematica module PlotHex20Elem produces plots of the 20-node hexahedron finite element
described in Chapter 11. The module aims to provide a comprehensive set of plotting options to
display an individual element of that particular configuration.
Although the module can display multiple elements, it is not recommended for showing a finite
element mesh because PlotHex20Elem focuses on local (intrinsic) element properties. As a matter
of fact, such multiple elements need not be connected in any way, as they would be in a mesh. That
lack of restrictions has some practical uses, for example to illustrate initial and final configurations
of the same element. Another module, called PlotHex20Mesh and described in Section ?, is more
suitable for plotting a hexahedral mesh.

PlotHex20Elem
Driver that generates plot
stream by interpreting
"plotwhat" commands,
and displays or saves
plot image

PlotHex20Faces

PlotHex20Lines

PlotHex20Points

PlotHex20Options

PlotHex20Macro

Hex20CarInterp

Draws Hex8 faces


as regular mesh of
color filled polygons
with edge lines

Draws lines (e.g.,


hexahedron edges)
joining two end points
of given location

Draws points at given


locations and places
labels nearby (point or
label may be omitted)

Injects plotting options


that affect downstream
colors, point size, line
thickness and labels,
into the plot stream.

Expands a macro
command keyword into
sequence of low-level
instructions

Returns x,y,z given


,, using iso-P
shape functions of
Hex20 element

Figure G.15. Organization of PlotHex20 graphics module.

The overall organization is diagrammed in Figure ?. On comparing Figures ? and ?, it is plain the
organization mimics that of 8-node tetrahedron plotting module PlotHex8Elem, which is described
in ?. In fact over 95% of the code is identical. In addition PlotHex20Elem is invoked with the
same arguments, but has some additional plotting commands because of the presence of midnodes.
Module PlotHex20Elem is actually a driver that interprets an array of plot what commands, and calls subordinate modules PlotHex20Faces, PlotHex20Lines, PlotHex20Points,
PlotHex20Options, and PlotHex20Macro as appropriate to construct the plot stream. Another
subordinate module, Hex20CarInterp, is called by PlotHex20Faces, PlotHex20Lines, and
PlotHex20Points to map natural to Cartesian coordinates using the Hex20 shape functions.
Once all instructions are processed, the plot image is created using the built in Show function. The
image is either output to the screen, or returned as a list, according to input specifications.
As in the other Sections, the abbreviation pt denotes a printer point, which is a length dimension
of 0.35146 mm = 0.013837 inches = (1/72.27) inches.

G17

Appendix G: GRAPHIC UTILITIES

G.3.1. Usage
The module may be invoked in either of two ways:
PlotHex20[xyzhex,plotwhat,plotspecs]
phex= PlotHex20[xyzhex,plotwhat,plotspecs]

(G.3)

The first form outputs a plot image to the screen. The second form displays no image but places the
plot object into phex as function return. A logical flag provided in argument plotspecs determines
the appropriate calling form, as described below.
The arguments are:
xyzhex

To plot an individual element: nodal coordinates stored node-by-node as a 203


matrix: { { x1,y1,z1 },{ x2,y2,z2 },{ x3,y3,z3 }, . . . { x20,y20,z20 } }.
Corner nodes are 18 whereasa midside nodes (ofthen called simply
midnodes) are not necessarily collocated at the midpoints of the sides.
To plot m > 1 elements: stack their nodal coordinate matrices in a m 20 3
three dimensional list: { xyzhex1,. . .,xyzhexm }. Elements stored in the list
may be totally independent of each other.

plotwhat

A list of commands specifying what is to be plotted. The list may include


commands of three types.
Macro commands. A character string that collectively represents a sequence
of lower level commands. For example: "faces" produces a plot of all
element faces and is equivalent to a list of six more detailed commands:
{ " ",-1 },{ " ",1 },{ "",-1 },{ "",1 },{ "",-1 },{ "",1 }. Available
macro commands are listed in Table ?.
Low-level commands. These specify only individual action, such as : plot a
point, plot a line, insert a label, etc. Low level commands are listed in Table ?.
Options commands. These are used to override default settings such as colors,
line thicknesses, point sizes and label styles. For example, by default points
are show as black disks of 6-pt diameter. To have them displayed in red with
4-pt diameter, say { "pcolor","red" } and { "psize",4 } before entering the
commands to draw those points. Option commands are listed in Table ?. The
last column of this Table gives the default settings.

plotspecs

A list containing the following items:


{ Nsub,boxrat,view,light,imgsiz,showbox,showxyz,plotsave }
which can be used to control the overall appearance of the plot. These items
are described in Table ?.

G18

G.3

HEX20 ELEMENT PLOTTING MODULE

Table G.5. Macro Commands in plotwhat Argument of PlotHex20Elem

Command

What to plot

Equivalent to low-level command sequence

"corners"

Corner nodes without labels

{ 1 },{ 2 },{ 3 },{ 3 }, . . ., { 8 }

"midpoints"

Midpoint nodes without labels

{ 9 },{ 10 },{ 11 },{ 12 }, . . ., { 20 }

"nodes"

All node points without labels

{ 1 },{ 2 },{ 3 },{ 3 },{ 4 },. . .,{ 20 }

"diagonals"

Diagonal lines (from each corner to


opposite corner)

{ 1,7 },{ 2,8 },{ 3,5 },{ 4,6 }

"edges" or
"sides"

Edges (generally curved)

{ 1,2 },{ 1,4 },{ 1,5 },{ 2,3 },{ 2,6 },{ 3,4 },
{ 3,7 },{ 4,8 },{ 5,6 },{ 5,8 },{ 6,7 },{ 7,8 }

"faces"

All faces using filled polygons, with


{ " ",-1 },{ " ",1 },{ "",-1 },
Nsub subdivisions along each direction. { "",1 },{ "",-1 },{ "",1 }.

"fcenters"

Face center points without labels

{ -1,0,0 },{ 1,0,0 },{ 0,-1,0 },


{ 0,1,0 },{ 0,0,-1 },{ 0,0,1 }

"gp111"

Labeled Gauss pt for 111 rule,


labeled G1

{ { 0,0,0 },"G1" }

"gp222"

Labeled Gauss pts for 222 rule

See Table ?.

"gp333"

Labeled Gauss pts for 333 rule

See source code in Figure ?.

"labcor"

Labeled corner nodes

{ 1,"1" },{ 2,"2" }, . . . ,{ 8,"8" }

"labmid"

Labeled midnodes

{ 9,"9" },{ 10,"10" }, . . . ,{ 20,"20" }

"labnodes"

Labeled nodes

{ 1,"1" },{ 2,"2" }, . . . ,{ 20,"20" }

"labfcent"

Labeled face center points

See Table ?.

"labnaxes"
Natural axes labels {, , } placed
or "labhaxes" near tips. Axis tips are not plotted

See Table ?.

"medians"

Median lines (from each face center


to opposite face center)

{ -1,0,0 },{ 1,0,0 } },{ { 0,-1,0 },


{ 0,1,0 } },{ { 0,0,-1 },{ 0,0,1 }

"medsurf" or
"medplanes"

Median surfaces = 0, = 0,
and = 0

{ { " ",0 },{ "",0 },{ "",0 } }

"naxes" or
"haxes"

Natural axes {, , } without labels.


Tips usually stick outside element.

{ { -1,0,0 },{ ,0,0 } },{ { 0,-1,0 },


{ 0,,0 } },{ { 0,0,-1 },{ 0,0, } },
in which = 1.5 by default.

Axis-tip distances from faces may be adjusted with the { "tips", } option; see Table ?

G19

Appendix G: GRAPHIC UTILITIES

Table G.6. Low-level Commands in plotwhat Argument of PlotHex20Elem


Command

Format

What to plot

{n}

n: integer in range 18

Corner point n, without label

{ n,label }

n: integer in range 18; label: a


character string

Corner point n with label

{ n1,n2 }

n1,n2: integers in range 18

Line joining corners n1 and n2

{m}

m: integer of form 100*n1+n2, with


both n1,n2 integers in range 18.

Same effect as { n1,n2 }.

{ ,, }

,,: numeric values (real, integer


or fraction) of natural coordinates.
Values outside range [1, 1] are OK;
if so point will fall out of element.

Point at location { ,, }, without label

{ { ,, },label }

,,: as in previous case; label:


a character string

Point at location { ,, }, with label.


To suppress point plotting, preceed with
option command { "psize",0 }

{ { 1,1,1 },
{ 2,2,2 } }

{ 1,1,1 } and { 2,2,2 }: :


natural coordinates of two points

Line joining the two points

{ " ",c }

c: coordinate of surface =c

Plot surface =c within element

{ "",c }

c: coordinate of surface =c

Plot surface =c within element

{ "",c }

c: coordinate of surface =c

Plot surface =c within element

If c is outside the range [1, 1], the plotted plane is outside the element, but will be bounded
by the [1, 1] range of of the other two coordinates.

G20

G.3

HEX20 ELEMENT PLOTTING MODULE

Table G.7. Option Commands in plotwhat Argument of PlotHex20Elem


Command

Description

Defaults

{ "fcolor",color }

Set face color for subsequent face plots. Here color


is either a list { R,G,B } of 3 numbers, all in range
[0, 1], which defines a RGB specification, or one of
the following strings: "black", "red", "green",
or "blue". For example: { "fcolor","blue" }
and { "fcolor",{ 0,0,1 } } are equivalent

Mathematica default
for 3D graphics (these
defaulst may vary with
version).

{ "lcolor",color }

Set face color for subsequent line plots. Here color


is as described above.

Black

{ "pcolor",color }

Set face color for subsequent point plots. Here


color is as described above.

Black

{ "style",
{ fontfamily,
fontsize,fontslant } }

Set font style for subsequent labels. Here fontfam


is a string that defines the font family, e.g., "Times",
"Helvetica", or "Courier"; fontsize is a number
defining the font size in printer points; fontslant is
one of the strings "Plain", "Bold" or "Italic".
Strings for fontfamily and fontslant must be
capitalized as per Mathematica naming rules.

Font family: Times,


font size: 14 pt,
font slant: Plain

{ "psize",size }

Value psize specifies the size, in printer pt, of


subsequent point to be plotted. If psize is 0, those
points are not shown. This is handy to show labelsonly at specified locations, omitting points.

Point size: 6 pt

{ "ethick",thickness }

Value thickness specifies the thickness, in printer


points, of edges of subsequent face polygons.

Polygon edge
thickness: 1.25 pt

{ "lthick",thickness }

Value thickness specifies the thickness, in printer


points, of subsequent lines to be plotted; e.g.,
{ "lthick",1.5 }. By line it is meant those
produced by jpining two specified points; for example
edges, medians and diagonals.

Line thickness: 2 pt

{ "offset",
{ x, y, z } }

The list { x, y, z } defines the offset, in {x, y, z}


coordinate units, from a point (actually the point
center) to its respective label. This setting applies to
all subsequent labels until reset.

x= x= z=0.04.

{ "tips", }

Defines ends (tips) of natural axes, as well as labels


positions, drawn with macro commands "naxes"
and "labnaxes" (Table ?). Tips placed at = ,
= and = , for axes {, , }, respectively.

= 1.5, whence
axes tips stick 50%
outside element.

Note: The label offset specification in terms of coordinate values is awkward, but unfortunately
Mathematica lacks the ability to specify an absolute distance between graphic objects in points.

G21

Appendix G: GRAPHIC UTILITIES

Table G.8. Items in plotspecs Argument of PlotHex20Elem


Item

Description

Recommended specifications

Nsub

A positive integer that specifies the subdivisions when


plotting faces, natural-coordinate surfaces, or lines. For
example, if Nsub=4, the face or surface will be rendered
with 42 = 16 filled polygons. Since element faces or
surfaces are (possibly warped) quadrilaterals, polygons
are also quadrilaterals.

2 to 4, but may be adjusted for


appearance. If face or surface is
highly warped or doubly curved,
a larger Nsub (e.g., 6 or 8) may be
appropriate.

boxrat

A list of three positive numbers that specifies the {x, y, z}


side ratios of the plot bounding box. Set through
the Mathematica 3D graphics option BoxRatios ->
boxrat. If an empty list: { }, the module uses
BoxRatios -> Automatic to specify default settings.

The default { }, which triggers


BoxRatios -> Automatic, often works OK, but plots with high
aspect ratios may require fiddling
with 3 numbers.

view

A list of 3 numeric items that specifies the location in


{x, y, z} space from which the objects plotted are to
be viewed. Set through the Mathematica 3D graphics
option ViewPoint -> view.

Start with a reasonable guess, e.g.,


{ 1,1,1 }, but experimentation will
be usually needed.

light

A specification, usually stated in terms of one of the


built-in functions GrayLevel, Hue or RGBColor, which
sets a level of diffuse isotropic lighting of the plot object.
Set through the 3D graphics option AmbientLight ->
light. For other types of lighting, such as point light
sources, the Show statement within PlotHex20Elem
has to be modified; cf. Remark ?.

GrayLevel[0], but some experimentation may be required. Hue[0]


can also be a useful start. As h in
Hue[h] changes from 0 to 1, the
ambient light color ranges from
red, yellow, green, cyan, blue,
magenta, and back to red.

imgsiz

Width of the plot in printer points. Specified through the


graphics option ImageSize -> imgsiz

300, which is about 4 inches or 10


cm.

showbox

A logical flag. If True, the plot bounding box is drawn


via the 3D graphics option Boxed -> True

False

showxyz

A logical flag. If True, the labeled Cartesian axes are


drawn along the edges of the plot bounding box via the
3D graphics options Axes -> True and AxesLabel
->{ "x","y","z" }.

False

plotsave A logical flag. If True, do not display plot on


screen, but return the plot object as function value from
PlotHex20Elem; see invokation format in (?). Useful
for downstream combining plots from various sources.

G22

False, unless plot is to be merged


downstream with other plots.

G.3

HEX20 ELEMENT PLOTTING MODULE

PlotHex20Elem[xyzhex_,plotwhat_,plotspecs_]:=Module[{i,j,k,m,n,p,e,
ip,n1,n2,np,ne=1,what,w,whead,wlen,kw,w1,w2,w1head,w1len,w2head,w2len,
F,L,P,expMC,Nsub,boxrat,view,light,imgsiz,showbox,showxyz,plotsave,
boxdim,ps,black,red,blue,psizdef=6,ethidef=1.25,lthidef=2,tipsdef=1.5,
styledef={TextStyle->{FontFamily->"Times",FontSize->14,
FontWeight->"Plain"}},offsetdef={0.04,0.04,0.04},plotopt,
axespec=False,axeslab=" ",polyfill,polyedge,lines,points,labels,
optkey,key,dfun,xyzc=xyzhex,mulele,phex,modname="PlotHex20Elem:"},
optkey[key_]:=StringLength[key]>=4&&Length[StringPosition[
validoptkeys,StringTake[key,4]]]>0;
validoptkeys="ethi fcol pcol lcol lthi psiz styl offs tips";
polyfill=polyedge=lines=points=labels={};
plotopt={styledef,psizdef,ethidef,lthidef,offsetdef,tipsdef};
{Nsub,boxrat,view,light,imgsiz,showbox,showxyz,plotsave}=plotspecs;
If [showxyz, axespec=True; axeslab={"x","y","z"}];
{black,red,blue}={RGBColor[0,0,0],RGBColor[1,0,0],RGBColor[0,0,1]};
mulele=Length[Dimensions[xyzhex]]==3; If [mulele, ne=Length[xyzhex]];
np=Length[plotwhat]; If [np<=0,Return[]];
For [e=1,e<=ne,e++, For [ip=1,ip<=np,ip++, p=False; what=plotwhat[[ip]];
whead=Head[what]; wlen=Length[what]; If [mulele, xyzc=xyzhex[[e]]];
If [wlen==0,
If [whead==String,
{{F,L,P},expMC}=PlotHex20Macro[what,plotopt,plotspecs];
If [F>0, {polyfill,polyedge}=PlotHex20Faces[
xyzc,expMC,Nsub,polyfill,polyedge]; p=True];
If [L>0, lines=PlotHex20Lines[xyzc,expMC,Nsub,lines]; p=True];
If [P>0, {points,labels}=PlotHex20Points[
xyzc,expMC,plotopt,points,labels]; p=True];
If [P<0, ps=plotopt[[2]]; plotopt[[2]]=0; {points,labels}=
PlotHex20Points[xyzc,expMC,plotopt,points,labels];
plotopt[[2]]=ps; p=True]];
If [whead==Integer, {points,labels}=PlotHex20Points[
xyzc,{{what}},plotopt,points,labels]; p=True];
];
If [wlen==1, {w1}=what; w1head=Head[w1]; w1len=Length[w1];
If [w1head==Integer,
If [w1>=1&&w1<=8, {points,labels}=PlotHex20Points[
xyzc,{w1},plotopt,points,labels]; p=True];
If [w1>=102&&w1<=2019, n1=Floor[w1/100]; n2=w1-100*n1;
lines=PlotHex20Lines[xyzc,{{n1,n2}},Nsub,lines]; p=True]];
If [whead==List&&wlen==3,
{points,labels}=PlotHex20Points[
xyzc,what,plotopt,points,labels]; p=True];
];
If [wlen==2, {w1,w2}=what; w1head=Head[w1]; w1len=Length[w1];
If [w1head==String,
If [optkey[w1],
{plotopt,polyfill,polyedge,lines,points,labels}=
PlotHex20Options[what,{plotopt,polyfill,polyedge,
lines,points,labels}]; p=True];
If [w1==" "||w1==""||w1=="",
{polyfill,polyedge}=PlotHex20Faces[xyzc,{what},
Nsub,polyfill,polyedge]; p=True]];
If [w1head==Integer, w2head=Head[w2];
If [w2head==Integer, lines=PlotHex20Lines[xyzc,{what},
Nsub,lines]; p=True];
If [w2head==String, {points,labels}=PlotHex20Points[
xyzc,{what},plotopt,points,labels]; p=True]];
If [w1head==List, w2head=Head[w2];
If [w2head==List, lines=PlotHex20Lines[xyzc,{what},
Nsub,lines]; p=True];
If [w2head==String, {points,labels}=PlotHex20Points[
xyzc,{what},plotopt,points,labels]; p=True]];
];

Figure G.16. Plot driver module PlotHex20Elem, Part 1.

G23

Appendix G: GRAPHIC UTILITIES


If [wlen==3,
If [whead==List, {points,labels}=PlotHex20Points[
xyzc,{what},plotopt,points,labels]; p=True];
]; If [!p, Print[modname," Illegal command ",what]];
]];
boxdim=Automatic; If [Length[boxrat]==3, boxdim=boxrat];
If [plotsave, phex=Show[Graphics3D[red],polyfill,
Graphics3D[AbsoluteThickness[ethidef]],polyedge,
Graphics3D[black],Graphics3D[AbsoluteThickness[lthidef]],
lines,Graphics3D[black],Graphics3D[AbsolutePointSize[psizdef]],
points,Graphics3D[black],labels,AmbientLight->light,
ViewPoint->view,Axes->axespec,AxesLabel->axeslab,
BoxRatios->boxdim,ImageSize->imgsiz,
PlotRange->All,Boxed->showbox,DisplayFunction->Identity];
ClearAll[xyzc,polyfill,polyedge,sides,points,labels];
Return[phex]];
dfun=$DisplayFunction; If [$VersionNumber>=6.0, dfun=Print];
Show[Graphics3D[red],polyfill,
Graphics3D[AbsoluteThickness[ethidef]],polyedge,
Graphics3D[black],Graphics3D[AbsoluteThickness[lthidef]],
lines,Graphics3D[black],Graphics3D[AbsolutePointSize[psizdef]],
points,Graphics3D[black],labels,AmbientLight->light,
ViewPoint->view,Axes->axespec,AxesLabel->axeslab,
BoxRatios->boxdim,ImageSize->imgsiz,
PlotRange->All,Boxed->showbox,DisplayFunction->dfun];
ClearAll[xyzc,polyfill,polyedge,sides,points,labels];
Return[]];

Figure G.17. Plot driver module PlotHex20Elem, Part 2.


PlotHex20Faces[xyzc_,facelist_,Nsub_,polyfinc_,polyeinc_]:=
Module[ {i,j,kf=Length[polyfinc],ke=Length[polyeinc],
n=Nsub,nf=Length[facelist],if,ic,cval,
am,ap,bm,bp,xyz1,xyz2,xyz3,xyz4,polyfill,polyedge},
If [n<=0||nf<=0, Return[polyfinc,polyeinc]];
polyfill=Join[polyfinc,Table[0,{n^2*nf}]];
polyedge=Join[polyeinc,Table[0,{n^2*nf}]];
For [if=1,if<=nf,if++, {c,cval}=facelist[[if]]; ic=c;
If [Head[c]==String, jc=StringPosition[" ",c];
If [jc=={},Continue[]]; {{ic,ic}}=jc ];
For [i=1,i<=n,i++, am=(2*i-n-2)/n; ap=(2*i-n)/n;
For [j=1,j<=n,j++, bm=(2*j-n-2)/n; bp=(2*j-n)/n;
1= 2= 3= 4=1=2=3=4=1=2=3=4=cval;
If [ic==1, 1=4=N[am]; 2=3=N[ap];
1=2=N[bm]; 3=4=N[bp]];
If [ic==2, 1=4=N[am]; 2=3=N[ap];
1= 2=N[bm]; 3= 4=N[bp]];
If [ic==3, 1= 4=N[am]; 2= 3=N[ap];
1=2=N[bm]; 3=4=N[bp]];
xyz1=Hex20CartInterp[xyzc,{ 1,1,1}];
xyz2=Hex20CartInterp[xyzc,{ 2,2,2}];
xyz3=Hex20CartInterp[xyzc,{ 3,3,3}];
xyz4=Hex20CartInterp[xyzc,{ 4,4,4}];
polyfill[[++kf]]=Graphics3D[Polygon[
{xyz1,xyz2,xyz3,xyz4}]];
polyedge[[++ke]]=Graphics3D[Line[
{xyz1,xyz2,xyz3,xyz4,xyz1}]];
]]];
Return[{polyfill,polyedge}]];

Figure G.18. Module PlotHex20Faces that plots hexahedron faces as well


as constamt-natural-coordinate surfaces.

G24

G.3

HEX20 ELEMENT PLOTTING MODULE

PlotHex20Lines[xyzc_,linelist_,Nsub_,linesinc_]:=Module[
{i,k,nl=Length[linelist],lk,nn, 1, 2,d , beg, end,
xyz1,xyz2,nbeg,nend,n1,n2,lindef,nod ,lines=linesinc},
nod ={{-1,-1,-1},{1,-1,-1},{1,1,-1},{-1,1,-1},
{-1,-1,1}, {1,-1,1}, {1,1,1}, {-1,1,1},
{0,-1,-1}, {1,0,-1}, {0,1,-1},{-1,0,-1},
{-1,-1,0}, {1,-1,0}, {1,1,0}, {-1,1,0},
{0,-1,1}, {1,0,1}, {0,1,1}, {-1,0,1}};
For [k=1,k<=nl,k++, lk=linelist[[k]]; nbeg=nend=Null;
If [Length[lk]==2,{nbeg,nend}=lk]; lindef=False;
If [Length[nbeg]==3&&Length[nend]==3,
beg=nbeg; end=nend; lindef=True];
If [Head[nbeg]==Integer&&Head[nend]==Integer,
n1=Min[nbeg,nend]; n2=Max[nbeg,nend];
If [n1>=1&&n1<=20&&n2>=1&&n2<=20, lindef=True;
beg=nod [[n1]]; end=nod [[n2]];
]];
If [!lindef||Nsub<=0, Return[lines]];
2= beg; d =( end- beg)/Nsub;
For [i=1,i<=Nsub,i++, 1= 2; 2= 1+d ;
xyz1=Hex20CartInterp[xyzc, 1];
xyz2=Hex20CartInterp[xyzc, 2];
AppendTo[lines,Graphics3D[Line[{xyz1,xyz2}]]]];
];
Return[lines]];

Figure G.19. Module PlotHex20Lines that plots lines joining two specified points; for
example hexahedron edges.

PlotHex20Points[xyzc_,pointlist_,plotopt_,pointsinc_,labelsinc_]:=
Module[{ip,np=Length[pointlist],k,pk,pklen,pdef,plab,p,xyzp,
pdeflen,style,psize,ethik,lthik,offset,tips,points=pointsinc,
labels=labelsinc}, {style,psize,ethik,lthik,offset,tips}=plotopt;
For [k=1,k<=np,k++, pk=pointlist[[k]]; pklen=Length[pk];
If [pklen>3, Continue[]]; pdef=plab=p=Null;
If [pklen==1, {pdef}=pk]; If [pklen==2, {pdef,plab}=pk];
If [pklen==0||pklen==3, pdef=pk]; pdeflen=Length[pdef];
If [pdeflen==0, p=pdef]; If [pdeflen==3, p=pdef];
If [Head[p]==Integer, If[p<1||p>20,Continue[]];
xyzp=xyzc[[p]]];
If [Head[p]==List, xyzp=Hex20CartInterp[xyzc,p]];
If [Head[plab]==String, AppendTo[labels,
Graphics3D[Text[plab,xyzp+offset,style]]]];
If [psize>0,
AppendTo[points,Graphics3D[Point[xyzp]]]];
];
Return[{points,labels}]];

Figure G.20. Module PlotHex20Lines that plots specified points (for example, nodes), and
optionally writes labels nearby.

G25

Appendix G: GRAPHIC UTILITIES


Hex20CartInterp[xyzc_, _]:=Module[{Ne, v,v,v},
Ne[{ v_,v_,v_}]:=
{-(1- v)*(1-v)*(1-v)*(2+ v+v+v)/8,
-(1+ v)*(1-v)*(1-v)*(2- v+v+v)/8,
-(1+ v)*(1+v)*(1-v)*(2- v-v+v)/8,
-(1- v)*(1+v)*(1-v)*(2+ v-v+v)/8,
-(1- v)*(1-v)*(1+v)*(2+ v+v-v)/8,
-(1+ v)*(1-v)*(1+v)*(2- v+v-v)/8,
-(1+ v)*(1+v)*(1+v)*(2- v-v-v)/8,
-(1- v)*(1+v)*(1+v)*(2+ v-v-v)/8,
(1- v^2)*(1-v)*(1-v)/4,(1+ v)*(1-v^2)*(1-v)/4,
(1- v^2)*(1+v)*(1-v)/4,(1- v)*(1-v^2)*(1-v)/4,
(1- v)*(1-v)*(1-v^2)/4,(1+ v)*(1-v)*(1-v^2)/4,
(1+ v)*(1+v)*(1-v^2)/4,(1- v)*(1+v)*(1-v^2)/4,
(1- v^2)*(1-v)*(1+v)/4,(1+ v)*(1-v^2)*(1+v)/4,
(1- v^2)*(1+v)*(1+v)/4,(1- v)*(1-v^2)*(1+v)/4};
Return[Simplify[Ne[ ].xyzc]]];

Figure G.21. Module Hex20CartInterp that returns {x, y, z} of a point, given its natural
(hexahedral) coordinates.
PlotHex20Options[opt_,graphicsinc_]:=Module[{w1,w2,key14,key24,
w2head,w2len,R,G,B,color,style,psize,ethik,lthik,offset,tips,
plotopt,polyfill,polyedge,lines,points,labels},
{plotopt,polyfill,polyedge,lines,points,labels}=graphicsinc;
{style,psize,ethik,lthik,offset,tips}=plotopt;
{w1,w2}=opt; w2head=Head[w2]; w2len=Length[w2];
key14=StringTake[w1,4]; key24=StringTake[w1,{2,4}];
If [key24=="col", R=G=B=0; color=False;
If [w2head==String,
If [w2=="black", color=True];
If [w2=="red",
color=True; R=1];
If [w2=="green", color=True; G=1];
If [w2=="blue", color=True; B=1]];
If [w2head==List&&w2len==3, color=True; {R,G,B}=w2];
If [key14=="pcol"&&color,
AppendTo[points,Graphics3D[RGBColor[R,G,B]]]];
If [key14=="lcol"&&color,
AppendTo[lines,Graphics3D[RGBColor[R,G,B]]]];
If [key14=="fcol"&&color,
AppendTo[polyfill,Graphics3D[RGBColor[R,G,B]]]]];
If [key14=="psiz", psize=6;
If [w2head==Integer||w2head==Real, psize=w2];
AppendTo[points,Graphics3D[AbsolutePointSize[psize]]]];
If [key14=="ethi", ethik=1.25;
If [w2head==Integer||w2head==Real, ethik=w2];
AppendTo[polyedge,Graphics3D[AbsoluteThickness[ethik]]]];
If [key14=="lthi", lthik=2;
If [w2head==Integer||w2head==Real, lthik=w2];
AppendTo[lines,Graphics3D[AbsoluteThickness[lthik]]]];
If [key14=="tips", tips=1.5;
If [w2head==Integer||w2head==Real, tips=w2]];
If [key14=="styl",
If [w2len==3, style={TextStyle->{FontFamily->w2[[1]],
FontSize->w2[[2]],FontWeight->w2[[3]]}}]];
If [key14=="offs", offset={0.04,0.04,0.04};
If [w2len==3, offset=w2]];
plotopt={style,psize,ethik,lthik,offset,tips};
Return[{plotopt,polyfill,polyedge,lines,points,labels}]];

Figure G.22. Module PlotHex20Options that injects non default options in the plot command stream.

G26

G.3

HEX20 ELEMENT PLOTTING MODULE

PlotHex20Macro[keyw_,plotopt_,plotspecs_]:=Module[{i,nod ,
t=plotopt[[6]],Nsub=plotspecs[[1]],FLP={0,0,0},gp333,
g=Sqrt[3/5],keylen=StringLength[keyw],kw=Null},
If [keylen<5, Return[{FLP,Null}]]; kw=StringTake[keyw,5];
nod ={{-1,-1,-1},{1,-1,-1},{1,1,-1},{-1,1,-1},
{-1,-1,1}, {1,-1,1}, {1,1,1}, {-1,1,1},
{0,-1,-1}, {1,0,-1}, {0,1,-1},{-1,0,-1},
{-1,-1,0}, {1,-1,0}, {1,1,0}, {-1,1,0},
{0,-1,1}, {1,0,1}, {0,1,1}, {-1,0,1}};
gp333={{-g,-g,-g},{0,-g,-g},{g,-g,-g},{-g,0,-g},{0,0,-g},{g,0,-g},
{-g, g,-g},{0, g,-g},{g, g,-g},{-g,-g,0},{0,-g,0},{g,-g,0},
{-g, 0, 0},{0, 0, 0},{g, 0, 0},{-g, g,0},{0, g,0},{g, g,0},
{-g,-g, g},{0,-g, g},{g,-g, g},{-g, 0,g},{0, 0,g},{g, 0,g},
{-g, g, g},{0, g, g},{g, g, g}};
If [kw=="faces", FLP[[1]]=1; Return[{FLP,
{{" ",-1},{" ",1},{"",-1},{"",1},{"",-1},{"",1}}}]];
If [kw=="medsu"||kw=="medpl", FLP[[1]]=1; Return[{FLP,
{{" ",0},{"",0},{"",0}}}]];
If [kw=="edges"||kw=="sides", FLP[[2]]=1; Return[{FLP,
{{1,2},{1,4},{1,5},{2,3},{2,6},{3,4},
{3,7},{4,8},{5,6},{5,8},{6,7},{7,8}} }]];
If [kw=="diago", FLP[[2]]=Nsub; Return[{FLP,
{{1,7},{2,8},{3,5},{4,6}}}]];
If [kw=="naxes"||kw=="haxes", FLP[[2]]=1; Return[{FLP,
{{{-1,0,0},{t,0,0}},{{0,-1,0},{0,t,0}},{{0,0,-1},{0,0,t}}}}]];
If [kw=="media", FLP[[2]]=1; Return[{FLP,{{{-1,0,0},{1,0,0}},
{{0,-1,0},{0,1,0}},{{0,0,-1},{0,0,1}}}}]];
If [kw=="corne", FLP[[3]]=1; Return[{FLP,Table[{i},{i,8}]}]];
If [kw=="nodes", FLP[[3]]=1; Return[{FLP,Table[{i},{i,20}]}]];
If [kw=="midno", FLP[[3]]=1; Return[{FLP,Table[{i},{i,9,20}]}]];
If [kw=="labco", FLP[[3]]=1; Return[{FLP,Table[{i,ToString[i]},{i,8}]}]];
If [kw=="labno", FLP[[3]]=1; Return[{FLP,Table[{i,ToString[i]},{i,20}]}]];
If [kw=="labmi", FLP[[3]]=1; Return[{FLP,Table[{i,ToString[i]},{i,9,20}]}]];
If [kw=="fcent", FLP[[3]]=1; Return[{FLP,
{{-1,0,0},{1,0,0},{0,-1,0},{0,1,0},{0,0,-1},{0,0,1}}}]];
If [kw=="labfc", FLP[[3]]=1; ; Return[{FLP,
{{{-1,0,0},"C1485"},{{1,0,0}, "C2376"},{{0,-1,0},"C1265"},
{{ 0,1,0},"C3487"},{{0,0,-1},"C1234"},{{0,0,1}, "C5678"}}}]];
If [kw=="labna"||kw=="labha", FLP[[3]]=-1; Return[{FLP,
{{{t,0,0}," "},{{0,t,0},""},{{0,0,t},""}}}]];
If [kw=="gp111", FLP[[3]]=1; Return[{FLP,{{{0,0,0},"G1"}}}]];
If [kw=="gp222", FLP[[3]]=1; Return[{FLP,
Table[{N[nod [[i]]/Sqrt[3]],"G"<>ToString[i]},{i,8}]}]];
If [kw=="gp333", FLP[[3]]=1; Return[{FLP,
Table[{N[gp333[[i]]],"G"<>ToString[i]},{i,27}]}]];
Return[{FLP,Null}]];

Figure G.23. Module PlotHex20Macro that receives a macro command keyword and emits a stream of
equivalent low-level commands.

G27

Appendix G: GRAPHIC UTILITIES

G.3.2. Source Code


A complete listing of PlotHex20 and its subordinate modules is given in Figures ? through ?.
Because of its length, the driver module listing is split into Figures ? and ?. The module notebook
can be downloaded from the Index of Appendix G.
Remark G.3. Implementation Considerations. The same considerations expressed in Remark ? hold: if a

new plot feature needs to be inserted, the quickest way is to modify the source code.
Remark G.4. Line Plotting Logic. Unlike the Hex8 plotting module, any line that joins two points is assumed
to be curved, and is drawn with Nsub piecewise linear segments. The straight-line versus curved-line switch
logic described in Remark ? does not apply.

G.3.3. Individual Element Example Plots


Figure ? shows six sample plots of an individual 20-node hexahedron.The geometry is roughly
similar to the 8-node hexahedrom shown in Figure ?. One starts the same way by defining the
corner nodes as given in (?). This 8-node hexahedron has a 2 1 plane rectangular faces at z = 0
and at z = c. By setting c=0.4 to 0.4 the upper face is shrunk so the element resembles a truncated
pyramid. Then 12 midpoints are placed at the midpoints of the sides. Finally two midnodes: 11
and 12, are moved down and up by 1/8 along the z directions, recpectively, to produce some visibly
curved faces.
The plots of Figure ? are produced by the script listed in Figure ?. Salient features are briefly
described in the figure legend. They are chosen to illustrate some commonly used options.

G28

G.3
(a)

HEX20 ELEMENT PLOTTING MODULE

(b)

(c)

5 20
6 17
18 7 19 8
13

16

14
1

15
12 11

3
10

(d)

(e)

(f)
x

G5 G8
G6 G7

G1
G2

G3

1.5

0.5 0

0.4

G4

0.2
z

0
0.25
0.5
0.75
y

Figure G.24. Sample plots of an individual Hex20 element, with Nsub=8, boxrat={ 1,1,1 }, view={ 4,3,1.5 },
and imgsiz=300 chosen for all: (a) shows faces, edges and labeled corners; (b) same as (a) except for white
lighting set via light=GrayLevel[1] and node labels are omitted; (c) shows median faces and labeled natural
axes , , (axis labels slightly moved with Illustrator for better view); (d) shows four natural coordinate surfaces
= c, c = 1, 1/3, 1/3, 1 plus the labeled axis; (e) shows corner and midnodes with different colors (black
and blue, repectively, while point size is boosted to 8 pt), green-colored diagonals (curved because element has
variable metric) and red-colored labeled sample points of the 2 2 2 Gauss rule (note that Gauss point fall on
the diagonals); (f) shows all lines (edges and face polygon edges) plotted in black with same thickness of 1.25 pt,
ambient light set to yellow via light=Hue[0.2], and labeled {x, y, z} axes drawn along plotting box edges.
xyzcor={{0,0,0}, {2,0,0}, {2,1,0}, {0,1,0},
{0,0,1}*c,{2,0,1}*c,{2,1,1}*c,{0,1,1}*c}/.c->.4;
mij={{1,2},{2,3},{3,4},{4,1},{1,5},{2,6},{3,7},{4,8},{5,6},{6,7},{7,8},{8,5}};
xyzhex=Table[0,{20}];
For [n=1,n<=20,n++,
If [n<=8,xyzhex[[n]]=xyzcor[[n]]; Continue[]];
{i,j}=mij[[n-8]]; xyzhex[[n]]=(xyzcor[[i]]+xyzcor[[j]])/2;
]; xyzhex[[10,3]]=-1/8; xyzhex[[11,3]]=1/8;
Nsub=8; boxrat={1,1,1}; view={4,3,1.5}; showbox=False; imgsiz=300;
light=GrayLevel[0]; showbox=False; showxyz=False; plotsave=False;
plotsp={Nsub,boxrat,view,light,imgsiz,showbox,showxyz,plotsave};
muaxis={{0,0,-1},{0,0,1.5}};
plotspwhite={Nsub,boxrat,view,GrayLevel[1],imgsiz,showbox,showxyz,plotsave};
plotspaxes={Nsub,boxrat,view,Hue[.15],imgsiz,showbox,True,plotsave};
PlotHex20Elem[xyzhex,{"faces","edges","labnodes"},plotsp];
PlotHex20Elem[xyzhex,{"faces","edges","nodes"},plotspwhite];
PlotHex20Elem[xyzhex,{"medsurf","edges","naxes","labnaxes"},plotsp];
PlotHex20Elem[xyzhex,{"edges","nodes",muaxis,{"offset",{0.0,0.05,0.0}},
{"psize",0},{{0,0,1.5},""},{"",-1},{"",-1/3},{"",1/3},{"",1}},plotsp];
PlotHex20Elem[xyzhex,{"edges","nodes",{"lcolor","green"},"diagonals",
{"pcolor","red"},"gp222"},plotsp];
PlotHex20Elem[xyzhex,{{"fcolor","black"},{"ethick",1.25},"faces",
{"lthick",1.25},"edges"},plotspaxes];

Figure G.25. Script to produce the individual element plots of Figure ?.

G29

Вам также может понравиться