📄 patran.c
字号:
CALLOC(current_name->name, len+1, char, ON, AMSC); delcr(line); strcpy(current_name->name, line); /* input NTYPE ID pair lines until no more, save patch id's that come in */ for(i = iv = 0; i < KC-1; i++) { /* loop on lines */ for(j = 0; j < 5 && iv < IV/2; j++, iv++) { /* loop on items */ fscanf(stream, "%d %d", &ntype, &id); if(ntype == 3) { /* if its a patch, save ID */ if(current_patch == NULL) { /* if 1st patch */ CALLOC(current_name->patch_list, 1, SM_PATCH, ON, AMSC); current_patch = current_name->patch_list; } else { CALLOC(current_patch->next, 1, SM_PATCH, ON, AMSC); current_patch = current_patch->next; } current_patch->ID = id; patch_cnt++; } } } if(patch_cnt == 0) { fprintf(stderr, "\nname_data: conductor '%s'\n has no patch - redo naming so that one is included.\n", current_name->name); exit(1); }}/* This function checks for coordinate-wise equivalent grid points. Each grid structure has a list of equivalent grids. If all three coordinates from two grid points are within SMALL_NUMBER, defined in patran.h, then they are equivalent. */grid_equiv_check(){ GRID *grid_ptr_1, *grid_ptr_2; int i; /* First, allocate spaces for equivalent grid arrays. */ grid_ptr_1 = start_grid; while (grid_ptr_1) { CALLOC(grid_ptr_1->equiv_ID, number_grids, int, ON, AMSC); grid_ptr_1->number_equiv_grids = 0; grid_ptr_1 = grid_ptr_1->next; } /* Begin search. Grid N is compared with grids from N+1 through the end of the list. */ grid_ptr_1 = start_grid; while (grid_ptr_1) { grid_ptr_2 = grid_ptr_1->next; while (grid_ptr_2) { if (if_same_coord(grid_ptr_1->coord,grid_ptr_2->coord)) { *(grid_ptr_1->equiv_ID + grid_ptr_1->number_equiv_grids) = grid_ptr_2->ID; *(grid_ptr_2->equiv_ID + grid_ptr_2->number_equiv_grids) = grid_ptr_1->ID; (grid_ptr_1->number_equiv_grids)++; (grid_ptr_2->number_equiv_grids)++; } grid_ptr_2 = grid_ptr_2->next; } grid_ptr_1 = grid_ptr_1->next; } /* Print the equivalent grid information. grid_ptr_1 = start_grid; while (grid_ptr_1) { printf("\nGrid %d : (%d)", grid_ptr_1->ID, grid_ptr_1->number_equiv_grids); for (i=0; i<grid_ptr_1->number_equiv_grids; i++) printf (" %d ", *(grid_ptr_1->equiv_ID+i)); grid_ptr_1 = grid_ptr_1->next; } */}int if_same_coord(coord_1, coord_2) double coord_1[3], coord_2[3];{ int i; for (i=0; i<3; i++) if (fabs(coord_1[i] - coord_2[i]) > SMALL_NUMBER) return 0; return 1;}/* makes 1st \n in a string = \0 and then deletes all trail/leading wh space*/char *delcr(str)char *str;{ int i, j, k; for(k = 0; str[k] != '\0'; k++) if(str[k] == '\n') { str[k] = '\0'; break; } for(i = 0; str[i] == ' ' || str[i] == '\t'; i++); /* count leading spaces */ if(i > 0) { for(j = 0; str[j+i] != '\0'; j++) str[j] = str[j+i]; str[j] = '\0'; } for(k--; str[k] == ' ' || str[k] == '\t'; k--) str[k] = '\0'; return(str);}/**************************************************************************** This section of code is responsible for assigning conductor numbers to all the patches.****************************************************************************//* This function fills the table that shows the connectivity of patches. If two patches share at least one common corner point, then they are connected. It is done by going through all the grid points and finding patches that are connected by the grid point. The end result table is symmetric. */ fill_patch_patch_table(patch_patch_table) int *patch_patch_table;{ int patch_count, patch_count_save, *current_table_ptr, *corner, i; GRID *grid_ptr; PATCH *patch_ptr; grid_ptr = start_grid; while (grid_ptr) { /* Patch_count is generic counter of current position in the patch array, start_patch. Patch_count_save is index of the last patch that had the current grid as its corner. */ patch_count = 0; patch_count_save = 0; current_table_ptr = 0; patch_ptr = start_patch; while (patch_ptr) { corner = patch_ptr->corner; for (i=0; i<4; i++) if (if_same_grid(*corner++,grid_ptr)) { if (current_table_ptr) { /* Have we already found another patch with the same grid as its corner? */ *(current_table_ptr+patch_count)=1; *(patch_patch_table + (patch_count * number_patches) + patch_count_save)=1; } current_table_ptr = patch_patch_table + patch_count*number_patches; patch_count_save = patch_count; } patch_ptr = patch_ptr->next; patch_count++; } grid_ptr = grid_ptr->next; }}/* Return 1 if ID matches grid_ptr's ID or IDs of its equivalent grids, and 0 otherwise. */int if_same_grid(ID,grid_ptr) int ID; GRID *grid_ptr;{ int *equiv_ID, i; if ((grid_ptr->ID)==ID) return 1; else { equiv_ID = grid_ptr->equiv_ID; for (i=0; i<grid_ptr->number_equiv_grids; i++) if (ID == equiv_ID[i]) return 1; return 0; }}/* This function searches through the patch_patch_table and finds groups of patches that are connected only among themselves. */assign_conductor(patch_patch_table) int *patch_patch_table;{ PATCH *patch_ptr; int patch_count=0, *current_table_ptr; conductor_count=1; /* Sets all the patches to conductor 0, meaning that it is yet to be assigned a conductor_ID. */ patch_ptr = start_patch; while (patch_ptr) { patch_ptr->conductor_ID = 0; patch_ptr = patch_ptr->next; } /* Current_table_ptr points the row that needs to be searched through. That row is associated with the current patch in need of a conductor number. */ current_table_ptr = patch_patch_table; patch_ptr = start_patch; while (patch_ptr) { if ((patch_ptr->conductor_ID) == 0) { /* If the patch is not assigned a conductor number. */ patch_ptr->conductor_ID = conductor_count; depth_search(patch_patch_table,current_table_ptr,conductor_count); conductor_count++; } patch_count++; current_table_ptr = patch_patch_table + patch_count*number_patches; patch_ptr = patch_ptr->next; } /* Prints the conductor information. patch_ptr = start_patch; while (patch_ptr) { printf("\nPatch %d Conductor %d", patch_ptr->ID, patch_ptr->conductor_ID); patch_ptr = patch_ptr->next; } */}/* This function searches through patch_patch_table recursively to find all patches that are somehow connected the current patch. */depth_search(patch_patch_table,current_table_ptr,conductor_count) int *patch_patch_table, *current_table_ptr,conductor_count;{ PATCH *patch_ptr; int i, *new_table_ptr; patch_ptr=start_patch; new_table_ptr=patch_patch_table; for (i=0; i<number_patches; i++) { if ((*(current_table_ptr+i)) != 0) { /* If the current patch is connected to i'th patch. */ if (patch_ptr->conductor_ID == 0) { /* If the patch is yet to be assigned a conductor number. */ patch_ptr -> conductor_ID = conductor_count; new_table_ptr = patch_patch_table+i*number_patches; /* Call depth_search recursively to continue searching for connected patches. */ depth_search(patch_patch_table,new_table_ptr,conductor_count); } } patch_ptr=patch_ptr->next; }}/* used with new naming functions---finds the patran name in the patran list - this code used to be in mksCapDump()*/char *getPatranName(cond_num)int cond_num;{ NAME *cname; cname = start_name_this_time; while(cname != NULL) { if((cname->patch_list)->conductor_ID == cond_num) return(cname->name); else cname = cname->next; } /*strcpy(cond_name, "??UNKNOWN??");*/ fprintf(stdout, "getPatranName: conductor %d has no name\n", cond_num); return(NULL);}/**************************************************************************** The following functions create the linked list of charges that can be used in Keith's FastCap program.****************************************************************************/charge *make_charges_all_patches(name_list, num_cond, surf_type, name_suffix)Name **name_list; /* master list of conductor names */int *num_cond; /* master conductor counter */int surf_type;char *name_suffix;{ CFEG *cfeg_ptr; int NELS, LPH_ID,conductor_ID,*element_list; char cond_name[BUFSIZ]; PATCH *patch_ptr; charge *first_pq=0,*current_pq,*make_charges_patch(); cfeg_ptr = start_cfeg; while (cfeg_ptr) { if (cfeg_ptr->LPH == 3) { NELS = cfeg_ptr->NELS; LPH_ID = cfeg_ptr->LPH_ID; /* Find the patch structure that is associated with the current cfeg pointer in order to find the conductor number. */ patch_ptr = start_patch; while (patch_ptr) { if (patch_ptr->ID == LPH_ID) { if(surf_type == CONDTR || surf_type == BOTH) { strcpy(cond_name, getPatranName(patch_ptr->conductor_ID)); strcat(cond_name, name_suffix); conductor_ID = getConductorNum(cond_name, name_list, num_cond); } else conductor_ID = 0; break; } patch_ptr = patch_ptr->next; }/* printf("\nCEFG %d LPH %d LPH_ID %d Conductor_ID %d", cfeg_ptr->ID,cfeg_ptr->LPH,cfeg_ptr->LPH_ID,conductor_ID); */ /* For each patch, call the subroutine to handle the detail. Make sure all the lists of charges are linked. */ element_list = cfeg_ptr->element_list; if (!first_pq) { first_pq = make_charges_patch(NELS,element_list,conductor_ID); current_pq = first_pq + NELS - 1; } else { current_pq->next = make_charges_patch(NELS,element_list,conductor_ID); current_pq = (current_pq->next) + NELS - 1; } } cfeg_ptr=cfeg_ptr->next; } /* Put a nil pointer at the end. */ current_pq->next = 0; return first_pq;}/* This function creates the linked list of charges for a single patch. */charge *make_charges_patch(NELS,element_list,conductor_ID) int NELS, *element_list, conductor_ID;{ charge *pq, *current_pq; int i,element_number,*element_corner_ptr; ELEMENT *element_ptr; NODE *node_ptr; CALLOC(pq,NELS,charge, ON, AMSC); /* Make sure that they are linked. */ current_pq = pq; for (i=0; i<NELS-1; i++) { current_pq = pq + i; current_pq->next = current_pq+1; } /* NELS stands for number of elements. */ for (i=0; i<NELS; i++) { (pq+i)->cond = conductor_ID; /* Original element number in Neutral file can be a negative number. */ if ((element_number= *(element_list+i))<0) element_number= -element_number; element_ptr = element_search_table[element_number]; element_corner_ptr = element_ptr->corner; /* Pointers to the corner points' coordinates are set. */ if ((element_ptr->shape) == 4) { /* Quadrilateral panels. */ (pq+i)->shape = 4; node_ptr = node_search_table[*(element_corner_ptr++)]; VCOPY((pq+i)->corner[0], node_ptr->coord); node_ptr = node_search_table[*(element_corner_ptr++)]; VCOPY((pq+i)->corner[1], node_ptr->coord); node_ptr = node_search_table[*(element_corner_ptr++)]; VCOPY((pq+i)->corner[2], node_ptr->coord); node_ptr = node_search_table[*(element_corner_ptr++)]; VCOPY((pq+i)->corner[3], node_ptr->coord); } else { /* Triangular panels. *//*printf("\nTTT\n");*/ (pq+i)->shape = 3; node_ptr = node_search_table[*(element_corner_ptr++)]; VCOPY((pq+i)->corner[0], node_ptr->coord); node_ptr = node_search_table[*(element_corner_ptr++)]; VCOPY((pq+i)->corner[1], node_ptr->coord); node_ptr = node_search_table[*(element_corner_ptr++)]; VCOPY((pq+i)->corner[2], node_ptr->coord); } } return pq;}/* assigns correct conductor number to all patches in name structs - really already done implicitly in name_data by setting up sm_patch lists - conductor_ID of first patch is used as the number associated w/the name - checks for no names and names including several conductor's panels - checks one linked list against another, potentially n^2 => named regions should be kept small (as few patches as possible)*/assign_names(){ int quit, current_conductor, cnt = 0; PATCH *current_patch; SM_PATCH *current_name_patch; NAME *cur_name = start_name_this_time; if(start_name_this_time == NULL) { fprintf(stderr, "\nassign_names: no conductor names specified\n"); exit(1); } /* for each name struct, find cond no of each patch (can be n^2 loop) */ while(cur_name != NULL) { current_name_patch = cur_name->patch_list; current_conductor = 0; while(current_name_patch != NULL) { current_patch = start_patch; quit = 0; while(current_patch != NULL && quit == 0) { if(current_patch->ID == current_name_patch->ID) { current_name_patch->conductor_ID = current_patch->conductor_ID; if(current_conductor == 0) { /* if this is 1st name struct patch */ current_conductor = current_patch->conductor_ID; } else if(current_conductor != current_patch->conductor_ID) { fprintf(stderr, "\nassign_names: alleged conductor '%s'\n has patches from more than one conductor - rename more carefully\n", cur_name->name); exit(1); } quit = 1; } current_patch = current_patch->next; } if(quit == 0) { fprintf(stderr, "\nassign_names: in conductor '%s'\n can't find named patch in master list\n", cur_name->name); exit(1); } current_name_patch = current_name_patch->next; } cur_name = cur_name->next; cnt++; } /* check to see if all conductors have a name and if too many names */ if(cnt < conductor_count - 1) { fprintf(stderr, "\nassign_names: %d conductors have no names\n", conductor_count - 1 - cnt); exit(1); } if(cnt > conductor_count - 1) { fprintf(stderr, "\nassign_names: %d names given for %d conductors\n", cnt, conductor_count - 1); exit(1); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -