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; }
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 */
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; }
/* * create_truth_table() -- Test each proposed element against each element * block for existance and populate the truth table. This saves file * rewrites later (a netcdf phenom) when each variable is written sequentially * later. * * Created: 1998/08/19 08:17 MDT [email protected] */ void create_truth_table(struct Results_Description *rd, Exo_DB *exo, double ***gvec_elem ) { char err_msg[MAX_CHAR_IN_INPUT], if_ev; int i, j, eb_indx, ev_indx, mat_num, error, check, iii; int tev, found_match, ip_total; ELEM_BLK_STRUCT *eb_ptr; static const char yo[] = "create_truth_table"; tev = 0; i = 0; exo->elem_var_tab = (int *) smalloc( (exo->num_elem_blocks*rd->nev)*sizeof(int)); exo->truth_table_existance_key = (int *) smalloc( (V_LAST - V_FIRST)*sizeof(int)); for ( i = 0; i < V_LAST - V_FIRST; i++ ) { exo->truth_table_existance_key[i] = 0; } /* This first cycle is a test to detect which potential elem variables (treated as nodal in goma) exist in which block via tests below on whether the variables have been requested at all by the user and if requested, are of the appropriate integration order for conversion to an elem var. This is necessary since the array of the truth table cycles through the element var index fastest, and if a given element var is defined for one block but not another, the block in which it is undefined will not know the difference between a defined variable that is of the wrong interpolation order for this block, and a variable that is not defined at all for the problem. This first cycle scopes for these cases and sets up a temp array of all possible elem vars model wide that must be treated (1 or 0) in the truth table. RRL */ if_ev = FALSE; for ( eb_indx = 0; eb_indx < exo->num_elem_blocks; eb_indx++ ) { /* First test for all the potential elem vars from primary nodal vars for this block */ mat_num = Matilda[eb_indx]; if (mat_num < 0) { continue; } for ( j = V_FIRST; j < V_LAST; j++) { if ( pd_glob[mat_num]->v[j] != V_NOTHING ) { if ( pd_glob[mat_num]->i[j] == I_P0 ) { if ( Num_Var_In_Type[j] > 1 ) { fprintf(stderr, "%s: Too many components in variable type for element variable %s (%s)\n", yo, Exo_Var_Names[j].name2, Exo_Var_Names[j].name1 ); exit (-1); } if ( exo->truth_table_existance_key[j - V_FIRST] == 0 ) { /* We just found a candidate for an element variable */ tev += Num_Var_In_Type[j]; exo->truth_table_existance_key[j - V_FIRST] = 1; } } } } /* Now pick up all the post processing variables for this block - yes, for now they must each be listed separately and painfully */ if (ERROR_ZZ_VEL != -1 && Num_Var_In_Type[R_MOMENTUM1]) { tev++; if (ERROR_ZZ_VEL_ELSIZE != -1) { tev++; } } if (ERROR_ZZ_Q != -1 && Num_Var_In_Type[R_ENERGY]) { tev++; if (ERROR_ZZ_Q_ELSIZE != -1) { tev++; } } check = 0; for ( i = 0; i < upd->Num_Mat; i++ ) { if( pd_glob[i]->MeshMotion == LAGRANGIAN || pd_glob[i]->MeshMotion == DYNAMIC_LAGRANGIAN) check = 1; } if (ERROR_ZZ_P != -1 && (Num_Var_In_Type[R_MOMENTUM1] || check)) { tev++; if (ERROR_ZZ_P_ELSIZE != -1) { tev++; } } /* Finally pick up all of the element-level-storage continuation * variables, e.g. for saturation hysteresis function */ mat_num = Matilda[eb_indx]; mp = mp_glob[mat_num]; eb_ptr = Element_Blocks + eb_indx; ip_total = elem_info(NQUAD, eb_ptr->Elem_Type); if((mp->PorousMediaType == POROUS_UNSATURATED || mp->PorousMediaType == POROUS_SHELL_UNSATURATED || mp->PorousMediaType == POROUS_TWO_PHASE) && mp->SaturationModel == TANH_HYST && !if_ev) { for ( j = 0; j < ip_total; j++) { if(SAT_CURVE_TYPE != -1) tev++; /*For Sat curve type */ if(CAP_PRESS_SWITCH != -1) tev++; /*For saturation switch */ if(SAT_QP_SWITCH != -1) tev++; /*for cap press switch point*/ } if_ev = TRUE; } } /* Sanity check */ if ( tev != rd->nev ) { sr = sprintf(err_msg, "%s: Elem var count mismatch: tev(%d)<>rd->nev(%d)!?", yo, tev, rd->nev); EH(-1, err_msg); /* fprintf(stderr, "%s: Disagreement over number of element variables\n", yo ); exit (-1); */ } /* Now do the real loop and populate the truth table */ i = 0; for ( eb_indx = 0; eb_indx < exo->num_elem_blocks; eb_indx++ ) { /* First test for all the potential elem vars from primary nodal vars for this block */ mat_num = Matilda[eb_indx]; ev_indx = 0; for ( j = V_FIRST; j < V_LAST; j++) { found_match = FALSE; if ( pd_glob[mat_num]->v[j] != V_NOTHING ) { if ( pd_glob[mat_num]->i[j] == I_P0 ) { if ( Num_Var_In_Type[j] > 1 ) { fprintf(stderr, "%s: Too many components in variable type for element variable %s (%s)\n", yo, Exo_Var_Names[j].name2, Exo_Var_Names[j].name1 ); exit (-1); } /* We just found a candidate for an element variable */ exo->elem_var_tab[i++] = 1; found_match = TRUE; ev_indx++; /* malloc the entry for this block by number of elems for this block but - only if the variable exists for this block! (by the truth table) */ if ( has_been_called == 0 ) { /* NOTE: this final array dim is only to be malloc'd once; when a user is annealing the mesh, anneal mesh calls wr_result_prelim_exo again, and hence create_truth_table, which would realloc this dim of gvec_elem. this test will prevent that. - RRL */ asdv ( &gvec_elem[eb_indx][ev_indx - 1], exo->eb_num_elems[eb_indx] ); } } } if ( found_match == FALSE && exo->truth_table_existance_key[j - V_FIRST] == 1 ) { exo->elem_var_tab[i++] = 0; ev_indx++; } } /* Now pick up all the post processing variables for this block - yes, for now they must each be listed separately and painfully */ if (ERROR_ZZ_VEL != -1 && Num_Var_In_Type[R_MOMENTUM1]) { exo->elem_var_tab[i++] = 1; ev_indx++; /* malloc the entry for this block by number of elems for this block but - only if the variable exists for this block! (by the truth table) */ if ( has_been_called == 0 ) { /* NOTE: this final array dim is only to be malloc'd once; when a user is annealing the mesh, anneal mesh calls wr_result_prelim_exo again, and hence create_truth_table, which would realloc this dim of gvec_elem. this test will prevent that. - RRL */ asdv ( &gvec_elem[eb_indx][ev_indx - 1], exo->eb_num_elems[eb_indx] ); } if (ERROR_ZZ_VEL_ELSIZE != -1) { exo->elem_var_tab[i++] = 1; ev_indx++; /* malloc the entry for this block by number of elems for this block but - only if the variable exists for this block! (by the truth table) */ if ( has_been_called == 0 ) { /* NOTE: this final array dim is only to be malloc'd once; when a user is annealing the mesh, anneal mesh calls wr_result_prelim_exo again, and hence create_truth_table, which would realloc this dim of gvec_elem. this test will prevent that. - RRL */ asdv ( &gvec_elem[eb_indx][ev_indx - 1], exo->eb_num_elems[eb_indx] ); } } } if (ERROR_ZZ_Q != -1 && Num_Var_In_Type[R_ENERGY]) { exo->elem_var_tab[i++] = 1; ev_indx++; /* malloc the entry for this block by number of elems for this block but - only if the variable exists for this block! (by the truth table) */ if ( has_been_called == 0 ) { /* NOTE: this final array dim is only to be malloc'd once; when a user is annealing the mesh, anneal mesh calls wr_result_prelim_exo again, and hence create_truth_table, which would realloc this dim of gvec_elem. this test will prevent that. - RRL */ asdv ( &gvec_elem[eb_indx][ev_indx - 1], exo->eb_num_elems[eb_indx] ); } if (ERROR_ZZ_Q_ELSIZE != -1) { exo->elem_var_tab[i++] = 1; ev_indx++; /* malloc the entry for this block by number of elems for this block but - only if the variable exists for this block! (by the truth table) */ if ( has_been_called == 0 ) { /* NOTE: this final array dim is only to be malloc'd once; when a user is annealing the mesh, anneal mesh calls wr_result_prelim_exo again, and hence create_truth_table, which would realloc this dim of gvec_elem. this test will prevent that. - RRL */ asdv ( &gvec_elem[eb_indx][ev_indx - 1], exo->eb_num_elems[eb_indx] ); } } } check = 0; for ( iii = 0; iii < upd->Num_Mat; iii++ ) { if( pd_glob[iii]->MeshMotion == LAGRANGIAN || pd_glob[iii]->MeshMotion == DYNAMIC_LAGRANGIAN) check = 1; } if (ERROR_ZZ_P != -1 && (Num_Var_In_Type[R_MOMENTUM1] || check)) { exo->elem_var_tab[i++] = 1; ev_indx++; /* malloc the entry for this block by number of elems for this block but - only if the variable exists for this block! (by the truth table) */ if ( has_been_called == 0 ) { /* NOTE: this final array dim is only to be malloc'd once; when a user is annealing the mesh, anneal mesh calls wr_result_prelim_exo again, and hence create_truth_table, which would realloc this dim of gvec_elem. this test will prevent that. - RRL */ asdv ( &gvec_elem[eb_indx][ev_indx - 1], exo->eb_num_elems[eb_indx] ); } if (ERROR_ZZ_P_ELSIZE != -1) { exo->elem_var_tab[i++] = 1; ev_indx++; /* malloc the entry for this block by number of elems for this block but - only if the variable exists for this block! (by the truth table) */ if ( has_been_called == 0 ) { /* NOTE: this final array dim is only to be malloc'd once; when a user is annealing the mesh, anneal mesh calls wr_result_prelim_exo again, and hence create_truth_table, which would realloc this dim of gvec_elem. this test will prevent that. - RRL */ asdv ( &gvec_elem[eb_indx][ev_indx - 1], exo->eb_num_elems[eb_indx] ); has_been_called++; } } } /*Now finally the saturation hysteresis variables */ if(SAT_CURVE_TYPE != -1 || CAP_PRESS_SWITCH != -1 || SAT_QP_SWITCH != -1) { eb_ptr = Element_Blocks + eb_indx; ip_total = elem_info(NQUAD, eb_ptr->Elem_Type); for(j=0; j < ip_total; j++) { /*Note that we will set these for all 3 var types because you *will never see them individually. */ exo->elem_var_tab[i++] = 1; ev_indx++; if ( has_been_called == 0 ) { asdv ( &gvec_elem[eb_indx][ev_indx - 1], exo->eb_num_elems[eb_indx] ); } exo->elem_var_tab[i++] = 1; ev_indx++; if ( has_been_called == 0 ) { asdv ( &gvec_elem[eb_indx][ev_indx - 1], exo->eb_num_elems[eb_indx] ); } exo->elem_var_tab[i++] = 1; ev_indx++; if ( has_been_called == 0 ) { asdv ( &gvec_elem[eb_indx][ev_indx - 1], exo->eb_num_elems[eb_indx] ); } } } } /* write out table */ error = ex_put_truth_table ( exo->exoid, EX_ELEM_BLOCK, exo->num_elem_blocks, rd->nev, exo->elem_var_tab ); EH(error, "ex_put_truth_table EX_ELEM_BLOCK"); /* Now set truth table exists flag */ exo->elem_var_tab_exists = TRUE; }