Beispiel #1
0
static int
build_side_node_list(int elem,
		     int face,
		     int eb_index,
		     Exo_DB *exo,
		     int *snl)
{
  int element_type;
  int i;
  int nodes_this_side;
  int num_sides;
  int shape;
  
  int local_nodeces[MAX_NODES_PER_SIDE];

  /*
   * Assume a canonical ordering to the local nodes in an element according
   * to the PATRAN convention. Faces, too, are conventionally numbered, so
   * all that is needed is the kind of element we have.
   */

  element_type = Elem_Type(exo, elem);
  shape        = type2shape(element_type);
  num_sides    = shape2sides(shape);

  /*
   * Count up the number of nodes and provide their local 0-based
   * indeces or offsets so their global names may be more easily retrieved.
   */

  nodes_this_side = sides2nodes(face, shape, local_nodeces);
  EH(nodes_this_side, "Problem counting nodes on an element face.");

  for ( i=0; i<nodes_this_side; i++)
    {
      snl[i] = exo->elem_node_list[exo->elem_node_pntr[elem]
				  +local_nodeces[i]];
    }

  return(nodes_this_side);
}
Beispiel #2
0
void
build_node_node(Exo_DB *exo)
{
  int curr_list_size;
  int dude;
  int e;
  int elem;
  int end;
  int i;
  int length;
  int max;
  int n;
  int node;
  int npe;
  int start;
  int this_node;
  int total_list_size;
  int n_elem;
  
  int *list;
  /*
   * Don't even attempt to do this without adequate preparation.
   */

  if ( ! exo->node_elem_conn_exists )
    {
      EH(-1, "node_elem conn must exist before node_node can be built.");
    }

  if ( ! exo->elem_node_conn_exists )
    {
      EH(-1, "elem_node conn must exist before node_node can be built.");
    }


  /*
   * Intial memory allocation. The length of the node list will be less than
   * this number by probably about a factor of 2. We will realloc more
   * precisely later. Repeating - this is an overestimate.
   */

  length = 0;

  max    = -1;

  for ( node=0; node<exo->num_nodes; node++)
    {
      this_node = 0;
      for ( e=exo->node_elem_pntr[node]; e<exo->node_elem_pntr[node+1]; e++)
	{
	  elem       = exo->node_elem_list[e];
	  npe        = exo->elem_node_pntr[elem+1] - exo->elem_node_pntr[elem];
	  length    += npe;
	  this_node += npe;
	}
      if ( this_node > max )
	{
	  max = this_node;
	}
    }

  exo->node_node_conn_exists = TRUE;
  exo->node_node_pntr        = (int *) smalloc((exo->num_nodes+1)*sizeof(int));
  exo->node_node_list        = (int *) smalloc(length*sizeof(int));
  exo->centroid_list         = (int *) smalloc((exo->num_nodes)*sizeof(int));

  /*
   * To build unique lists of nodes we'll need some little buffer arrays, too.
   */

  list = (int *) smalloc(max*sizeof(int));

  /*
   * Loop through each node and build a list of all the nodes to which it
   * is connected. Flatten the list by extracting duplicate entries. Finally,
   * sort it and attach it to the global list.
   */

  exo->node_node_pntr[0] = 0;

  total_list_size = 0;

  for ( node=0; node<exo->num_nodes; node++)
    {

      exo->centroid_list[node] = -1;

      /* Clear out any old garbage... */

      for ( i=0; i<max; i++)
	{
	  list[i] = -1;
	}

      curr_list_size = 0;

      for ( e=exo->node_elem_pntr[node]; e<exo->node_elem_pntr[node+1]; e++)
	{
	  elem = exo->node_elem_list[e];

	  start = exo->elem_node_pntr[elem];
	  end   = exo->elem_node_pntr[elem+1];
	  for ( n=start; n<end; n++)
	    {
	      dude = exo->elem_node_list[n];

	      /*
	       * If this dude is not in the list, then add it and make the list
	       * suitably larger.
	       */

	      if ( -1 == in_list(dude, 0, curr_list_size, list) )
		{
		  list[curr_list_size] = dude;
		  curr_list_size++;
		}
	    }
	}

      /* 
       * add centroid nodes of surrounding elements if node is a centroid node
       *  This feature is used in discontinuous Galerkin upwinding....
       */

      if (  ( exo->node_elem_pntr[node+1] - exo->node_elem_pntr[node] ) == 1
	    && ( Use_DG || TRUE ) )  /* Disable Use_DG switch */
	{
	  /* 
	   * This node belongs to only one element 
	   */

	  elem = exo->node_elem_list[ exo->node_elem_pntr[node] ];

	  if (  ( n = centroid_node( Elem_Type( exo, elem ) ) ) != -1 )
	    {

	      if ( node  == exo->elem_node_list[ exo->elem_node_pntr[elem] + n ] )
		{
		  /* This is a centroid node */
		  
		  exo->centroid_list[node] = elem;

		  for( e = exo->elem_elem_pntr[elem]; e < exo->elem_elem_pntr[elem+1]; e++ )
		    {
		      if ( (n_elem = exo->elem_elem_list[e]) != -1 )
			{
			  
			  n = centroid_node ( Elem_Type( exo , n_elem ) );
			  
			  EH(n, "No centroid node exists for element type ");
		      
			  dude = exo->elem_node_list[ exo->elem_node_pntr[n_elem] + n ];
			  
			  if ( -1 == in_list(dude, 0, curr_list_size, list) )
			    {
			      list[curr_list_size++] = dude;
			    }
			}
		    }
		}
	    }
	}


      /*
       * Sort the list before appending to the big concatenated list...
       */

      isort(curr_list_size, list);

      /*
       * No, we're assuming we're never in danger of overrunning the buffer
       * since we were so profligate at the beginning...
       */

      for ( i=0; i<curr_list_size; i++, total_list_size++)
	{
	  exo->node_node_list[total_list_size] = list[i];
	}

      exo->node_node_pntr[node+1] = total_list_size;
    }

  exo->node_node_list = (int *) realloc(exo->node_node_list,
					total_list_size*sizeof(int));

#ifdef DEBUG
  fprintf(stderr, "Printing node-node connectivities...\n");
  for ( node=0; node<exo->num_nodes; node++)
    {
      fprintf(stderr, "Node (%d): ", node+1); /* f77 RuLZ, C++ sUx ! */
      for ( n=exo->node_node_pntr[node]; n<exo->node_node_pntr[node+1]; n++)
	{
	  fprintf(stderr, "(%d) ", exo->node_node_list[n] + 1);
	}
      fprintf(stderr, "\n");
    }
#endif

  safe_free(list);

  return;
}
Beispiel #3
0
void 
extract_nodal_eb_vec(double sol_vec[], int var_no, int ktype, int matIndex,
		     int eb_index, double nodal_vec[], Exo_DB *exo, 
		     int timeDerivative, double time)

  /******************************************************************************
   *
   * extract_nodal_eb_vec:
   *
   *      This function extracts the a particular nodal variable specified
   *  by the program arguments and loads it up into a global vector.
   *  This routine only operates on one element block.
   *
   * This function puts the nodal values of the selected variable
   * into a global solution vector which contains all the mesh nodes,
   * and interpolates the mid-side and centroid values of 
   * all variables with Q1 interpolation on a
   * 9-NODE mesh and interpolates to find their values at the mid-side
   * nodes and at the centroid
   *
   *  Input
   * --------
   *  sol_vec[] = Current global solution vector
   *  var_no    = Variable type to be extracted
   *  ktype     = sub_var number of the variable type to be extracted
   *  matIndex  = material index of the variable to be extracted.
   *             -1 : extract the nonspecific variable
   *             -2 : extract the first variable with var_no no
   *                  matter what material index.
   *  exo       = Exodus database structure
   *  timeDerivative = Are we extracting a time derivative? if so,
   *              then this is true. If not, false.
   *
   * Output
   * -------
   *  nodal_vec[] = nodal vector which receives the value
   *                of the extracted vector. (length number
   *                of nodes)
   *********************************************************************************/
{
  int mn, e_start, e_end, ielem, ielem_type, ip_total, num_local_nodes;
  int ielem_dim, iconnect_ptr, i, I, index;
  int ileft, Ileft, iright, Iright, midside;
  int lastSpeciesSum, iDof, j;
  MATRL_PROP_STRUCT *matrl;
  double rho;
#ifdef DEBUG_HKM
  int nunks, interpType;
#endif

  /*
   * Find out the material number, mn, from the element block index
   */
  mn = Matilda[eb_index];
  matrl = mp_glob[mn];

  /* 
   * Assign local pointer pd to appropriate material
   */
  pd = pd_glob[mn];

  /*
   *  Check for the existence of a special case for the sum of
   *  the last species constraint condition
   */
  lastSpeciesSum = FALSE;
  if (var_no == MASS_FRACTION) {
    if (matrl->Num_Species_Eqn < matrl->Num_Species) {
      if (ktype == matrl->Num_Species - 1) lastSpeciesSum = TRUE;
    }
  }

  /*
   *  Found out the beginning element number and ending element number
   *  from the element block index
   */
  e_start =  exo->eb_ptr[eb_index];
  e_end   =  exo->eb_ptr[eb_index+1];

  /*
   *  Loop over elements in the element block
   */
  for (ielem = e_start; ielem < e_end; ielem++) {

    /*
     *  Get the element type for this element -> Isn't this the
     *  same for all elements in the element block?
     *  
     */
    ielem_type      = Elem_Type(exo, ielem);

    /*
     *  Get the total number of quadrature points
     */
    ip_total        = elem_info(NQUAD, ielem_type); 

    /*
     *  Get the dimensionality of the elements in the element block
     */
    ielem_dim       = elem_info(NDIM, ielem_type);

    /*
     * Number of local nodes in the element
     */
    num_local_nodes = elem_info(NNODES, ielem_type);

    /*
     *  find ptr to beginning of this element's connectivity list 
     *
     */
    iconnect_ptr = Proc_Connect_Ptr[ielem]; 

    /* 
     * First, place the known nodal variable values for this
     * particular variable and type into the nodal vector.
     *
     * This will zero out the midside node for conjugate problems
     * at the interface between material.
     * It needs to be fixed! -RRR
     *
     *  The field variable is zero where it is not defined
     */

    for (i = 0; i < num_local_nodes; i++) {
      I = Proc_Elem_Connect[iconnect_ptr + i];
      iDof = 0;
      /*
       * HKM -> Special compatibility section
       */
#ifdef DEBUG_HKM
      interpType = pd_glob[mn]->i[var_no];
      nunks = node_info(i, ielem_type, var_no, I);
      if (nunks > 1) {
	if (interpType == I_P0 || interpType == I_P1) {
	} else {
	  if (((exo->eb_id[eb_index] + 1) % 2) == 0) {
	    iDof = 0;
	  } else {
	    iDof = 1;
	  }
	}
      }
#endif
      if (lastSpeciesSum) {
	index = Index_Solution(I, var_no, 0, iDof, matIndex);
	if (index != -1) {
	  nodal_vec[I] = 0.0;
	  for (j = 0; j < matrl->Num_Species_Eqn; j++) {
	    index = Index_Solution(I, var_no, j, iDof, matIndex);
	    nodal_vec[I] -= sol_vec[index];
	  }
	  switch (matrl->Species_Var_Type) {
	  case SPECIES_CONCENTRATION:
	      if (matrl->DensityModel == DENSITY_CONSTANT_LAST_CONC) {
		nodal_vec[I] = matrl->u_density[0];
	      } else {
		rho = calc_concentration(matrl, FALSE, NULL);
		nodal_vec[I] += rho;
	      }
	      break;
	  case SPECIES_DENSITY:
	      rho = calc_density(matrl, FALSE, NULL, time);
	      nodal_vec[I] += rho;
	      break;
	  default:
	      if (!timeDerivative) {
		nodal_vec[I] += 1.0;
	      }
	      break;
	  }
	}
      } else {
	index = Index_Solution(I, var_no, ktype, iDof, matIndex);
	if (index != -1) {
	  nodal_vec[I] = sol_vec[index];
	} 
      }
    }

    /*
     * Rich's famous patch up for lesserly interpolated variables.
     * Promote quadrilateral Q1 variables to Q2 status, 8 node serendipity
     * at least, and 9-node biquadratic at best.
     */
    /* RRR notes a problem here in 3D. 
     *     Should add check for TRIQUAD_QUAD elem type */

    midside = 0;  
    if (((pd->i[var_no] == I_Q1)   ||
         (pd->i[var_no] == I_Q1_G)   ||
	 (pd->i[var_no] == I_Q1_GP)   ||
	 (pd->i[var_no] == I_Q1_GN)   ||
         (pd->i[var_no] == I_Q1_XV)   ||
         (pd->i[var_no] == I_Q1_XG)   ||
         (pd->i[var_no] == I_Q1_HV)   ||
         (pd->i[var_no] == I_Q1_HG)   ||
         (pd->i[var_no] == I_Q1_HVG)   ||
	 (pd->i[var_no] == I_Q1_D) ||
	 (pd->i[var_no] == I_SP)      )
	&& ((ielem_type == S_BIQUAD_QUAD)  ||
	    (ielem_type == BIQUAD_QUAD)         )) {
      midside = 1;
    }
  
    if (midside) {
      /* now interpolate Q1 variables onto 9-node mesh if needed */
      for (i = 4; i < 8; i++) {
	I = Proc_Elem_Connect[iconnect_ptr + i]; 
	/* 
	 * Double check to insure there really are no dofs here.
	 */
	if (Index_Solution(I, var_no, ktype, 0, matIndex) == -1) {
	  /* 
	   * make node lie halfway between adjacent nodes 
	   * cf. PATRAN local numbering scheme for element.
	   */
	  ileft = i - 4;
	  Ileft = Proc_Elem_Connect[iconnect_ptr + ileft];
	  iright = i - 3;
	  if (iright == 4) iright = 0;
	  Iright = Proc_Elem_Connect[iconnect_ptr + iright];
	  nodal_vec[I] = 
	      0.5 * (nodal_vec[Ileft] + nodal_vec[Iright]);
#if 0
          if ((pd->i[var_no] == I_Q1_HV)   ||
              (pd->i[var_no] == I_Q1_HG)   ||
              (pd->i[var_no] == I_Q1_HVG)) nodal_vec[I] = -1.;
#endif
	}
      }
      /*
       *  Only interpolate centroid in  BIQUAD_QUAD
       */
      if (ielem_type == BIQUAD_QUAD) {
	I = Proc_Elem_Connect[iconnect_ptr + 8];
	nodal_vec[I] = 0.0; 
	if ( (Index_Solution(I, var_no, ktype, 0, matIndex) == -1) ||
             /* for P0 jumps, overwrite jump with interpolant */
             (pd->i[var_no] == I_Q1_HV ||
              pd->i[var_no] == I_Q1_HG ||
              pd->i[var_no] == I_Q1_HVG) ) {
	  for (ileft = 0; ileft < 4; ileft++) {
	    Ileft = Proc_Elem_Connect[iconnect_ptr + ileft];
	    nodal_vec[I] += 0.25 * nodal_vec[Ileft];
	  }
#if 0
          if ((pd->i[var_no] == I_Q1_HV)   ||
              (pd->i[var_no] == I_Q1_HG)   ||
              (pd->i[var_no] == I_Q1_HVG)) nodal_vec[I] = -1.;
#endif
	}     
      }
    } /* END if (midside) */
  } /* END for (ielem = e_start; ielem < e_end; ielem++) */
  return;
}
Beispiel #4
0
void 
extract_elem_vec(const double sol_vec[],
		 const int    ev_indx,
		 const int    var_no,
		 double ***gvec_elem,
		 const Exo_DB *exo )
     
  /***************************************************
   *
   * This function puts the element values of the selected variable
   * into a global solution vector which contains all the elements,
   *
   * Now this is set up to be at least compatible w/ parallel computing.
   * We actually load the nodal vector for the current processor only.
   *
   *
   * Written by: Randy Lober  13 August 1998
   *
   * Revised: 
   *
   ***************************************************/
{
  int eb_index;
  int mn, e_start, e_end, ielem, ielem_type, num_local_nodes;
  int ielem_dim, iconnect_ptr, var, ktype, i, I, index;
  int found_quantity;

  for ( eb_index=0; eb_index < exo->num_elem_blocks; eb_index++ ) {

    mn = Matilda[eb_index];
    pd = pd_glob[mn];

    /* 
     * Not all element variables exist in all element blocks.
     * Thus, create_truth_table() didn't malloc all 
     * spots in gvec_elem. For those cases, just skip the 
     * calculation below
     */
    if (gvec_elem[eb_index][ev_indx] == NULL) {
      continue;
    }

    /* 
     * Assign local pointer pd to appropriate material
     */

    e_start = exo->eb_ptr[eb_index];
    e_end   = exo->eb_ptr[eb_index+1];
      
    for (ielem = e_start; ielem < e_end; ielem++) {

      ielem_type      = Elem_Type(exo, ielem); /* func defd in el_geom.h */
      num_local_nodes = elem_info(NNODES, ielem_type);
      ielem_dim       = elem_info(NDIM, ielem_type);
      iconnect_ptr    = Proc_Connect_Ptr[ielem]; /* find ptr to beginning */
      /* of this element's */
      /* connectivity list */
      var   = var_no;
      ktype = 0;

      /* We're looking at a nodal quantity that should be defined at only 1 
	 node of this element (aka, the pressure value off the hanging center
	 node). If we find it at more than 1 node, we have a serious problem
	 so we're leaving. If we don't find any values, we set the element
	 value to 0. RRl */
      found_quantity = FALSE;
      /* Only do this for elements with a haning center node, otherwise the
	 extraction of the quantity can be ambiguous for non-regular grid models */
      if (ielem_type == BIQUAD_QUAD ||
	  ielem_type == TRIQUAD_HEX ||
	  ielem_type == C_BILINEAR_QUAD ||
	  ielem_type == C_TRILINEAR_HEX ) {
	for (i = 0; i < num_local_nodes; i++) {
	  I     = Proc_Elem_Connect[iconnect_ptr + i];
	  /* NOTE: here, the element variables (such as PRESSURE) are being
	     extracted from the solution vector coming off of the hanging
	     interior nodes, or a given specified node for such a quantity.
	     There should never be more than one of this quantity defined
	     per element, or we have a problem treating it as an element
	     variable. Hence the found_quantity check.                       */
	  index = Index_Solution(I, var, ktype, 0, mn);
	  if (index != -1) {
	    /* This should be the one node that has our value - set the element
	       value to this */
	    gvec_elem[eb_index][ev_indx][ielem - e_start] = sol_vec[index];
	    if (found_quantity == TRUE) {
	      fprintf(stderr,
		      "Warning: Too many nodes returning quantities for element variable %s (%s) - may not be accurate\n",
		      Exo_Var_Names[var].name2,
		      Exo_Var_Names[var].name1 );
	      exit (-1);
	    }
	    found_quantity = TRUE;
	  }
	}
      }
      if (found_quantity == FALSE) {
	gvec_elem[eb_index][ev_indx][ielem - e_start] = 0.;   
	/* Field variable is zero where it
	 * is not defined.                 */
      }
#ifdef RRLOBER
      if (found_quantity == FALSE) {
	printf(" No quantity found for variable %s (%s), element %d (%d)\n",
	       Exo_Var_Names[var].name2, Exo_Var_Names[var].name1,
	       ielem, ielem - e_start );
      }
#endif
    }
  }
  return;
}
Beispiel #5
0
void 
sum_total_stress(double sol_vec[],
		 int    var_no,
		 int    k,
		 double nodal_vec[],
		 Exo_DB *exo)

  /*********************************************************************
   *
   * This function gets the nodal stress values for each mode
   * and sums them into a total stress tensor which contains all the
   * mesh nodes, and interpolates the mid-side and centroid values of 
   * all variables with Q1 interpolation on a
   * 9-NODE mesh and interpolates to find their values at the mid-side
   * nodes and at the centroid
   *
   * Now this is set up to be at least compatible w/ parallel computing.
   * We actually load the nodal vector for the current processor only.
   *
   ********************************************************************/
{
  int eb_index;
  int mn, e_start, e_end, ielem, ielem_type, ip_total, num_local_nodes;
  int ielem_dim, iconnect_ptr, var, ktype, i, I, index, ileft, Ileft;

  int iright, Iright;
  int mode;
  
  for (eb_index=0; eb_index<exo->num_elem_blocks; eb_index++)
    {
      mn = Matilda[eb_index];
      pd = pd_glob[mn];
      vn  = vn_glob[mn];

      /* 
       * Assign local pointer pd to appropriate material
       */
      e_start = exo->eb_ptr[eb_index];
      e_end   = exo->eb_ptr[eb_index+1];
      
      for( ielem = e_start; ielem < e_end; ielem++)
	{
	  ielem_type      = Elem_Type(exo, ielem); 
	  ip_total        = elem_info(NQUAD, ielem_type);
	                     /* number of quadrature points */
	  num_local_nodes = elem_info(NNODES, ielem_type);
                             /* number of local  basis functions */
    
	  ielem_dim       = elem_info(NDIM, ielem_type);
	  iconnect_ptr    = Proc_Connect_Ptr[ielem];
	                     /* find ptr to beginning of this element's */
     			     /* connectivity list */
	  ktype = k;

	  /* 
	   * First, place the known nodal variable values for this
	   * particular variable and type into the nodal vector.
	   */
	  /* This will zero out the midside node for conjugate problems
	   * at the interface between material.
	   * It needs to be fixed! -RRR
	   */

	  for (i=0; i<num_local_nodes; i++)
	    {
	      I     = Proc_Elem_Connect[iconnect_ptr + i];
	      if(Num_Var_In_Type[var_no])
		{
		  index = Index_Solution(I, var_no, ktype, 0, mn);
		  if (index != -1)
		    {
		      nodal_vec[I] = sol_vec[index];
		      /* BEWARE: this routine depends upon the exact
		       * ordering in re_fem_const.h. Don't change
		       * it or bad things will happen!
		       */
		      var = var_no + 24;
		      for ( mode=1; mode<vn->modes; mode++)
			{
			  index = Index_Solution(I, var, ktype, 0, mn);
			  nodal_vec[I] += sol_vec[index];
			  var += 6;
			}
		    }
		  else
		    {
		      /* Field variable is zero where it is not defined. */
		      nodal_vec[I] = 0.;       
		    }
		}
	    }

	  /*
	   * Rich's famous patch up for lesserly interpolated variables.
	   * Promote quadrilateral Q1 variables to Q2 status, 8 node serendipity
	   * at least, and 9-node biquadratic at best.
	   */

	  /* RRR notes a problem here in 3D.  Should add
	   * check for TRIQUAD_QUAD elem type
	   */

	  if ( pd->v[var_no] &&
	       ( pd->i[var_no] == I_Q1 ||
                 pd->i[var_no] == I_Q1_G ||
		 pd->i[var_no] == I_Q1_GP ||
		 pd->i[var_no] == I_Q1_GN ||
                 pd->i[var_no] == I_Q1_XV ||
                 pd->i[var_no] == I_Q1_XG ||
                 pd->i[var_no] == I_Q1_HV ||
                 pd->i[var_no] == I_Q1_HG ||
                 pd->i[var_no] == I_Q1_HVG ||
                 pd->i[var_no] == I_SP) && 
	       (ielem_type ==  S_BIQUAD_QUAD || ielem_type == BIQUAD_QUAD ))
	    {
	      /* now interpolate Q1 variables onto 9-node mesh if needed */
	      for (i=4; i<8; i++)
		{
		  I = Proc_Elem_Connect[iconnect_ptr + i]; 
		  /* 
		   * Double check to insure there really are no dofs here.
		   */
		  if (Index_Solution(I,var_no,ktype, 0, mn) == -1)
		    {
		      /* 
		       * make node lie halfway between adjacent nodes 
		       * cf. PATRAN local numbering scheme for element.
		       */
		      ileft = i - 4;
		      Ileft = Proc_Elem_Connect[iconnect_ptr + ileft];
		      iright = i - 3;
		      if (iright == 4) iright = 0;
		      Iright = Proc_Elem_Connect[iconnect_ptr + iright];
		      nodal_vec[I] = 
			0.5 * (sol_vec[Index_Solution(Ileft, var_no, ktype, 0, mn)] +
			       sol_vec[Index_Solution(Iright, var_no, ktype, 0, mn)]);
		      var = var_no + 24;
		      for ( mode=1; mode<vn->modes; mode++)
			{
			  nodal_vec[I] += 
			    0.5 * (sol_vec[Index_Solution(Ileft, var, ktype, 0, mn)] +
				   sol_vec[Index_Solution(Iright, var, ktype, 0, mn)]);
			  var += 6;
			}
		    }
                  /*
		   * only interpolate centroid in BIQUAD_QUAD
                   */		  
		  if (ielem_type == BIQUAD_QUAD) 
		    {
		      /*
		       *  put centroid in center
		       *  but only if there are no dofs here
		       */
		      I = Proc_Elem_Connect[iconnect_ptr + 8];
        nodal_vec[I] = 0.;
		      if (Index_Solution(I, var_no, ktype, 0, mn) == -1)
			{
     for (ileft=0; ileft<4; ileft++)
			    {
			      Ileft = Proc_Elem_Connect[iconnect_ptr + ileft];
			      nodal_vec[I] += 0.25 * 
				sol_vec[Index_Solution(Ileft, var_no, ktype, 0, mn)];
			      var = var_no + 24;
			      for ( mode=1; mode<vn->modes; mode++)
				{
				  nodal_vec[I] += 0.25 * 
			 	    sol_vec[Index_Solution(Ileft, var, ktype, 0, mn)];
				  var += 6;
				}

			    }
			}
		    }
		}
	    }
	}
    }
  return;
} /* end of sum_total_stress */