Beispiel #1
0
void
initialize_goma_export_vars_ ( int *nnodes,
				int *nelems,
				int *nnv_in,
				int *nev_in,
				int *nnod_r,
				int *i_soln,
				double *xnv_in,
				double *xev_in,
				double *xsoln )
{

  double *x;

  int ev;
  int I;
  int ie;
  int offset;

  asdv(&x, NumUnknowns);

  init_vec(x, cx, EXO_ptr, DPI_ptr, NULL, 0);

  /* 
   * Goma export variables.  may be read from material files or from preexisting exodus file
   */


  for( ev=0; ev< *i_soln; ev++)
    {
      offset = *nnod_r*ev;
      for( I=0; I< *nnod_r; I++ )
	{
	  ie = Index_Solution( I,Export_XS_ID[ev], 0, 0, -1);

	  if( ie != -1 ) xsoln[offset+I] = x[ie];
	}
    }

  safer_free( (void **) &x );
  return;
} 
Beispiel #2
0
void output_stability_matrices(double *mass_matrix,
			       double *jacobian_matrix,
			       int *ija,
			       int num_total_nodes,
			       int NumUnknowns,
			       int NZeros)
{
  static int fake = 0;

  int i, j, k, num_B_nonzeros, num_J_nonzeros;
  FILE *mass_file, *jacobian_file, *vars_file;
  char LSA_mass_output_filename[256],
    LSA_jacobian_output_filename[256],
    LSA_vars_output_filename[256]; 

  /* Get the filenames.  These will be different if we're doing a
   * normal mode analysis for 3D stability of a 2D flow. */
  if(LSA_3D_of_2D_wave_number == -1.0)
    {
      sprintf(LSA_mass_output_filename, "LSA_mass_coo.out");
      sprintf(LSA_jacobian_output_filename, "LSA_jac_coo.out");
      sprintf(LSA_vars_output_filename, "LSA_vars.out");
    }
  else
    {
      sprintf(LSA_mass_output_filename, "LSA_mass_coo-%g.out",
	      (double)fake);
      sprintf(LSA_jacobian_output_filename, "LSA_jac_coo-%g.out",
	      (double)fake);
      sprintf(LSA_vars_output_filename, "LSA_vars-%g.out",
	      (double)fake++);
    }

/* Multiplex output names in parallel */
  if (Num_Proc > 1)
    {
      multiname(LSA_mass_output_filename, ProcID, Num_Proc);
      multiname(LSA_jacobian_output_filename, ProcID, Num_Proc);
      multiname(LSA_vars_output_filename, ProcID, Num_Proc);
    }

  printf("Writing matrix files (%s, %s, %s)...",
	 LSA_mass_output_filename,
	 LSA_jacobian_output_filename,
	 LSA_vars_output_filename);
  fflush(stdout);

  /* First, count out how many actual nonzeros there are.  This will
   * reduce filesizes substantially (especially for the mass
   * matrix.
   */
  num_J_nonzeros = 0;
  num_B_nonzeros = 0;
  for (i=0; i<NumUnknowns; i++)
    {
      if(fabs(jacobian_matrix[i]) > LSA_MATRIX_OUTPUT_TOLERANCE) num_J_nonzeros++;
      if(fabs(mass_matrix[i]) > LSA_MATRIX_OUTPUT_TOLERANCE) num_B_nonzeros++;
      for (j=ija[i]; j<ija[i+1]; j++)
	{
	  if(fabs(jacobian_matrix[j]) > LSA_MATRIX_OUTPUT_TOLERANCE) num_J_nonzeros++;
	  if(fabs(mass_matrix[j]) > LSA_MATRIX_OUTPUT_TOLERANCE) num_B_nonzeros++;
	}
    }

  mass_file = fopen(LSA_mass_output_filename, "w");
  if(!mass_file)
    EH(-1, "Could not open mass matrix output file.");
  jacobian_file = fopen(LSA_jacobian_output_filename, "w");
  if(!jacobian_file)
    EH(-1, "Could not open jacobian matrix output file.");
  
  /* Print out header line containing #rows, #nonzeros.
   */
  fprintf(jacobian_file, "%12d\n%12d\n", num_J_nonzeros, NumUnknowns);
  fprintf(mass_file, "%12d\n%12d\n", num_B_nonzeros, NumUnknowns);

  k = 0;
  for (i=0; i<NumUnknowns; i++)
    {
      if(fabs(mass_matrix[i]) > LSA_MATRIX_OUTPUT_TOLERANCE)
	fprintf(mass_file, " %5d %5d % 17.14e\n", i, i, mass_matrix[i]);
      if(fabs(jacobian_matrix[i]) > LSA_MATRIX_OUTPUT_TOLERANCE)
	fprintf(jacobian_file, " %5d %5d % 17.14e\n", i, i, jacobian_matrix[i]);
      k++;
      for (j=ija[i]; j<ija[i+1]; j++)
	{
	  if(fabs(mass_matrix[j]) > LSA_MATRIX_OUTPUT_TOLERANCE)
	    fprintf(mass_file, " %5d %5d % 17.14e\n", i, ija[j], mass_matrix[j]);
	  if(fabs(jacobian_matrix[j]) > LSA_MATRIX_OUTPUT_TOLERANCE)
	    fprintf(jacobian_file, " %5d %5d % 17.14e\n", i, ija[j], jacobian_matrix[j]);
	  k++;
	}
    }
  fclose(mass_file);
  fclose(jacobian_file);

  /* MMH Find out which components of the solution vector correspond
   * to which unknowns.  I know there's a better way to do this, but
   * I just don't know what it is.  Oh well...
   */
  vars_file = fopen(LSA_vars_output_filename, "w");
  if(!vars_file)
    EH(-1, "Could not open variable listing output file.");
  for(i = 0; i < num_total_nodes; i++)
    {
      if( (j = Index_Solution(i, VELOCITY1, 0, 0, -1)) > -1 )
	fprintf(vars_file, "u %d\n", j);
      if( (j = Index_Solution(i, VELOCITY2, 0, 0, -1)) > -1 )
	fprintf(vars_file, "v %d\n", j);
      if( (j = Index_Solution(i, VELOCITY3, 0, 0, -1)) > -1 )
	fprintf(vars_file, "w %d\n", j);
      if( (j = Index_Solution(i, MESH_DISPLACEMENT1, 0, 0, -1)) > -1 )
	fprintf(vars_file, "x %d\n", j);
      if( (j = Index_Solution(i, MESH_DISPLACEMENT2, 0, 0, -1)) > -1 )
	fprintf(vars_file, "y %d\n", j);
      if( (j = Index_Solution(i, PRESSURE, 0, 0, -1)) > -1 )
	fprintf(vars_file, "p %d\n", j);
      if( (j = Index_Solution(i, PRESSURE, 0, 1, -1)) > -1 )
	fprintf(vars_file, "p %d\n", j);
      if( (j = Index_Solution(i, PRESSURE, 0, 2, -1)) > -1 )
	fprintf(vars_file, "p %d\n", j);
    }
  fclose(vars_file);

  puts("done.");
  printf("LSA (in) nnz = %d\n   (out) nnz = %d\n (out) J_nnz = %d\n (out) B_nnz = %d\n\n",
	 NZeros, k, num_J_nonzeros, num_B_nonzeros);
  fflush(stdout);
}
Beispiel #3
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 #4
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 #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 */
Beispiel #6
0
int
ns_data_print(pp_Data * p, 
	      double x[], 
	      const Exo_DB * exo, 
	      const double time_value,
	      const double time_step_size)
{
  const int quantity       = p->data_type;
  int mat_num        = p->mat_num;
  const int elemBlock_id   = p->elem_blk_id;
  const int node_set_id    = p->ns_id;
  const int species_id     = p->species_number;
  const char * filenm      = p->data_filenm;
  const char * qtity_str   = p->data_type_name;
  const char * format_flag = p->format_flag;
  int * first_time         = &(p->first_time);

  static int err=0;
  int num_nodes_on_side;
  int ebIndex_first = -1;
  int local_side[2];
  int side_nodes[3];		/* Assume quad has no more than 3 per side. */
  int elem_list[4], elem_ct=0, face, ielem, node2;
  int local_node[4];
  int node = -1;
  int idx, idy, idz, id_var;
  int iprint;
  int nsp;			/* node set pointer for this node set */
  dbl x_pos, y_pos, z_pos;
  int j, wspec;
  int doPressure = 0;

#ifdef PARALLEL
  double some_time=0.0;
#endif
  double abscissa=0;
  double ordinate=0;
  double n1[3], n2[3];
  double xi[3];

  /*
   * Find an element block that has the desired material id.
   */
  if (elemBlock_id != -1) {
    for (j = 0; j < exo->num_elem_blocks; j++) {
      if (elemBlock_id == exo->eb_id[j]) {
	ebIndex_first = j;
	break;
      }
    }
    if (ebIndex_first == -1) {
      sprintf(err_msg, "Can't find an element block with the elem Block id %d\n", elemBlock_id);
    if (Num_Proc == 1) {
      EH(-1, err_msg);
    }
    }
    mat_num = Matilda[ebIndex_first];
    p->mat_num = mat_num;
    pd = pd_glob[mat_num];
  } else {
    mat_num = -1;
    p->mat_num = -1;
    pd = pd_glob[0];
  }

  nsp = match_nsid(node_set_id);  

  if( nsp != -1 )
    {
      node = Proc_NS_List[Proc_NS_Pointers[nsp]];
    }
  else
    {
      sprintf(err_msg, "Node set ID %d not found.", node_set_id);
      if( Num_Proc == 1 ) EH(-1,err_msg);
    }

  /* first right time stamp or run stamp to separate the sets */

  print_sync_start(FALSE);

  if (*first_time)
    {
      if ( format_flag[0] != '\0' ) 
	{
	  if (ProcID == 0)
	    {
	      uf = fopen(filenm,"a");
	      if (uf != NULL)
		{
		  fprintf(uf,"# %s %s @ nsid %d node (%d) \n", 
			  format_flag, qtity_str, node_set_id, node );
		  *first_time = FALSE;
		  fclose(uf);
		}
	    }
	}
    }

  if (format_flag[0] == '\0')
    {
      if (ProcID == 0)
	{
	  if ((uf = fopen(filenm,"a")) != NULL)
	    {
	      fprintf(uf,"Time/iteration = %e \n", time_value);
	      fprintf(uf,"  %s   Node_Set  %d Species %d\n", qtity_str,node_set_id,species_id);
	      fflush(uf);
	      fclose(uf);
	    }
	}
    }

  if (nsp != -1 ) {

    for (j = 0; j < Proc_NS_Count[nsp]; j++) {
      node = Proc_NS_List[Proc_NS_Pointers[nsp]+j];
      if (node < num_internal_dofs + num_boundary_dofs ) {
        idx = Index_Solution(node, MESH_DISPLACEMENT1, 0, 0, -1);
        if (idx == -1) {
          x_pos = Coor[0][node];
          WH(idx, "Mesh variable not found.  May get undeformed coords.");
        } else {
          x_pos = Coor[0][node] + x[idx];
        }
        idy = Index_Solution(node, MESH_DISPLACEMENT2, 0, 0, -1);
        if (idy == -1) {
          y_pos = Coor[1][node];
        } else {
          y_pos = Coor[1][node] + x[idy];
        }
        z_pos = 0.;
        if(pd->Num_Dim == 3) {
          idz = Index_Solution(node, MESH_DISPLACEMENT3, 0, 0, -1);
          if (idz == -1) {
	    z_pos = Coor[2][node];
          }  else{
	    z_pos = Coor[2][node] + x[idz];
          }
        }
        if (quantity == MASS_FRACTION) {
          id_var = Index_Solution(node, quantity, species_id, 0, mat_num);
        } else if (quantity < 0) {
          id_var = -1;
        } else {
          id_var = Index_Solution(node, quantity, 0, 0, mat_num);
        }

	/*
	 * In the easy case, the variable can be found somewhere in the
	 * big vector of unknowns. But sometimes we want a derived quantity
	 * that requires a little more work than an array reference.
	 *
	 * For now, save the good result if we have it.
	 */

	if ( id_var != -1 )
	  {
	    ordinate = x[id_var];
	    iprint = 1;
	  }
	else
	  {
	    /*
	     *  If we have an element based interpolation, let's calculate the interpolated value
	     */
	    if (quantity == PRESSURE) {
	      if ((pd->i[PRESSURE] == I_P1) || ( (pd->i[PRESSURE] > I_PQ1) && (pd->i[PRESSURE] < I_Q2_HVG) )) {
		doPressure = 1;
	      }
	    }
	    iprint = 0;
	  }

	/*
	 * If the quantity is "theta", an interior angle that only
	 * makes sense at a point, in 2D, we'll need to compute it.
	 */

	if ( strncasecmp(qtity_str, "theta", 5 ) == 0 || doPressure)
	  {
	    /*
	     * Look for the two sides connected to this node...?
	     *
	     * Premise:
	     *	1. The node appears in only one element(removed-RBS,6/14/06)
	     *          2. Exactly two sides emanate from the node.
	     *          3. Quadrilateral.
	     *
	     * Apologies to people who wish to relax premise 1. I know
	     * there are some obtuse angles out there that benefit from
	     * having more than one element at a vertex. With care, this
	     * procedure could be extended to cover that case as well.
	     */
	    
	    if ( ! exo->node_elem_conn_exists )
	      {
		EH(-1, "Cannot compute angle without node_elem_conn.");
	      }
	    
	    elem_list[0] = exo->node_elem_list[exo->node_elem_pntr[node]];

	    /*
	     * Find out where this node appears in the elements local
	     * node ordering scheme...
	     */

	    local_node[0] = in_list(node, exo->elem_node_pntr[elem_list[0]], 
				    exo->elem_node_pntr[elem_list[0]+1],
				    exo->elem_node_list);

	    EH(local_node[0], "Can not find node in elem node connectivity!?! ");
	    local_node[0] -= exo->elem_node_pntr[elem_list[0]];
	    /* check for neighbors*/
	    if( mat_num == find_mat_number(elem_list[0], exo))
	      {elem_ct = 1;}
	    else
	      {WH(-1,"block id doesn't match first element");}
	    for (face=0 ; face<ei->num_sides ; face++)
	      {
		ielem = exo->elem_elem_list[exo->elem_elem_pntr[elem_list[0]]+face];
		if (ielem != -1)
		  {
		    node2 = in_list(node, exo->elem_node_pntr[ielem], 
				    exo->elem_node_pntr[ielem+1],
				    exo->elem_node_list);
		    if (node2 != -1 && (mat_num == find_mat_number(ielem, exo)))
		      {
			elem_list[elem_ct] = ielem;
			local_node[elem_ct] = node2;
			local_node[elem_ct] -= exo->elem_node_pntr[ielem];
			elem_ct++;
		      }
		  }
	      }

	    /*
	     * Note that indeces are zero based!
	     */

	    ordinate = 0.0;
	    for (ielem = 0 ; ielem < elem_ct ; ielem++)
	      {
		if ( local_node[ielem] < 0 || local_node[ielem] > 3 ) 
		  {
		    if (strncasecmp(qtity_str, "theta", 5 ) == 0) {
		      EH(-1, "Node out of bounds.");
		    }
		  }

		/*
		 * Now, determine the local name of the sides adjacent to this
		 * node...this works for the exo patran convention for quads...
		 *
		 * Again, local_node and local_side are zero based...
		 */

		local_side[0] = (local_node[ielem]+3)%4;
		local_side[1] = local_node[ielem];

		/*
		 * With the side names, we can find the normal vector.
		 * Again, assume the sides live on the same element.
		 */
		load_ei(elem_list[ielem], exo, 0);

		/*
		 * We abuse the argument list under the conditions that
		 * we're going to do read-only operations and that
		 * we're not interested in old time steps, time derivatives
		 * etc.
		 */
		if (x == x_static) /* be the least disruptive possible */
		  {
		    err = load_elem_dofptr(elem_list[ielem], exo, x_static, x_old_static,
					   xdot_static, xdot_old_static, x_static, 1);
		  }
		else
		  {
		    err = load_elem_dofptr(elem_list[ielem], exo, x, x, x, x, x, 1);
		  }

		/*
		 * What are the local coordinates of the nodes in a quadrilateral?
		 */

		find_nodal_stu(local_node[ielem], ei->ielem_type, xi, xi+1, xi+2);

		err = load_basis_functions(xi, bfd);

		EH( err, "problem from load_basis_functions");
	    
		err = beer_belly();
		EH( err, "beer_belly");
	    
		err = load_fv();
		EH( err, "load_fv");
	    
		err = load_bf_grad();
		EH( err, "load_bf_grad");

		err = load_bf_mesh_derivs(); 
		EH(err, "load_bf_mesh_derivs");
		
		if (doPressure) {
		  ordinate = fv->P;
		  iprint = 1;
		} else {

		/* First, one side... */

		get_side_info(ei->ielem_type, local_side[0]+1, &num_nodes_on_side, 
			      side_nodes);

		surface_determinant_and_normal(elem_list[ielem], 
					       exo->elem_node_pntr[elem_list[ielem]],
					       ei->num_local_nodes,  
					       ei->ielem_dim-1, 
					       local_side[0]+1, 
					       num_nodes_on_side,
					       side_nodes);

		n1[0] = fv->snormal[0];
		n1[1] = fv->snormal[1];

		/* Second, the adjacent side of the quad... */

		get_side_info(ei->ielem_type, local_side[1]+1, &num_nodes_on_side, 
			      side_nodes);

		surface_determinant_and_normal(elem_list[ielem], 
					       exo->elem_node_pntr[elem_list[ielem]],
					       ei->num_local_nodes,  
					       ei->ielem_dim-1, 
					       local_side[1]+1, 
					       num_nodes_on_side,
					       side_nodes);

		n2[0] = fv->snormal[0];
		n2[1] = fv->snormal[1];

		/* cos (theta) = n1.n2 / ||n1|| ||n2|| */

		ordinate += 180. - (180./M_PI)*acos((n1[0]*n2[0] + n1[1]*n2[1])/
						    (sqrt(n1[0]*n1[0]+n1[1]*n1[1])*
						     sqrt(n2[0]*n2[0]+n2[1]*n2[1])));
		}
		iprint = 1;
	      }	/*ielem loop	*/
	  }
	else if ( strncasecmp(qtity_str, "timestepsize", 12 ) == 0 )
	  {
	    ordinate = time_step_size;
	    iprint = 1;
	  }
	else if ( strncasecmp(qtity_str, "cputime", 7 ) == 0 )
	  {
	    ordinate = ut();
	    iprint = 1;
	  }
	else if ( strncasecmp(qtity_str, "wallclocktime", 13 ) == 0 )
	  {
	    /* Get these from extern via main...*/
#ifdef PARALLEL
	    some_time = MPI_Wtime();
	    ordinate = some_time - time_goma_started;
#endif
#ifndef PARALLEL
            time_t now=0;
	    (void)time(&now);
	    ordinate = (double)(now) - time_goma_started;
#endif
	    iprint = 1;
	  }
	else if ( strncasecmp(qtity_str, "speed", 5 ) == 0 )
	  {
            id_var = Index_Solution(node, VELOCITY1, 0, 0, mat_num);
	    ordinate = SQUARE(x[id_var]);
            id_var = Index_Solution(node, VELOCITY2, 0, 0, mat_num);
	    ordinate += SQUARE(x[id_var]);
            id_var = Index_Solution(node, VELOCITY3, 0, 0, mat_num);
	    ordinate += SQUARE(x[id_var]);
	    ordinate = sqrt(ordinate);
	    iprint = 1;
	  }
        else if ( strncasecmp(qtity_str, "ac_pres", 7 ) == 0 )
          {
            id_var = Index_Solution(node, ACOUS_PREAL, 0, 0, mat_num);
            ordinate = SQUARE(x[id_var]);
            id_var = Index_Solution(node, ACOUS_PIMAG, 0, 0, mat_num);
            ordinate += SQUARE(x[id_var]);
            ordinate = sqrt(ordinate);
            iprint = 1;
          }
        else if ( strncasecmp(qtity_str, "light_comp", 10 ) == 0 )
          {
            id_var = Index_Solution(node, LIGHT_INTP, 0, 0, mat_num);
            ordinate = x[id_var];
            id_var = Index_Solution(node, LIGHT_INTM, 0, 0, mat_num);
            ordinate += x[id_var];
            iprint = 1;
          }
        else if ( strncasecmp(qtity_str, "nonvolatile", 11 ) == 0 )
          {
            ordinate = 1.0;
	    for(wspec = 0 ; wspec < pd->Num_Species_Eqn ; wspec++)
		{
            	id_var = Index_Solution(node, MASS_FRACTION, wspec, 0, mat_num);
            	ordinate -= x[id_var]*mp_glob[mat_num]->molar_volume[wspec];
		}
            iprint = 1;
          }
	else
	  {
	    WH(id_var,
	       "Requested print variable is not defined at all nodes. May get 0.");
	    if(id_var == -1) iprint = 0;
	  }

        if ((uf=fopen(filenm,"a")) != NULL)
	  {
	    if ( format_flag[0] == '\0' )
	      {
		if (iprint)
		  {
		    fprintf(uf,"  %e %e %e %e \n", x_pos, y_pos, z_pos, ordinate);
		  }
	      }
	    else
	      {
		if ( strncasecmp(format_flag, "t", 1) == 0 )
		  {
		    abscissa = time_value;
		  }
		else if (  strncasecmp(format_flag, "x", 1) == 0 )
		  {
		    abscissa = x_pos;		      
		  }
		else if (  strncasecmp(format_flag, "y", 1) == 0 )
		  {
		    abscissa = y_pos;		      
		  }
		else if (  strncasecmp(format_flag, "z", 1) == 0 )
		  {
		    abscissa = z_pos;		      
		  }
		else
		  {
		    abscissa = 0;
		  }
		if (iprint)
		  {
		    fprintf(uf, "%.16g\t%.16g\n", abscissa, ordinate);
		  }
	      }
	    fclose(uf);
	  }
      }
    }
  }
  print_sync_end(FALSE);

  return(1);
} /* END of routine ns_data_print */
Beispiel #7
0
int
ns_data_sens_print(const struct Post_Processing_Data_Sens *p,
		   const double x[], /* solution vector */
		   double **x_sens,  /* solution sensitivity vector */
		   const double time_value) /* current time */
{
  const int node_set_id = p->ns_id;
  const int quantity    = p->data_type;
  const int mat_id      = p->mat_id;
  const int species_id  = p->species_number;
  const int sens_type   = p->sens_type;
  const int sens_id     = p->sens_id;
  const int sens_flt    = p->sens_flt;
  const int sens_flt2   = p->sens_flt2;
  const char *filenm    = p->data_filenm;
  const char *qtity_str = p->data_type_name;
  const int sens_ct     = p->vector_id;

  int node;
  int idx, idy, idz, id_var;
  int nsp;                      /* node set pointer for this node set */
  dbl x_pos, y_pos, z_pos;
  int j;

  nsp            = match_nsid(node_set_id);
  if( nsp != -1 ) {
     node           = Proc_NS_List[Proc_NS_Pointers[nsp]];
  }
  else
  {
    sprintf(err_msg, "Node set ID %d not found.", node_set_id);
    if( Num_Proc == 1 ) EH(-1,err_msg);
  }

  /* first right time stamp or run stamp to separate the sets */

  print_sync_start(TRUE);

  if (ProcID == 0 && (uf=fopen(filenm,"a")) != NULL)
    {
      fprintf(uf,"Time/iteration = %e \n", time_value);
      fprintf(uf,"  %s   Node_Set  %d \n", qtity_str,node_set_id);
	if(sens_type == 1)
	{
      fprintf(uf,"Sensitivity_type BC  ID  %d  Float  %d\n",sens_id,sens_flt);
	}
	else
	if(sens_type == 2)
	{
      fprintf(uf,"Sensitivity_type MT  NO  %d  Prop.  %d\n",sens_id,sens_flt);
	}
	else
	if(sens_type == 3)
	{
      fprintf(uf,"Sensitivity_type AC  ID  %d  Float  %d\n",sens_id,sens_flt);
	}
	else
	if(sens_type == 4)
	{
      fprintf(uf,"Sensitivity_type UM  NO  %d  Prop.  %d %d\n",sens_id,sens_flt,sens_flt2);
	}
	else
	if(sens_type == 5)
	{
      fprintf(uf,"Sensitivity_type UF  ID  %d  Float  %d\n",sens_id,sens_flt);
	}
	else
	if(sens_type == 6)
	{
      fprintf(uf,"Sensitivity_type AN  ID  %d  Float  %d\n",sens_id,sens_flt);
	}
      fflush(uf);
      fclose(uf);
    }

  if( nsp != -1 ) {

    for (j = 0; j < Proc_NS_Count[nsp]; j++) {
      node = Proc_NS_List[Proc_NS_Pointers[nsp]+j];
      if( node < num_internal_dofs + num_boundary_dofs ) {
        idx = Index_Solution (node, MESH_DISPLACEMENT1, 0, 0, -1);
        if (idx == -1) {
	  x_pos = Coor[0][node];
          WH(idx, "Mesh variable not found.  May get undeformed coords.");
        } else {
	  x_pos = Coor[0][node] + x[idx];
        }
        idy = Index_Solution (node, MESH_DISPLACEMENT2, 0, 0, -1);
        if (idy == -1) {
	  y_pos = Coor[1][node];
        } else {
	  y_pos = Coor[1][node] + x[idy];
        }
        z_pos = 0.;
        if (pd->Num_Dim == 3) {
	  idz = Index_Solution(node, MESH_DISPLACEMENT3, 0, 0, -1);
	  if (idz == -1) {
	    z_pos = Coor[2][node];
	  } else {
	    z_pos = Coor[2][node] + x[idz];
	  }
        }
        if(quantity == MASS_FRACTION) {
	  id_var = Index_Solution(node, quantity, species_id, 0, mat_id);
        } else {
	  id_var = Index_Solution(node, quantity, 0, 0, mat_id);
        }
        WH(id_var,
	   "Requested print variable is not defined at all nodes. May get 0.");

        if ((uf=fopen(filenm,"a")) != NULL) {
	  if (id_var != -1) {
	    fprintf(uf, "  %e %e %e %e \n",
		    x_pos, y_pos, z_pos, x_sens[sens_ct][id_var]);
	  }
	  fclose(uf);
        }
      }
    }
  }

  print_sync_end(TRUE);

  return(1);
} /* END of routine ns_data_sens_print */