Clarified descriptions, and added examples.
authorOrion Lawlor <olawlor@acm.org>
Wed, 12 Mar 2003 17:34:54 +0000 (17:34 +0000)
committerOrion Lawlor <olawlor@acm.org>
Wed, 12 Mar 2003 17:34:54 +0000 (17:34 +0000)
doc/fem/idxl.tex

index 9185cbbea90d9a82c4e9f27478e8293668c8149b..a0e0e14e66051d338fe75e8dcb704cdf4ed118d1 100644 (file)
@@ -126,12 +126,14 @@ Like Index Lists, Layouts are referred to via an opaque handle---in a C program
 
 \subsubsection{Layout Routines}
 
+In most programs, the data to be communicated is a dense array of data of one type.  In this case, there is only one layout routine you need to know:
+
 \prototype{IDXL\_Layout\_create}
 \function{IDXL\_Layout\_t IDXL\_Layout\_create(int type,int width);}
 \function{integer function IDXL\_Layout\_create(type,width)}
     \args{integer, intent(in) :: type,width}
 
-The simplest data layout to describe---a dense array of this IDXL datatype, with \kw{width} communicated items of data per entity.  
+The simplest data layout to describe---a dense array of this IDXL datatype, indexed by entity number, with \kw{width} pieces of data per entity. Note that the number of entities is not stored with the layout--the number of entities to be communicated depends on the communication routine.
 
 The IDXL datatypes are:
 \begin{center}
@@ -148,7 +150,7 @@ IDXL Datatype & C Datatypes & Fortran Datatypes \\\hline
 \end{tabular}
 \end{center}
 
-For example, if you keep a dense array with 3 doubles of net force per node, you'd call this routine as:
+For example, if you keep a dense array with 3 doubles of force per node, you'd call this routine as:
 
 \begin{alltt}
 // C++ version:
@@ -163,20 +165,25 @@ For example, if you keep a dense array with 3 doubles of net force per node, you
 
 \end{alltt}
 
+This routine was once called \kw{FEM\_Create\_simple\_field}.
+
 
 \subsubsection{Advanced Layout Routines}
 \label{sec:IDXL_Layout_offset}
+
+These advanced routines are only needed if you want to exchange data stored in an array of user-defined types.  Most programs only need \kw{IDXL\_Layout\_create}.
+
 \prototype{IDXL\_Layout\_offset}
 \function{IDXL\_Layout\_t IDXL\_Layout\_offset(int type, int width, int offsetBytes, int distanceBytes,int skewBytes);}
 \function{integer function IDXL\_Layout\_offset(type,width,offsetBytes,distanceBytes,skewBytes)}
     \args{integer, intent(in) :: type,width,offsetBytes,distanceBytes,skewBytes}
 
-The most general data layout.  This routine expands on \kw{IDXL\_Layout\_create} by adding: 
+The most general data layout--an array indexed by entity, containing \kw{width} pieces of data per entity.  This routine expands on \kw{IDXL\_Layout\_create} by adding support for user-defined types or other unusual data layouts.  You describe your layout by giving various in-memory byte offsets that describe the data is stored. Again, the number of entities is not stored with the layout--the number of entities to be communicated depends on the communication routine.
 
 \begin{itemize}
   \item \kw{offsetBytes} The number of bytes from the start of the array to the start of the data.
-  \item \kw{distanceBytes} The number of bytes taken by one entity's record.
-  \item \kw{skewBytes} The number of bytes between each field of a record.  Since this can almost always be determined from the data type, this parameter can also be left as zero.
+  \item \kw{distanceBytes} The number of bytes taken by one entity.
+  \item \kw{skewBytes} The number of bytes between each piece of data.  Since this can almost always be determined from the size of the base data type, this parameter can be left as zero.
 \end{itemize}
 
 \begin{figure}[h]
@@ -187,7 +194,7 @@ The most general data layout.  This routine expands on \kw{IDXL\_Layout\_create}
 \label{fig:layout}
 \end{figure}
 
-For example, if your node data is all stored in a struct (named TYPE in fortran), offsetBytes gives the distance between the start of the struct and the force and distanceBytes gives the size in bytes of the struct.
+For example, if your node data is all stored in a struct (in fortran, a named TYPE), offsetBytes gives the distance between the start of the struct and the force; and distanceBytes gives the size in bytes of the struct.  
 
 In C, the offsetof and sizeof keywords are useful for finding these values.  In Fortran, we provide a special routine called \kw{foffsetof} that returns the distance, in bytes, between its two arguments.
 
@@ -282,13 +289,37 @@ This section brings together all the pieces of IDXL: Index Lists are used to det
 
 Sum these \kw{indices} of shared entites across all chunks that share them.
 The user \kw{data} array is interpreted according to the given \kw{layout}.
-If \kw{comm} is zero, this routine is blocking and finishes the communication immediately.
 
+If \kw{comm} is zero, this routine is blocking and finishes the communication immediately.
 If \kw{comm} is not zero, this routine is non-blocking and equivalent to a call to 
 \kw{IDXL\_Comm\_send} followed by a call to \kw{IDXL\_Comm\_sum}.
 
 This routine is typically used to sum up partial values on shared nodes.
 It is a more general version of the old FEM routine \kw{FEM\_Update\_field}.
+For example, to sum up the shared-node values in a 3d \uw{force} vector indexed 
+by node, you would use:
+
+\begin{alltt}
+// C++ version:
+     double *force=new double[3*nNodes];
+     IDXL\_Layout\_t force\_layout=IDXL\_Layout\_create(IDXL\_DOUBLE,3);
+     IDXL\_t shared\_indices=FEM_Comm_shared(mesh,FEM_NODE);
+     
+     ... in the time loop ...
+         IDXL_Comm_sendsum(0,shared_indices,force_layout,force);
+
+! F90 Version
+     double precision, allocatable :: force(:,:)
+     integer :: force\_layout, shared_indices
+     ALLOCATE(force(3,nNodes)) ! (could equivalently use force(3*nNodes) )
+     force\_layout=IDXL\_Layout\_create(IDXL\_DOUBLE,3)
+     shared_indices=FEM_Comm_shared(mesh,FEM_NODE)
+     
+     ... in the time loop ...
+         CALL IDXL_Comm_sendsum(0,shared_indices,force_layout,force)
+
+\end{alltt}
+
 
 \prototype{IDXL\_Comm\_sendrecv}
 \function{void IDXL\_Comm\_sendrecv(IDXL\_Comm\_t comm,IDXL\_t indices,IDXL\_Layout\_t layout,void *data);}
@@ -299,14 +330,40 @@ It is a more general version of the old FEM routine \kw{FEM\_Update\_field}.
 Send these (typically real) send \kw{indices} and copy in these 
 (typically ghost) receive \kw{indices}.
 The user \kw{data} array is interpreted according to the given \kw{layout}.
-If \kw{comm} is zero, this routine is blocking and finishes the communication immediately.
 
+If \kw{comm} is zero, this routine is blocking and finishes the communication immediately.
 If \kw{comm} is not zero, this routine is non-blocking and equivalent to a call to 
 \kw{IDXL\_Comm\_send} followed by a call to \kw{IDXL\_Comm\_sum}.
 
 This routine is typically used to obtain the values of ghost entities.
 It is a more general version of the old FEM routine \kw{FEM\_Update\_ghost\_field}.
+For example, to obtain 7 solution values per ghost element, storing \uw{gElem}
+ghosts in the array just after the \uw{nElem} regular elements, we could:
 
+\begin{alltt}
+// C++ version:
+     double *elem=new double[7*(nElem+gElem)];
+     IDXL\_Layout\_t elem\_layout=IDXL\_Layout\_create(IDXL\_DOUBLE,7);
+     IDXL\_t ghost\_original=FEM_Comm_ghost(mesh,FEM_ELEM+1);
+     IDXL\_t ghost\_shifted=IDXL_Create(); // ghosts start at nElem
+     IDXL_Combine(ghost_shifted,ghost_original,0,nElem);
+     
+     ... in the time loop ...
+         IDXL_Comm_sendrecv(0,ghost_shifted,elem_layout,elem);
+
+! F90 Version
+     double precision, allocatable :: elem(:,:)
+     integer :: elem\_layout, ghost_original,ghost_shifted
+     ALLOCATE(elem(7,nElem+gElem))
+     elem\_layout=IDXL\_Layout\_create(IDXL\_DOUBLE,7)
+     ghost\_original=FEM_Comm_ghost(mesh,FEM_ELEM+1)
+     ghost\_shifted=IDXL_Create() ! ghosts start at nElem+1
+     CALL IDXL_Combine(ghost_shifted,ghost_original,1,nElem+1)
+     
+     ... in the time loop ...
+         CALL IDXL_Comm_sendrecv(0,ghost_shifted,elem_layout,elem)
+
+\end{alltt}
 
 
 \subsubsection{Advanced Communication Routines}