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; }
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); }
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 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; }
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 */
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 */
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 */