📄 input.c
字号:
exit(1); } } fclose(fp);}#if 1 == 0 /* now done one panel at a time in initcalcp *//* TEMPORARY: works best for closed surfaces in which case ref should be a point inside with ref_inside = TRUE can also be used with open surfaces: ref = point on - side, ref_inside = TRUE will not work if the surface folds back on itself (and other ways too)*/void align_normals(panel_list, surf)surface *surf;charge *panel_list;{ int i, flip_normal; char *hack_path(); charge *nc; double ctr_minus_n[3], ctr_plus_n[3], norm_minus, norm_plus, norm, norm_sq; double x, y, z, *normal, *direction, *tempd; int ref_inside = surf->ref_inside; double *ref = surf->ref, temp; char *surf_name = surf->name; for(nc = panel_list; nc != NULL; nc = nc->next) { /* get panel position (relative to reference point) and normal */ x = nc->x - ref[0]; y = nc->y - ref[1]; z = nc->z - ref[2]; norm_sq = x*x + y*y + z*z; norm = sqrt(norm_sq); normal = nc->Z; /* add the (scaled) normal and negative normal to the panel center */ /* negative normal result should be closer to ref point if(ref_inside) */ ctr_minus_n[0] = x - 0.1*norm*normal[0]; ctr_minus_n[1] = y - 0.1*norm*normal[1]; ctr_minus_n[2] = z - 0.1*norm*normal[2]; ctr_plus_n[0] = x + 0.1*norm*normal[0]; ctr_plus_n[1] = y + 0.1*norm*normal[1]; ctr_plus_n[2] = z + 0.1*norm*normal[2]; /* get norms of test points, one inside (minus) other out (plus) */ norm_minus = ctr_minus_n[0]*ctr_minus_n[0]; norm_plus = ctr_plus_n[0]*ctr_plus_n[0]; for(i = 1; i < 3; i++) { norm_minus += ctr_minus_n[i]*ctr_minus_n[i]; norm_plus += ctr_plus_n[i]*ctr_plus_n[i]; } flip_normal = FALSE; if(norm_minus > norm_sq) { if(norm_plus > norm_sq) { fprintf(stderr, "align_normals: both test points on non-reference side\n"); fprintf(stderr, " Surface: %s\n", hack_path(surf_name)); fprintf(stderr, " Translation: (%g %g %g)\n", surf->trans[0], surf->trans[1], surf->trans[2]); fprintf(stderr, " Reference point: (%g %g %g)\n", ref[0], ref[1], ref[2]); fprintf(stderr, " Panel cntr: (%g %g %g)\n", nc->x, nc->y, nc->z); fprintf(stderr, " Normal: (%g %g %g)\n", normal[0], normal[1], normal[2]); exit(1); } if(ref_inside) flip_normal = TRUE; } else if(norm_plus < norm_sq) { if(norm_minus < norm_sq) { fprintf(stderr, "align_normals: both test points on reference point side\n"); fprintf(stderr, " Surface: %s\n", hack_path(surf_name)); fprintf(stderr, " Translation: (%g %g %g)\n", surf->trans[0], surf->trans[1], surf->trans[2]); fprintf(stderr, " Reference point: (%g %g %g)\n", ref[0], ref[1], ref[2]); fprintf(stderr, " Panel cntr: (%g %g %g)\n", nc->x, nc->y, nc->z); fprintf(stderr, " Normal: (%g %g %g)\n", normal[0], normal[1], normal[2]); exit(1); } if(!ref_inside) flip_normal = TRUE; } if(flip_normal) { for(i = 0; i < 3; i++) { normal[i] = -normal[i]; /* flip the normal */ nc->X[i] = -(nc->X[i]); /* flip the x direction */ /* interchange points 0 and 2 so that corner order will be consistent with X flip (note that this is OK for quads and tris) */ temp = nc->corner[0][i]; nc->corner[0][i] = nc->corner[2][i]; nc->corner[2][i] = temp; } } }}#endif/* add dummy panel structs to the panel list for electric field evaluation - assumes its handed a list of DIELEC or BOTH type panels*/void add_dummy_panels(panel_list)charge *panel_list;{ double h; charge *dummy_list = NULL; charge *cur_panel, *cur_dummy; for(cur_panel = panel_list; cur_panel != NULL; cur_panel = cur_panel->next) { cur_panel->dummy = FALSE; /* make 2 dummy panels for evaluation points needed to do div difference */ /* make the first */ if(dummy_list == NULL) { CALLOC(dummy_list, 1, charge, ON, AMSC); cur_dummy = dummy_list; } else { CALLOC(cur_dummy->next, 1, charge, ON, AMSC); cur_dummy = cur_dummy->next; } cur_dummy->dummy = TRUE; h = HPOS; cur_dummy->x = cur_panel->x + cur_panel->Z[0]*h; cur_dummy->y = cur_panel->y + cur_panel->Z[1]*h; cur_dummy->z = cur_panel->z + cur_panel->Z[2]*h; /* note ABUSE OF area field - used to store div dif distance */ cur_dummy->area = h; cur_panel->pos_dummy = cur_dummy; /* link dummy to its real panel */ /* make the second dummy struct */ CALLOC(cur_dummy->next, 1, charge, ON, AMSC); cur_dummy = cur_dummy->next; cur_dummy->dummy = TRUE; h = HNEG; cur_dummy->x = cur_panel->x - cur_panel->Z[0]*h; cur_dummy->y = cur_panel->y - cur_panel->Z[1]*h; cur_dummy->z = cur_panel->z - cur_panel->Z[2]*h; /* note ABUSE OF area field - used to store div dif distance */ cur_dummy->area = h; cur_panel->neg_dummy = cur_dummy; /* link dummy to its real panel */ } /* put the dummies in the list */ for(cur_panel = panel_list; cur_panel->next != NULL; cur_panel = cur_panel->next); cur_panel->next = dummy_list; }/* returns a pointer to a file name w/o the path (if present) */char *hack_path(str)char *str;{ int i; int last_slash; for(i = last_slash = 0; str[i] != '\0'; i++) { if(str[i] == '/') last_slash = i; } if(str[last_slash] == '/') return(&(str[last_slash+1])); else return(str);}/* reassigns conductor numbers to a list of panels so that they'll be numbered contiguously from 1 - also changes conductor numbers associated with conductor name structs - dummy panels are skipped - dielectric panels, with conductor number 0, are also skipped*/void reassign_cond_numbers(panel_list, name_list, surf_name)char *surf_name;NAME *name_list;charge *panel_list;{ int i, j, cond_nums[MAXCON], num_cond, cond_num_found, temp; char str[BUFSIZ], *hack_path(); charge *cur_panel; NAME *cur_name; /* get the conductor numbers currently being used */ num_cond = 0; for(cur_panel = panel_list; cur_panel != NULL; cur_panel = cur_panel->next) { if(cur_panel->dummy || cur_panel->cond == 0) continue; cond_num_found = FALSE; for(i = 0; i < num_cond; i++) { if(cur_panel->cond == cond_nums[i]) { cond_num_found = TRUE; break; } } if(!cond_num_found) cond_nums[num_cond++] = cur_panel->cond; } /* rewrite all the conductor numbers to be their position in the array */ for(cur_panel = panel_list; cur_panel != NULL; cur_panel = cur_panel->next) { if(cur_panel->dummy || cur_panel->cond == 0) continue; for(i = 0; i < num_cond && cur_panel->cond != cond_nums[i]; i++); if(i == num_cond) { fprintf(stderr, "reassign_cond_numbers: cant find conductor number that must exist\n"); exit(1); } cur_panel->cond = i+1; } /* do the same for the name structs */ for(cur_name = name_list; cur_name != NULL; cur_name = cur_name->next) { for(i = 0; i < num_cond && cur_name->patch_list->conductor_ID != cond_nums[i]; i++); if(i == num_cond) { fprintf(stderr, "reassign_cond_numbers: cant find conductor number in name list\n"); exit(1); }#if 1 == 0 /* change the name given to this conductor if it was derived from the ID */ /* check the number */ if(sscanf(&(cur_name->name[9]), "%d", &temp) == 1) { if(temp == cur_name->patch_list->conductor_ID) { strcpy(str, cur_name->name); str[9] = '\0'; /* check the rest of the string, replace if necessary */ if(!strcmp(str, "CONDUCTOR")) { sprintf(str, "COND%d (%s)", i+1, hack_path(surf_name)); if(strlen(str) > strlen(cur_name->name)) CALLOC(cur_name->name, strlen(str)+1, char, ON, AMSC); strcpy(cur_name->name, str); } } } cur_name->patch_list->conductor_ID = i+1;#endif } }/* negates all the conductor numbers - used to make a panel list's conds unique just before renumbering*/void negate_cond_numbers(panel_list, name_list)NAME *name_list;charge *panel_list;{ charge *cur_panel; NAME *cur_name; for(cur_panel = panel_list; cur_panel != NULL; cur_panel = cur_panel->next) { if(cur_panel->dummy) continue; cur_panel->cond = -cur_panel->cond; } for(cur_name = name_list; cur_name != NULL; cur_name = cur_name->next) { cur_name->patch_list->conductor_ID = -cur_name->patch_list->conductor_ID; }}/* for debug - dumps the iter list*/int dump_ilist(){ ITER *cur_iter; extern ITER *qpic_num_list; /* check the list for the iter number passed in */ fprintf(stdout, "Iter list:"); for(cur_iter = qpic_num_list; cur_iter != NULL; cur_iter = cur_iter->next) { fprintf(stdout, "%d ", cur_iter->iter); } fprintf(stdout, "\n"); return(TRUE);}#if 1 == 0/* adds an iteration number to the list that get shaded .ps file dumps - list is built on global variable q_iter*/void add_iter(iter_num)int iter_num;{ ITER *cur_iter, *tail_iter; extern ITER *q_iter; /* check the list for the iter number passed in */ for(cur_iter = q_iter; cur_iter != NULL; tail_iter = cur_iter, cur_iter = cur_iter->next) { if(cur_iter->iter == iter_num) { return; } } /* not in list; create a new iter struct to store the new iter number */ if(q_iter == NULL) { CALLOC(q_iter, 1, ITER, ON, AMSC); tail_iter = q_iter; } else { CALLOC(tail_iter->next, 1, ITER, ON, AMSC); tail_iter = tail_iter->next; } tail_iter->iter = iter_num; tail_iter->next = NULL;}#endif/* checks if a particular iter is in the list; returns TRUE if it is*/int want_this_iter(iter_list, iter_num)ITER *iter_list;int iter_num;{ ITER *cur_iter; for(cur_iter = iter_list; cur_iter != NULL; cur_iter = cur_iter->next) { if(cur_iter->iter == iter_num) { return(TRUE); } } return(FALSE);}/* sets up the ps file base string*/void get_ps_file_base(argv, argc)char *argv[];int argc;{ int i, j; char temp[BUFSIZ], *hack_path(); extern char *ps_file_base; /* - if no list file, use input file; otherwise use list file */ /* - if neither present, use "stdin" */ /* check for list file */ for(i = 1; i < argc; i++) { if(argv[i][0] == '-' && argv[i][1] == 'l') { strcpy(temp, &(argv[i][2])); /* go to end of string, walk back to first period */ for(j = 0; temp[j] != '\0'; j++); for(; temp[j] != '.' && j >= 0; j--); if(temp[j] == '.') temp[j] = '\0'; /* save list file base */ CALLOC(ps_file_base, strlen(temp)+1, char, ON, AMSC); strcpy(ps_file_base, hack_path(temp)); break; } else if(argv[i][0] != '-') { /* not an option, must be input file */ strcpy(temp, argv[i]); for(j = 0; temp[j] != '\0' && temp[j] != '.'; j++); temp[j] = '\0'; /* save list file base */ CALLOC(ps_file_base, strlen(temp)+1, char, ON, AMSC); strcpy(ps_file_base, hack_path(temp)); break; } } if(ps_file_base == NULL) { /* input must be stdin */ CALLOC(ps_file_base, strlen("stdin")+1, char, ON, AMSC); strcpy(ps_file_base, "stdin"); }}/* open all the surface files and return a charge (panel) struct list set up pointers from each panel to its corresponding surface struct align the normals of all the panels in each surface so they point towards the same side as where the ref point is (dielectric files only)*/charge *read_panels(surf_list, name_list, num_cond)Name **name_list;int *num_cond;surface *surf_list;{ int patran_file, num_panels, stdin_read, num_dummies, num_quads, num_tris; charge *panel_list = NULL, *cur_panel, *patfront(), *panel_group, *c_panel; surface *cur_surf; extern NAME *start_name, *start_name_this_time; extern char *title; NAME *name_group; FILE *fp, *fopen(); char surf_name[BUFSIZ], *hack_path(); int patran_file_read; /*title[0] = '\0';*/ stdin_read = FALSE; for(cur_surf = surf_list; cur_surf != NULL; cur_surf = cur_surf->next) { if(!strcmp(cur_surf->name, "stdin")) { if(stdin_read) { fprintf(stderr, "read_panels: attempt to read stdin twice\n"); exit(1); } else { stdin_read = TRUE; fp = stdin; } }#if SINGLE_FILE_INPUT == ON else if((fp = fc_fopen(cur_surf->name, "r")) == NULL) {#else else if((fp = fopen(cur_surf->name, "r")) == NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -