\documentclass[12pt]{beamer}
\input{BEAMERoptions.tex}

% ----- Packages and libraries ----- %
\usepackage[T1]{fontenc} 				% cut/paste and search with "_"
\usepackage[english]{babel}
\usepackage{graphics}
\usepackage{verbatim}
\usepackage{times}
\usepackage{graphicx}
\usepackage{epsfig}
\usepackage{subfigure}
\usepackage{amssymb}
\usepackage{amsmath, amsfonts}
\usepackage{amsthm}
\usepackage{color}
\usepackage{alltt}
\usepackage{anyfontsize}
\usepackage{tikz}
   \usetikzlibrary{shapes, arrows, shadows}

\newcommand{\Frametitle}[1]{\frametitle{\includegraphics[width=0.25in]{esp_logo.png}
      \hspace{0.05in} #1}}

\newcommand{\FrameTitle}[1]{\frametitle{\includegraphics[width=0.3in]{caps_logo.png}
      \hspace{0.05in} #1}}

\setbeamertemplate{navigation symbols}{}
\setbeamertemplate{caption}[numbered]

%============================
% command to repeate a ~ n-times
%============================
\newcount\myloopcounter

\newcommand{\spaces}[1][10]{%
  \myloopcounter0% initialize the loop counter
  \loop\ifnum\myloopcounter < #1 % Test if the loop counter is < #1
  ~%
  \advance\myloopcounter by 1 %
  \repeat % start again
}
%============================

% ----- Presentation information ----- %
\title[AIM Programming -- Mesh Writing]{
\includegraphics[width=1.0in]{caps_logo.png}\\
Computational Aircraft Prototype Syntheses\\
AIM Programming -- Mesh Writing\\[0.02in]
For {\tt ESP} Rev 1.28}

\author[Haimes]{
Bob Haimes \\
  {\footnotesize \textcolor{blue}{bob@geocentrictech.com}~~or~~\textcolor{blue}{haimes@mit.edu} \\[-0.03in]
    Geocentric Technologies LLC}
}

\date[July 2025]{}

% ----- Document follows ----- %

\begin{document}

\begin{frame}
  \titlepage
\end{frame}

\begin{frame}
  \FrameTitle{Introduction}
   
   \begin{block}{Mesh Writer AIM Plugins}
   \begin{itemize}
   \item Can always write out a mesh as part of {\it aimCalcOutputs}
   \item Can use existing MeshWriters if the structures discussed below are filled out
   \item Can provide support for new mesh formats to the community\\
   See {\tt \$ESP\_ROOT/src/CAPS/aim/meshWriter} for a list of supported formats
   \end{itemize}
   \end{block}

\end{frame}

\begin{frame}

  \center
  {\LARGE AIM meshWriter} \\[0.05in]
  {\LARGE Structures and Functions}

  \vspace{0.4in}
    \begin{itemize}
   \item Structures filled by an AIM mesh generation
   \item Functions for initializing and filling the structures
   \item The library (libaimMesh.a/aimMesh.lib) must be included in the AIM so/DLL build
   \end{itemize}

 \end{frame}

%------------------------------------------------------------------
\begin{frame}[fragile]
  \FrameTitle{meshWriter Structures 1/5}

  \scriptsize

  \begin{block}{Dynamically loading the mesh writer}
    \footnotesize
   The meshing AIM dynamically loads the appropriate so/DLL to output the mesh file in its default location.
   If the mesh data is resident in memory during postAnalysis, it needs be written to disk and freed. The mesh writer
   shared object/DLL needs to contain just the entry points: {\tt meshExtension} \& {\tt meshWrite} (see below).
   \end{block}

\begin{block}{aimMesh Structure}
The complete representation of a mesh
{\tiny {\bf
\begin{verbatim}
  typedef struct {
    aimMeshData *meshData;
    aimMeshRef  *meshRef;
  } aimMesh;
\end{verbatim}
}} \vspace{-1em}
\begin{description}
\item[meshData] represents the mesh coordinates and connectivity
\item[meshRef] mapping of the boundary mesh vertexes to the interior vertexes
\end{description}
A mesh generation AIM is responsible for filling the complete \textcolor{blue}{aimMesh} Structure that is passed to a {\tt meshWriter} shared library, which is responsible for writing the data to disk. Only the {\tt meshRef} pointer is passed via a link to an analysis AIM.
\end{block}
\end{frame}

%------------------------------------------------------------------
\begin{frame}[fragile]
  \FrameTitle{meshWriter Structures 2/5}

\scriptsize
\begin{block}{aimMeshElemGroup Structure}
  Represents a group of elements of the same type
  \vspace{-.8em}
{\tiny{ \bf
\begin{verbatim}
typedef struct {
  char             *groupName;  /* name of group or NULL */
  int              ID;          /* Group ID */
  enum aimMeshElem elementTopo; /* Element topology */
  int              order;       /* order of the element (1 - Linear) */
  int              nPoint;      /* number of points defining an element */
  int              nElems;      /* number of elements in the group */
  int              *elements;   /* Element-to-vertex connectivity (1-based)
                                   nElem*nPoint in length */
} aimMeshElemGroup;
\end{verbatim}
}} \vspace{-1em}
\begin{description}
  \setlength{\itemsep}{0pt}
  \item[groupName] group identifier that may be non-unique
  \item[ID] group identifier that may be non-unique
  \item[elementTopo] is one of:
  %\vspace{-0.8em}
  {\tiny {\bf
  \begin{verbatim}
enum aimMeshElem {aimUnknownElem, aimLine, aimTri, aimQuad, aimTet,
                  aimPyramid, aimPrism, aimHex};
  \end{verbatim}
  }}\vspace{-0.8em}
  \item[order] polynomial degree of element
  \item[nPoint] number of points in an element
  \item[nElems] number of elements the group
  \item[elements] Element-to-vertex (1-based) connectivity nElem*nPoint in length
\end{description}

\end{block}

\end{frame}


%------------------------------------------------------------------
\begin{frame}[fragile]
  \FrameTitle{meshWriter Structures 3/5}
\vspace{-0.1in}
\scriptsize
\begin{block}{aimMeshData Structure}
Represents the Cartesian coordinates and element connectivity of the mesh
\vspace{-.8em}
{\tiny {\bf
\begin{verbatim}
  typedef double aimMeshCoords[3];
  typedef int    aimMeshIndices[2];
  typedef struct {
    int              dim;         /* Physical dimension: 2D or 3D */
    int              nVertex;     /* total number of vertices in the mesh */
    aimMeshCoords    *verts;      /* the xyz coordinates of the vertices
                                     nVertex in length */
    int              nElemGroup;  /* number of element groups */
    aimMeshElemGroup *elemGroups; /* element groups -- nElemGroup in length */
    int              nTotalElems; /* total number of elements */
    aimMeshIndices   *elemMap;    /* group,elem map in original element ordering
                                     nTotalElems in length -- can be NULL */
  } aimMeshData;
\end{verbatim}
}} \vspace{-1em}
\begin{description}
  \setlength{\itemsep}{0pt}
\item[dim] must be 2 or 3 to represent the number Physical dimensions used in {\tt verts}.
\item[nVertex] number of coordinates
\item[verts] Coordaintes stored as {\tt verts}[$iv$][$d$] for $iv \in [0,\text{nVertex})$ and $d \in [0, dim)$.
\item[nElemGroup] number of element groups
\item[elemGroups] group of elements with all the same type ({\tt nElemGroups} in length)
\item[nTotalElems] total number of elements in the mesh
\item[elemMap] The original element ordering ({\it nTotalElems} in length). {\tt elemMap}[$ie$][0] is the
0-based element group index into {\tt elemGroups}, and {\tt elemMap}[$ie$][1] is 0-based index of the element in the group.
\end{description}
\end{block}
\end{frame}


%------------------------------------------------------------------
\begin{frame}[fragile]
  \FrameTitle{meshWriter Structures 4/5}
\vspace{-0.05in}
\scriptsize

\begin{block}{aimMeshTessMap Structure}
  Represents the a boundary mesh and it's mapping to the interior
  \vspace{-.8em}
{\tiny{ \bf
\begin{verbatim}
typedef struct {
  ego  tess;       /* the EGADS Tessellation Objects (contains Body) */
  int  *map;       /* the mapping between Tessellation vertices and
                      mesh vertices -- tess verts in length */
} aimMeshTessMap;
\end{verbatim}
}} \vspace{-1em}
\begin{description}
  \setlength{\itemsep}{0pt}
  \item[tess] an EGADS tessellation of the boundary
  \item[map] mapping from global tessellation vertices to the interior mesh verticies. Use EG\_statusTessBody to get the length.
\end{description}
\end{block}


\begin{block}{aimMeshBnd Structure}
  Represents the a boundary group information
  \vspace{-.8em}
{\tiny{ \bf
\begin{verbatim}
typedef struct {
  char             *groupName;  /* name of group or NULL */
  int              ID;          /* Group ID */
} aimMeshBnd;
\end{verbatim}
}} \vspace{-1em}
\begin{description}
  \setlength{\itemsep}{0pt}
  \item[groupName] a name associated with a boundary group
  \item[ID] an identifier associated with the group
\end{description}
\end{block}

\end{frame}

%------------------------------------------------------------------
\begin{frame}[fragile]
  \FrameTitle{meshWriter Structures 5/5}
\vspace{-0.05in}
\scriptsize
\begin{block}{aimMeshRef Structure}
  Represents the boundary of a mesh and a reference to the full mesh
  \vspace{-.8em}
{\tiny{ \bf
\begin{verbatim}
typedef struct {
  enum aimMeshType type;     /* type of mesh referenced */
  int              nmap;     /* number of EGADS Tessellation Objects */
  aimMeshTessMap  *maps;     /* the EGADS Tess Object and map to mesh verts */
  int              nbnd;     /* number of boundary groups */
  aimMeshBnd      *bnds;     /* boundary group info */
  char            *fileName; /* full path name (no extension) for grids */
  int              _delTess; /* internal use only, whether tess/body ego are deleted */
} aimMeshRef;
\end{verbatim}
}} \vspace{-1em}
\begin{description}
  \setlength{\itemsep}{0pt}
  \item[type] is one of:
  {\tiny {\bf
\begin{verbatim}
enum aimMeshType {aimUnknownMeshType, aimAreaMesh,
                  aimSurfaceMesh, aimVolumeMesh};
\end{verbatim}
  }}
  \item[nmap] number of mappings from the boundary to the interior
  \item[maps] boundary to the interior mapping
  \item[nbnd] number of boundary groups
  \item[bnds] bounary group information
  \item[fileName] absolute path to the full mesh file name without the extension
  \item[\_delTess] Internal usage that should not be modified
\end{description}

\end{block}

\end{frame}


%------------------------------------------------------------------
\begin{frame}
  \FrameTitle{AIM Mesh Writer Interface}

%\setbeamercolor{block title}{bg=red!80}
 \begin{block}{Mesh writer entry points}

{\footnotesize
The following two functions are required for each dynamically loaded mesh writer.\\[-0.01in]
They allow the AIM mesh writer interface the ability to complete the filenames and \\[-0.01in]
to output the meshes. This is dynamically loadable so that new (or custom) mesh \\[-0.05in]
writer can be easily attached to a CAPS session.}

{\scriptsize
\vspace{0.2in}
{\tt
\textcolor{magenta}{const char} *extension = meshExtension()}
\begin{description}
\item[extension] the file extension used for this writer
\end{description}

\vspace{0.2in}
{\tt
icode = meshWrite(\textcolor{magenta}{void} *aimInfo, \textcolor{blue}{aimMesh} *mesh)}

\begin{description}

\item[aimInfo] the AIM context
\item[mesh]  the mesh data structure that will be written
\item[icode] integer return code
\end{description}
\vspace{0.05in}
}
\end{block}

\end{frame}

\begin{frame}
  \FrameTitle{AIM Mesh Library -- Mesh Generator}

% \setbeamercolor{block title}{bg=red!80}
 \begin{block}{Delete previous meshes}
 {\scriptsize

{\tt
icode = aim\_deleteMeshes(\textcolor{magenta}{void} *aimInfo,  \textcolor{blue}{aimMeshRef} *meshRef)}

\begin{description}

\item[aimInfo] the AIM context
\item[meshRef] the pointer to the Mesh Reference Structure
\item[icode] integer return code
\end{description}}
\scriptsize
This should be called during the mesh writing
preAnalysis to cleanup mesh files from previous invocations of
the AIM instance. This is required because if the mesh file already exists,
it is not (re)written in {\tt aim\_writeMeshes}.
\end{block}

 \begin{block}{Query mesh existance}
 {\scriptsize

{\tt
icode = aim\_queryMeshes(\textcolor{magenta}{void} *aimInfo,  \textcolor{magenta}{int} index, \textcolor{blue}{aimMeshRef} *meshRef)}

\begin{description}

\item[aimInfo] the AIM context
\item[index] the AnalysisOut Value index to query
\item[meshRef] the pointer to the Mesh Reference Structure
\item[icode] integer return code
\end{description}}
\scriptsize
This call returns {\tt CAPS\_SUCCESS} if the mesh file already exists and no others
are needed, if positive then this is the number of file types that need to be
written via calling {\tt aim\_writeMeshes}.
\end{block}

\end{frame}

%------------------------------------------------------------------
\begin{frame}
  \FrameTitle{AIM Mesh Library -- Mesh Generator}

% \setbeamercolor{block title}{bg=red!80}
 \begin{block}{Write meshes}
 {\scriptsize

{\tt
icode = aim\_writeMeshes(\textcolor{magenta}{void} *aimInfo,  \textcolor{magenta}{int} index,\\
\spaces[24]\textcolor{magenta}{enum} \textcolor{blue}{capssType} stype, \textcolor{blue}{aimMesh} *mesh)}

\begin{description}

\item[aimInfo] the AIM context
\item[index] the AnalysisOut Value index to write
\item[stype] ANALYSISIN or ANALYSISOUT
\item[mesh] the pointer to the Mesh Structure
\item[icode] integer return code
\end{description}}

\vspace{0.075in}
\scriptsize
If meshes need to be output (see {\tt aim\_queryMeshes}), the mesh data must be populated
and then written out by calling this function.\\[0.1in]

{\bf For stype = ANALYSISIN:}\\
This calls {\tt writeMesh} for each name sepcified by the list of strings in the analysis value. The suffix ``Writer'' is appended to each name.
\\[0.1in]
{\bf For stype = ANALYSISOUT:}\\
This calls {\tt writeMesh} for each linked solver Analysis Input (as specified in the linkage).
\\[0.1in]
After this call the memory allocated to fill \textcolor{espred}{mesh} should
be freed.

\end{block}

\end{frame}

%------------------------------------------------------------------
\begin{frame}
  \FrameTitle{AIM Mesh Library -- Mesh Generator}

 \begin{block}{Write a single mesh}
 {\scriptsize

{\tt
icode = aim\_writeMesh(\textcolor{magenta}{void} *aimInfo,  \textcolor{magenta}{const char} *writerName,\\
\spaces[22]\textcolor{magenta}{const char} *units, \textcolor{blue}{aimMesh} *mesh)}

\begin{description}

\item[aimInfo] the AIM context
\item[writerName] the string for a mesh writer (including the suffix ``Writer'' at the end)
\item[units] length units for the output mesh (may be NULL)
\item[mesh] the pointer to the Mesh Structure
\item[icode] integer return code
\end{description}}

\vspace{0.05in}
\scriptsize

\end{block}

\end{frame}

%------------------------------------------------------------------
\begin{frame}
  \FrameTitle{AIM Mesh Library -- Mesh Generator}

 \begin{block}{Initialize aimMeshRef}
  {\scriptsize

 {\tt
 icode = aim\_initMeshRef(\textcolor{blue}{aimMeshRef} *meshRef, \textcolor{blue}{enum aimMeshType} type)}

 \begin{description}
 \item[meshRef] the aimMeshRef instance for member data initialization
 \item[type] the AIM mesh type ({\tt aimUnknownMeshType}, {\tt aimAreaMesh}, {\tt aimSurfaceMesh} or {\tt aimVolumeMesh})
 \item[icode] integer return code
 \end{description}}
 \end{block}


\begin{block}{Free aimMeshRef}
  {\scriptsize

 {\tt
 icode = aim\_freeMeshRef(\textcolor{blue}{aimMeshRef} *meshRef)}

 \begin{description}
 \item[meshRef] the aimMeshRef instance to free member data
 \item[icode] integer return code
 \end{description}}
 \end{block}

 \begin{block}{Initialize aimMeshBnd}
  {\scriptsize

 {\tt
 icode = aim\_initMeshBnd(\textcolor{blue}{aimMeshBnd} *meshBnd)}

 \begin{description}
 \item[meshBnd] the aimMeshBnd instance for member data initialization
 \item[icode] integer return code
 \end{description}}
 \end{block}
\end{frame}

%------------------------------------------------------------------
\begin{frame}
  \FrameTitle{AIM Mesh Library -- Mesh Generator}

\begin{block}{Initialize aimMeshData}
  {\scriptsize

 {\tt
 icode = aim\_initMeshData(\textcolor{blue}{aimMeshData} *meshData)}

 \begin{description}
 \item[meshData] the aimMeshData instance for member data initialization
 \item[icode] integer return code
 \end{description}}
 \end{block}


\begin{block}{Free aimMeshData}
  {\scriptsize

 {\tt
 icode = aim\_freeMeshData(\textcolor{blue}{aimMeshData} *meshData)}

 \begin{description}
 \item[meshData] the aimMeshData instance to free member data
 \item[icode] integer return code
 \end{description}}
 \end{block}

\begin{block}{Element topological dimension}
  {\scriptsize

 {\tt
 dim = aim\_elemTopoDim(\textcolor{magenta}{enum} aimMeshElem topo)}

 \begin{description}
 \item[topo] the aimMeshElem element type
 \item[dim] topological dimension of the element type: 1, 2 or 3
 \end{description}}
 \end{block}
\end{frame}

%------------------------------------------------------------------
\begin{frame}
  \FrameTitle{AIM Mesh Library -- Mesh Generator}
  \vspace{-0.05in}
 \begin{block}{Add element group to aimMeshData}
  {\scriptsize

 {\tt
 icode = aim\_addMeshElemGroup(\textcolor{magenta}{void} *aimInfo, \textcolor{magenta}{const char} *groupName, \\
 \spaces[29]\textcolor{magenta}{int} ID, \textcolor{magenta}{enum} aimMeshElem elementTopo, \\
 \spaces[29]\textcolor{magenta}{int} order, \textcolor{magenta}{int} nPoint, \\
 \spaces[29]\textcolor{blue}{aimMeshData} *meshData)}

 \begin{description}
  \setlength{\itemsep}{0pt}
  \item[aimInfo] the AIM context
  \item[groupName] the name of the group (may be \textcolor{magenta}{NULL})
  \item[ID] an integer group ID
  \item[order] the degree of the polynomial for the elements
  \item[nPoint] number of points in the element
  \item[meshData] the aimMeshData where the element group is added
  \item[icode] integer return code
 \end{description}}
 \end{block}

 \vspace{-0.05in}
 \begin{block}{Add elements to aimMeshElemGroup}
  {\scriptsize

 {\tt
 icode = aim\_addMeshElem(\textcolor{magenta}{void} *aimInfo, \textcolor{magenta}{int} nElems, \\
  \spaces[24]\textcolor{blue}{aimMeshElemGroup} *elemGroup)}

 \begin{description}
  \setlength{\itemsep}{0pt}
  \item[aimInfo] the AIM context
  \item[nElems] number of elements to add to the element group
  \item[elemGroup] the aimMeshElemGroup where the elements are added
  \item[icode] integer return code
 \end{description}}
 \end{block}

\end{frame}

%------------------------------------------------------------------
\begin{frame}
  \FrameTitle{AIM Mesh Library -- Mesh Morphing}

\begin{block}{Write meshRef to disk}
  {\scriptsize

 {\tt
 icode = aim\_storeMeshRef(\textcolor{magenta}{void} *aimInfo, \textcolor{magenta}{const} \textcolor{blue}{aimMeshRef} *meshRef, \\
 \spaces[25]\textcolor{magenta}{const char} *meshextension)}

 \begin{description}
  \setlength{\itemsep}{0pt}
  \item[aimInfo] the AIM context
  \item[meshRef] the aimMeshRef instance written to disk
  \item[meshextension] the mesh extension used by the analysis AIM
  \item[icode] integer return code
 \end{description}}
 \scriptsize
 Note: This function should be called by an analysis AIM during preAnalysis to store
 a meshRef instance for mesh morphing.
 \end{block}


\begin{block}{Load aimMeshRef from disk}
  {\scriptsize

 {\tt
 icode = aim\_loadMeshRef(\textcolor{magenta}{void} *aimInfo, \textcolor{blue}{aimMeshRef} *meshRef)}

 \begin{description}
  \setlength{\itemsep}{0pt}
  \item[aimInfo] the AIM context
  \item[meshRef] the aimMeshRef instance fill from disk
  \item[icode] integer return code
 \end{description}}
 \scriptsize
 Note: This function should be called by an analysis AIM during preAnalysis to load
 a meshRef instance for mesh morphing.
 \end{block}
\end{frame}


%------------------------------------------------------------------
\begin{frame}
  \FrameTitle{AIM Mesh Library -- Mesh Morphing}

\begin{block}{Morph a meshRef}
  {\scriptsize

 {\tt
 icode = aim\_morphMeshUpdate(\textcolor{magenta}{void} *aimInfo, \textcolor{blue}{aimMeshRef} *meshRef, \\
 \spaces[28]\textcolor{magenta}{int} numBody, \textcolor{blue}{ego} *bodies)}

 \begin{description}
  \setlength{\itemsep}{0pt}
  \item[aimInfo] the AIM context
  \item[meshRef] the aimMeshRef instance to be updated
  \item[numBody] number of bodies
  \item[bodies] ego list of new bodies ({\it numBody} in length)
  \item[icode] integer return code
 \end{description}}
 \scriptsize
 Note: The tessellation objects in {\it meshRef} are mapped to {\it bodies} and
 the boundary to interior mapping is updated.
 \end{block}


\begin{block}{Create a meshRef to a local file}
  {\scriptsize

 {\tt
 icode = aim\_localMeshRef(\textcolor{magenta}{void} *aimInfo, \textcolor{magenta}{const} \textcolor{blue}{aimMeshRef} *meshRefIn, \\
 \spaces[25]\textcolor{blue}{aimMeshRef} *meshRefLocal)}

 \begin{description}
  \setlength{\itemsep}{0pt}
  \item[aimInfo] the AIM context
  \item[meshRefIn] the input aimMeshRef instance
  \item[meshRefLocal] the output aimMeshRef instance with an AIM local file
  \item[icode] integer return code
 \end{description}}
 \scriptsize
 Note: All pointers are shallow copied to meshRefLocal
 \end{block}

\end{frame}

\begin{frame}
\FrameTitle{Exercises}

\begin{block}{Mesh Writing}  
In {\it exercises/session13}:
\begin{itemize}
\item Run {\tt session13.py} and view the resultant binary STL file: {\tt myExample/Scratch/cfd/myMeshFile.bstl}\\
You can use {\it ParaView}, but  may need to rename with the file with the extension {\tt .stl}
\item Run {\tt 2bodySTL.py} and note the difference.
\end{itemize}
\end{block}
  
 \end{frame}

\end{document}

