int get_new_coord(double *new_coord[DIM], double *x, const Exo_DB *exo ) { int p,i,j; int dim = exo->num_dim; int num_nodes = exo->num_nodes; int displacement_somewhere = FALSE; int ln; int *moved; int e_start = exo->eb_ptr[0]; int e_end = exo->eb_ptr[exo->num_elem_blocks]; int ielem; int gnn; int var; double phi[MDE]; for(p = 0; p < dim; p++) { new_coord[p] = (double *) calloc(num_nodes, sizeof(double)); dcopy1( num_nodes, Coor[p], new_coord[p] ); } for(p = 0; p < upd->Num_Mat; p++) displacement_somewhere |= ( pd_glob[p]->e[R_MESH1] ); if ( displacement_somewhere == FALSE ) return (FALSE ); moved = (int *) calloc( num_nodes, sizeof(int) ); /* * Loop through nodes, find displacement, and add it into * the coordinate */ for(ielem = e_start; ielem < e_end; ielem++) { double displacement[DIM]; load_elem_dofptr(ielem, exo, x, x, x, x, x, 1); for(ln = 0; ln < ei->num_local_nodes; ln++) { double xi[3] = {0.0, 0.0, 0.0}; find_nodal_stu(ln, ei->ielem_type, xi, xi+1, xi+2); gnn = exo->elem_node_list[ exo->elem_node_pntr[ielem] + ln ] ; memset(displacement, 0, sizeof(double)*DIM); if( moved[gnn] != 1 ) { for(p = 0; p < DIM; p++) { var = MESH_DISPLACEMENT1 + p; for(i = 0; i < ei->dof[var]; i++) { phi[i] = newshape(xi, ei->ielem_type, PSI, ei->dof_list[var][i], ei->ielem_shape, pd->i[var], i); } if( pd->v[var] ) { for(j = 0; j < ei->dof[var]; j++) { displacement[p] += *esp->d[p][j] * phi[j]; } moved[gnn] = 1; } else displacement[p] = 0.0; } } for(p = 0; p < dim; p++) new_coord[p][gnn] += displacement[p]; } } safer_free((void **) &moved); return( TRUE ); }
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 */