Commit 15c12ba4 authored by Mark van Turnhout's avatar Mark van Turnhout
Browse files

documentation up to the cast, changed some screenshots

parent ba4f4702
......@@ -54,7 +54,7 @@
% graphics, figures, colour
\usepackage[pdftex]{graphicx}
\usepackage{color}
\usepackage{xcolor}
\definecolor{shadecolor}{rgb}{0.95,0.95,0.95}
\definecolor{listc}{rgb}{0.95,0.95,0.95}
\usepackage[labelfont = {bf},format = default,indention = -4\parindent]{caption,subfig}
......
documentation/abaqus_indenterSketch.png

88.6 KB | W: | H:

documentation/abaqus_indenterSketch.png

93.7 KB | W: | H:

documentation/abaqus_indenterSketch.png
documentation/abaqus_indenterSketch.png
documentation/abaqus_indenterSketch.png
documentation/abaqus_indenterSketch.png
  • 2-up
  • Swipe
  • Onion skin
......@@ -346,11 +346,11 @@ p.AnalyticRigidSurfRevolve(sketch=s1)
myModel.parts['indenter'].ReferencePoint(point=(0, 0, 0))
\end{lstlisting}
The sketch itself (lines \texttt{5--7}, figure \ref{indentersketch}) is axisymmetric and is rotated around it's symmetry axis (line \texttt{7}) when it is imported into the \texttt{part} (lines \texttt{8--9}, figure \ref{indenterpart}).
\begin{figure}[h!]
\begin{figure}[p!]\center
\subfloat[\label{indentersketch}]{%
\includegraphics[width=\linewidth]{abaqus_indenterSketch.png}}\\
\includegraphics[width=.9\linewidth]{abaqus_indenterSketch.png}}\\
\subfloat[\label{indenterpart}]{%
\includegraphics[width=\linewidth]{abaqus_indenterPart.png}}\\
\includegraphics[width=.9\linewidth]{abaqus_indenterPart.png}}\\
\caption{The indenter in Abaqus: \textbf{(a)} the 2D axisymmetric sketch; and \textbf{(b)} the rigid surface part. \label{abaqusindenter}}
\end{figure}
......@@ -423,9 +423,9 @@ a1 = myModel.rootAssembly
a1.translate(instanceList=('indenter-1', ), vector=(-4.811105, -5.031821, 0.552060))
\end{lstlisting}
The indenter is first rotated from \texttt{(0, 1, 0)} to \texttt{(0, 0, 1)} (line \texttt{6}). Next, \bas{buildFEM} does the book-keeping to rotate the indenter to the correct orientation from \texttt{(0, 0, 1)} (line \texttt{8}); and to translate it to the correct position for indentation (line \texttt{11}). Note that \bas{buildFEM} uses the rotation matrix stored in \texttt{Indenter\_tipNR.txt\index{Indenter\_tipNR.txt@\texttt{Indenter\_tipNR.txt}}} and the \gibbon-function \gib{rot2VecAngle} to calculate the \texttt{AxisDirection} and \texttt{angle} for the \texttt{rotate}-command for Abaqus (lines \texttt{6} and \texttt{8}).
The indenter is first rotated from \texttt{(0, 1, 0)} to \texttt{(0, 0, 1)} (line \texttt{6}). Next, \bas{buildFEM} does the book-keeping to rotate the indenter to the correct orientation from \texttt{(0, 0, 1)} (line \texttt{8}); and to translate it to the correct position for indentation (line \texttt{11}). Note that \bas{buildFEM} uses the rotation matrix stored in \texttt{Indenter\_tipNR.txt\index{Indenter\_tipNR.txt@\texttt{Indenter\_tipNR.txt}}} and the \gibbon-function \gib{rot2VecAngle} to calculate the \texttt{AxisDirection} and \texttt{angle} for the \texttt{rotate}-command for Abaqus (lines \texttt{6} and \texttt{8}).\\
The orientation of the assist-disc depends on the local curvature of the leg close to the indenter. The function \bas{buildFEM} looks for the point in the skin contour definition that is closest to the indenter tip start position. It then finds the closest point on the same contour, and the closest point on an adjacent contour. With these three points, \bas{buildFEM} estimates the local normal vector of the leg underneath the indenter. The assist-disc is therefore positioned 'parallel to the skin':
\noindent The orientation of the assist-disc depends on the local curvature of the leg close to the indenter. The function \bas{buildFEM} looks for the point in the skin contour definition that is closest to the indenter tip start position. It then finds the closest point on the same contour, and the closest point on an adjacent contour. With these three points, \bas{buildFEM} estimates the local normal vector of the leg underneath the indenter. The assist-disc is therefore positioned 'parallel to the skin':
\begin{lstlisting}[language=apython, numbers=none]
# instance and position assist disc
a1 = myModel.rootAssembly
......@@ -442,10 +442,118 @@ a1.translate(instanceList=('assistDisc-1', ), vector=(-4.811105, -5.031821, 0.55
The translation vector (last line) is the same as that for the indenter. However, because we sketched the assist-disc at \texttt{y = 1\,param.ri}, the centre of the disc will not end up at the tip of the indenter, but one indenter radius `higher' instead.\\
\noindent If you run the main \texttt{basil<basilid>\-\_job\-.py\index{basil<basilid>\_job.py@\texttt{basil<basilid>\_job.py}}}-script up until this point, Abaqus should display something like figure \eqref{abaqus_assemblyNoCast}.
\begin{figure}[h!]
\begin{figure}[p!]\center
\subfloat[\label{abaqus_assemblyNoCastDefault}]{%
\includegraphics[width=\linewidth]{abaqus_assemblyNoCastDefault.png}}\\
\includegraphics[width=.85\linewidth]{abaqus_assemblyNoCastDefault.png}}\\
\subfloat[\label{abaqus_assemblyNoCastRot}]{%
\includegraphics[width=\linewidth]{abaqus_assemblyNoCastRot.png}}
\caption{The model assembled in Abaqus. The yellow lines are the symmetry axis af the indenter and assist-disc (construction lines in the sketches), RP's are the reference points for the indenter and bone. With \textbf{(a)} the default view with the indenter hidden behind the leg; and \textbf{(b)} a rotated view. \label{abaqus_assemblyNoCast}}
\includegraphics[width=.85\linewidth]{abaqus_assemblyNoCastRot.png}}
\caption{The model assembled in Abaqus. The yellow lines are the symmetry axis of the indenter and assist-disc (construction lines in the sketches), RP's are the reference points for the indenter and bone. With \textbf{(a)} the default view with the indenter hidden behind the leg; and \textbf{(b)} a rotated view. \label{abaqus_assemblyNoCast}}
\end{figure}
\subsection{Define area on skin for indenter contact}
The next step is to `partition' the skin in order to define the contact area for the indenter. As mentioned above, this is the (only) purpose of the assist-disc:
\begin{lstlisting}[language=apython]
# partition skin for indenter contact region (surface)
a = myModel.rootAssembly
f1 = a.instances['leg-1'].faces
pickedFaces = f1.getSequenceFromMask(mask=('[#8 ]', ), )
# project indenter hat onto skin
e1 = a.instances['assistDisc-1'].edges
pickedEdges = e1.getSequenceFromMask(mask=('[#2 ]', ), )
a.PartitionFaceByProjectingEdges(faces=pickedFaces, edges=pickedEdges, extendEdges=False)
# create skinContactIn surface
s1 = a.instances['leg-1'].faces
side1Faces1 = s1.getSequenceFromMask(mask=('[#1 ]', ), )
a.Surface(side1Faces=side1Faces1, name='skinContactIn')
\end{lstlisting}
We select the inner radius of the assist-disc (lines \texttt{2--4}) and project this ring onto the skin (lines \texttt{6--8}, figure \ref{abaqus_skinPartitioned}). Finally, the newly defined area gets a surface definition for contact (lines \texttt{10--12}).
\begin{figure}[h!]
\includegraphics[width=\linewidth]{abaqus_skinPartitioned.png}
\caption{Definition of indenter contact area by partitioning of the skin. The inner radius of the assist-disc is projected onto the skin surface and the area inside the new (red) contour will be used for contact modelling with the indenter. \label{abaqus_skinPartitioned}}
\end{figure}
\subsection{Meshing the leg}
After partitioning of the skin surface, we can have Abaqus mesh the leg \texttt{instance}. First, we need to `seed' the leg: seeds will be placed at the edges in the model with a density determined by \texttt{param.seed}. These seeds will serve as the corner points of the elements that form a part of the edge: for linear elements nodes will coincide with the seeds; for quadratic elements there will also be nodes between the seeds.
\begin{lstlisting}[language=apython]
# mesh leg
import mesh
a = myModel.rootAssembly
partInstances =(a.instances['leg-1'], )
a.seedPartInstance(regions=partInstances, size=1.000000, deviationFactor=0.1, minSizeFactor=0.1)
c1 = a.instances['leg-1'].cells
cells = c1.getSequenceFromMask(mask=('[#1 ]', ), )
a.setMeshControls(regions=cells, elemShape=TET, technique=FREE)
pickedRegions =(cells, )
elemType1 = mesh.ElemType(elemCode=C3D20R, elemLibrary=STANDARD)
elemType2 = mesh.ElemType(elemCode=C3D15, elemLibrary=STANDARD)
elemType3 = mesh.ElemType(elemCode=C3D10M, elemLibrary=STANDARD)
a.setElementType(regions=pickedRegions, elemTypes=(elemType1, elemType2, elemType3))
a.generateMesh(regions=partInstances)
\end{lstlisting}
After seeding the leg (lines \texttt{3--5}, figure \ref{abaqus_legSeeded}), we tell Abaqus which meshing technique to use (lines \texttt{6--8}) and which element types can be used for meshing (lines \texttt{10--13}). The mesh is finally generated in line \texttt{14} (figure \ref{abaqus_legMeshed}).\\
\noindent Note that Abaqus will only accept the `free' technique (line \texttt{8}) and tetrahedral elements (lines \texttt{8--12}) for meshing a volume with a shape like ours.
\begin{figure}[p!]\center
\subfloat[\label{abaqus_legSeeded}]{%
\includegraphics[width=.85\linewidth]{abaqus_legSeeded.png}}\\
\subfloat[\label{abaqus_legMeshed}]{%
\includegraphics[width=.85\linewidth]{abaqus_legMeshed.png}}
\caption{Meshing the leg in Abaqus. With \textbf{(a)} the mesh seeds on the leg's edges; and \textbf{(b)} the resulting mesh. Note that there are no elements crossing the indentation contact area boundary because we partitioned the skin surface before meshing. \label{abaqus_legMeshing}}
\end{figure}
\subsection{Contact modelling for indenter and skin}
Contact between the indenter and the skin has to modelled and this is done in Abaqus' \texttt{interaction} module. First we need to define the type of `interaction' (contact) itself, and then we define the surfaces for which this contact interaction needs to be active:
\begin{lstlisting}[language=apython]
# indenter skin contact interaction
import interaction
myModel.ContactProperty('contact')
myModel.interactionProperties['contact'].TangentialBehavior(formulation=FRICTIONLESS)
myModel.interactionProperties['contact'].NormalBehavior(pressureOverclosure=HARD, allowSeparation=ON, constraintEnforcementMethod=DEFAULT)
a = myModel.rootAssembly
region1=a.instances['indenter-1'].surfaces['indenter']
region2=a.surfaces['skinContactIn']
myModel.SurfaceToSurfaceContactStd(name='indentInteraction', createStepName='Initial', master=region1, slave=region2, sliding=FINITE, thickness=ON, interactionProperty='contact', adjustMethod=NONE, initialClearance=OMIT, datumAxis=None, contactTracking=ONE_CONFIG, clearanceRegion=None)
\end{lstlisting}
Tangential contact between the indenter and skin is modelled as frictionless (line \texttt{4}, the skin can freely slide over the indenter surface), and the normal contact behaviour is `hard' (line \texttt{5}, skin nodes are not allowed to penetrate the indenter surface). Furthermore, nodes of the skin are allowed to separate from the indenter (line \texttt{5}) when contact between the indenter and skin is 'released' (i.e.\ the skin nodes will not `stick' to the indenter).
We finally use our earlier defined surface sets (lines \texttt{6--8}) to assign this interaction contact property to the two surfaces (line \texttt{9}). The indenter is the `master' surface, the skin is the `slave' surface that will follow the deformation defined by the indenter surface.
\subsection{Tie the nodes on the tibia into a rigid surface}
Also in the \texttt{interaction} module, we need to convert the nodes on the tibia into a rigid surface. The relative positions of these tibia surface nodes will not change, modelling the (hollow) tibia bone as completely rigid (undeformable). Boundary conditions for these coupled nodes will be applied to the tibia's reference point.
We defined the tibia surface set and the reference point (set) earlier, so this is easy:
\begin{lstlisting}[language=apython]
# bone to rigid surface
a = myModel.rootAssembly
region4=a.instances['leg-1'].sets['bone']
region5=a.instances['leg-1'].sets['boneRP']
myModel.RigidBody(name='rigidBone', refPointRegion=region5, tieRegion=region4)
\end{lstlisting}
\subsection{The cast}
When \texttt{param.cast = 1}, we also model the alginate cast around the leg. The modelling procedure that we follow is similar to that of the leg: create part, import geometry, create a hole for the indenter, instance part into the model assembly, mesh the cast, convert the cast to a rigid surface, and define contact between cast and skin.
First, we create a \texttt{part} for the cast, import the geometry contours and loft the cast:
\begin{lstlisting}[language=apython,escapechar=!]
# build cast
myPart = myModel.Part(name='cast', dimensionality=THREE_D, type=DEFORMABLE_BODY)
# import contours
execfile('basil140611_castContours.py')
# loft cast
e = myPart.edges
# get ordered list of egdes (because: not the same as wire-numbers, and prone to change when the part changes)
ed = e.getClosest(coordinates=((-8.230588, 2.481426, -9.000000), (-8.738121, 2.341253, -8.000000), (-8.872285, 2.523443, -7.000000), (-9.310450, 2.158532, -6.000000), (-9.679797, 2.190323, -5.000000), (-9.724094, 2.282848, -4.000000), (-9.870556, 2.097831, -3.000000), (-9.926339, 2.193581, -2.000000), (-9.938902, 1.832282, -1.000000), (-9.967482, 2.154195, 0.000000), (-9.881632, 2.032669, 1.000000), (-9.640275, 1.877945, 2.000000), (-9.408549, 1.820624, 3.000000), (-9.286976, 2.289981, 4.000000), (-9.132973, 2.417475, 5.000000), (-9.015611, 2.588699, 6.000000), (-8.827642, 2.824779, 7.000000), (-8.656432, 3.013280, 8.000000), (-8.475119, 3.391914, 9.000000), ))
# create ordered edge list
ledges=list()
for i in range(0, 19):
t = ed[i]
ledges.append( t[0] );
# create loft of edge list
myPart.ShellLoft(loftsections=((ledges[0], ), (ledges[1], ), (ledges[2], ), (ledges[3], ), (ledges[4], ), (ledges[5], ), (ledges[6], ), (ledges[7], ), (ledges[8], ), (ledges[9], ), (ledges[10], ), (ledges[11], ), (ledges[12], ), (ledges[13], ), (ledges[14], ), (ledges[15], ), (ledges[16], ), (ledges[17], ), (ledges[18], ), ), startCondition=NONE,endCondition=NONE)
\end{lstlisting}
......@@ -71,7 +71,49 @@ morekeywords = {WireSpline,
axisPoint,
axisDirection,
DatumCsysByDefault,
dependent}}
dependent,
instances,
PartitionFaceByProjectingEdges,
extendEdges,
seedPartInstance,
regions,
partInstance,
size,
deviationFactor,
minSizeFactor,
elemShape,
technique,
mesh,
ElemType,
elemCode,
elemLibrary,
setElementType,
elemTypes,
generateMesh,
setMeshControls,
ContactProperty,
interactionProperties,
TangentialBehavior,
formulation,
NormalBehavior,
pressureOverclosure,
allowSeparation,
constraintEnforcementMethod,
surfaces,
SurfaceToSurfaceContactStd,
createStepName,
master,
slave,
sliding,
interactionProperty,
adjustMethod,
initialClearance,
datumAxis,
contactTracking,
clearanceRegion,
RigidBody,
refPointRegion,
tieRegion}}
\lst@definelanguage{basillab}
{alsolanguage = Octave,
keywordsprefix = {bas_},
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment