⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 muldisplay.c

📁 很经典的电磁计算(电容计算)软件 MIT90年代开发
💻 C
📖 第 1 页 / 共 3 页
字号:
  char unit[BUFSIZ], name[BUFSIZ], *padName(), *spaces(), cond_name[BUFSIZ];  char *getConductorName();  extern NAME *start_name;	/* NAME structs giving conductor names */  Name *cname;  extern ITER *kill_num_list, *kinp_num_list;  extern double iter_tol;  first_offd = TRUE;  minoffd = capmat[1][1];	/* this entry is always present */				/* - in the 1 cond case, assign is still ok */  /* set up symetrized matrix storage */  CALLOC(sym_mat, numconds+1, double*, ON, AMSC);  for(i=1; i <= numconds; i++)  {    CALLOC(sym_mat[i], numconds+1, double, ON, AMSC);  }  /* get the smallest and largest (absolute value) symmetrized elements */  /* check for non-M-matrix symmetrized capacitance matrix */  for(i = 1; i <= numconds; i++) {    /* skip conductors removed from input */    if(want_this_iter(kinp_num_list, i)) continue;    i_killed = want_this_iter(kill_num_list, i);    if(capmat[i][i] <= 0.0 && !i_killed) {      fprintf(stderr, "\nmksCapDump: Warning - capacitance matrix has non-positive diagonal\n  row %d\n", i+1);    }    maxdiag = MAX(maxdiag, fabs(capmat[i][i]));    rowttl = 0.0;    for(j = 1; j <= numconds; j++) {      /* skip conductors removed from input */      if(want_this_iter(kinp_num_list, j)) continue;      if(j == i) {	sym_mat[i][i] = capmat[i][i];	continue;      }      /* if this column was not calculated and neither was the column         with the same number as the current row, then symetrized mat has	 no entry at [i][j], [j][i] */      j_killed = want_this_iter(kill_num_list, j);      if(i_killed && j_killed) continue;      /* if this column was calculated but column with the same number         as the current row wasnt, then symmetrized mat has unaveraged entry 	 at [i][j], [j][i] */      else if(i_killed && !j_killed) mat_entry = capmat[i][j];      /* if this column was not calculated but column with the same number         as the current row was, then symmetrized mat has unaveraged entry 	 at [i][j], [j][i] */      else if(!i_killed && j_killed) mat_entry = capmat[j][i];      /* if this column was calculated and column with the same number         as the current row was also, then symmetrized mat has averaged entry 	 at [i][j], [j][i] */      else mat_entry = (capmat[i][j] + capmat[j][i])/2.0;      rowttl += mat_entry;      if(mat_entry >= 0.0) {	fprintf(stderr, "\nmksCapDump: Warning - capacitance matrix has non-negative off-diagonals\n  row %d col %d\n", i, j);      }      if(fabs(mat_entry) != 0.0) {	if(first_offd) {	  minoffd = fabs(mat_entry);	  first_offd = FALSE;	}	else minoffd = MIN(minoffd, fabs(mat_entry));      }      sym_mat[i][j] = mat_entry;    }    if(rowttl + capmat[i][i] <= 0.0 && !i_killed) {      fprintf(stderr, "\nmksCapDump: Warning - capacitance matrix is not strictly diagonally dominant\n  due to row %d\n", i);    }  }  /* figure the units to use for the matrix entries      - set up so smallest element is between 0.1 and 10 */  if(minoffd*FPIEPS*relperm*scale > 10.0) toobig = TRUE;  else toobig = FALSE;  if(minoffd*FPIEPS*relperm*scale < 0.1) toosmall = TRUE;  else toosmall = FALSE;  while(toobig == TRUE || toosmall == TRUE) {    if(toobig == TRUE) {      scale *= 1e-3;      if(minoffd*FPIEPS*relperm*scale <= 10.0) break;    }    if(toosmall == TRUE) {      scale *= 1e+3;      if(minoffd*FPIEPS*relperm*scale >= 0.1) break;    }  }  /* get the appropriate unit string */  if(scale == 1e-18) strcpy(unit, "exa");  else if(scale == 1e-15) strcpy(unit, "peta");  else if(scale == 1e-12) strcpy(unit, "tera");  else if(scale == 1e-9) strcpy(unit, "giga");  else if(scale == 1e-6) strcpy(unit, "mega");  else if(scale == 1e-3) strcpy(unit, "kilo");  else if(scale == 1.0) strcpy(unit, "");  else if(scale == 1e+3) strcpy(unit, "milli");  else if(scale == 1e+6) strcpy(unit, "micro");  else if(scale == 1e+9) strcpy(unit, "nano");  else if(scale == 1e+12) strcpy(unit, "pico");  else if(scale == 1e+15) strcpy(unit, "femto");  else if(scale == 1e+18) strcpy(unit, "atto");  else sprintf(unit, "every unit is %g ", 1/scale);  /* get the length of the longest name */  maxlen = 0;  for(i = 1; i <= numconds; i++) {    maxlen = MAX(strlen(getConductorName(i, name_list)), maxlen);  }  /* print the matrix */  sigfig = 2+log10(1.0/iter_tol);	/* get no. significant figs to prnt */  colwidth = sigfig+6;		/* field width for cap mat columns */  if(ITRDAT == OFF) fprintf(stdout, "\n");  if(kill_num_list != NULL)       fprintf(stdout, "\nPARTIAL CAPACITANCE MATRIX, %sfarads\n", unit);  else fprintf(stdout, "\nCAPACITANCE MATRIX, %sfarads\n", unit);  if(numconds < 10) fprintf(stdout, "%s", spaces(unit, maxlen+2));  else if(numconds < 100) fprintf(stdout, "%s", spaces(unit, maxlen+3));  else fprintf(stdout, "%s", spaces(unit, maxlen+4));  for(j = 1; j <= numconds; j++) { /* column headings */    if(want_this_iter(kinp_num_list, j)) continue;    sprintf(name, "%d ", j);    sprintf(unit, "%%%ds", colwidth+1);    fprintf(stdout, unit, name);  }  fprintf(stdout, "\n");  for(i = 1; i <= numconds; i++) { /* rows */    /* skip conductors removed from input */    if(want_this_iter(kinp_num_list, i)) continue;    sprintf(unit, "%d", i);    strcpy(cond_name, getConductorName(i, name_list));    if(numconds < 10)	fprintf(stdout, "%s %1s", padName(name, cond_name, maxlen), unit);    else if(numconds < 100)	fprintf(stdout, "%s %2s", padName(name, cond_name, maxlen), unit);    else	fprintf(stdout, "%s %3s", padName(name, cond_name, maxlen), unit);    for(j = 1; j <= numconds; j++) {      /* skip conductors removed from input */      if(want_this_iter(kinp_num_list, j)) continue;      if(want_this_iter(kill_num_list, i) 	 && want_this_iter(kill_num_list, j)) {	/* print a blank if capacitance was not calculated */	fprintf(stdout, "%s", spaces(unit, colwidth+1));      }      else {	sprintf(unit, " %%%d.%dg", colwidth, sigfig);	fprintf(stdout, unit, scale*FPIEPS*relperm*sym_mat[j][i]);      }    }    fprintf(stdout, "\n");  }}/*  dumps brief information about multipole set up*/void dumpMulSet(sy, numLev, order)ssystem *sy;int numLev, order;{  int numcubes, numsides, i, multerms();  for(numcubes = 1, i = 0; i < numLev; numcubes *= 8, i++);  for(numsides = 1, i = 0; i < numLev; numsides *= 2, i++);  fprintf(stdout, "\nMULTIPOLE SETUP SUMMARY\n");  fprintf(stdout, "Level 0 cube extremal coordinates\n");  fprintf(stdout, "  x: %g to %g\n", 	  sy->minx, sy->minx + numsides * (sy->length));  fprintf(stdout, "  y: %g to %g\n", 	  sy->miny, sy->miny + numsides * (sy->length));  fprintf(stdout, "  z: %g to %g\n", 	  sy->minz, sy->minz + numsides * (sy->length));  fprintf(stdout, "Level %d (lowest level) cubes\n  %d total\n", 	  numLev, numcubes);  fprintf(stdout, 	  "  side length = %g\n  maximum number of panels in each = %d\n",	  sy->length, sy->mul_maxlq);  fprintf(stdout, "  maximum number of evaluation points in each = %d\n",	  sy->loc_maxlq);  fprintf(stdout, 	  "Maximum number of panels treated with a multipole expansion = %d\n",	  sy->max_panel);  fprintf(stdout,   "Maximum number of evaluation points treated with a local expansion = %d\n",	  sy->max_eval_pnt);  fprintf(stdout, 	  "Maximum number of panels treated exactly = %d (limit = %d)\n",	  sy->mul_maxq, multerms(order));  fprintf(stdout,    "Maximum number of evaluation points treated exactly = %d (limit = %d)\n",	  sy->loc_maxq, multerms(order));}/*  dump all the preconditioner matrices in the direct list cubes as one  big matrix for matlab read in "Ctil"  - figures preconditioner by multiplying it by columns of the inverse    and dumping results one column at a time  - figures the unpreconditioned matrix (using calcp) and dumps it to "P"  - type determines which of the matrices to dump*/void dump_preconditioner(sys, chglist, type)charge *chglist;ssystem *sys;int type;			/* 1=>dump P and C; 2=>P only; 3=>C only */{  int num_panels, i, j;  charge *pp, *pi;  cube *cp;  double calcp();  FILE *fp;  /* find the number of panels */  for(num_panels = 0, pp = chglist; pp != NULL; pp = pp->next, num_panels++);  /* open the output file */  if((fp = fopen("prec.mat","w")) == NULL) {    fprintf(stderr, "dump_preconditioner: can't open `prec.mat'\n");    exit(1);  }    if(type == 1 || type == 3) {    fprintf(stdout, "\nDumping preconditioner to `prec.mat' as `Ctil'\n");    /* dump the preconditioner one column at a time */    /* - savemat arg "type" can be used to make rowwise dumps         type = x0xx  =>  columnwise dumps          type = x1xx  =>  rowwise dumps (see matlab manual) */    for(j = 1; j < num_panels+1; j++) {      /* load I col into q and zero p */      for(i = 0; i < num_panels+1; i++) {	if(i == j) sys->q[i] = 1.0;	else sys->q[i] = 0.0;      }      /* figure the column of C in p (xfered to q after calculation) */      mulPrecond(sys, PRECOND);      /* dump the preconditioner column */      if(j == 1) savemat_mod(fp, 1000, "Ctil", num_panels, num_panels, 0, 			     &(sys->q[1]), (double *)NULL, 0, num_panels);      else savemat_mod(fp, 1000, "Ctil", num_panels, num_panels, 0, 		       &(sys->q[1]), (double *)NULL, 1, num_panels);    }  }  if(type == 1 || type == 2) {    fprintf(stdout, "\nDumping pot. coeff. mat. to `prec.mat' as `P'\n");    /* dump the P matrix - DANGER: does n^2 calcp() calls,       but storage is only n */    /* are q indices from 1?? */    for(j = 1; j < num_panels+1; j++) {      /* find the panel with the current index (select column) */      for(pp = chglist; pp != NULL; pp = pp->next) {	if(pp->index == j) break;      }      if(pp == NULL) {	fprintf(stderr, "dump_preconditioner: no charge with index %d\n", j);	exit(1);      }      for(i = 0; i < num_panels+1; i++) sys->p[i] = 0.0;      /* find the column---influence of q_j on potentials at each q_i */      for(i = 1, pi = chglist; pi != NULL; i++, pi = pi->next) {	sys->p[pi->index] = calcp(pp, pi->x, pi->y, pi->z, NULL);      }      /* dump the column */      if(j == 1) savemat_mod(fp, 1000, "P", num_panels, num_panels, 0, 			     &(sys->p[1]), (double *)NULL, 0, num_panels);      else savemat_mod(fp, 1000, "P", num_panels, num_panels, 0, 		       &(sys->p[1]), (double *)NULL, 1, num_panels);    }  }  fclose(fp);}/*  do an n^2/2 check to see if any panels have the same center points  (debug only)*/int has_duplicate_panels(fp, chglst)charge *chglst;FILE *fp;{  int no_duplicates;  charge *cp, *cpinner;  no_duplicates = TRUE;  for(cp = chglst; cp != NULL; cp = cp->next) {    for(cpinner = cp->next; cpinner != NULL; cpinner = cpinner->next) {      if(cp->x == cpinner->x && cp->y == cpinner->y && cp->z == cpinner->z) {	no_duplicates = FALSE;	if(cp->surf->type == CONDTR) fprintf(fp, "Panels %d(CONDTR)",						cp->index);	if(cp->surf->type == DIELEC) fprintf(fp, "Panels %d(DIELEC)",						cp->index);	if(cp->surf->type == BOTH) fprintf(fp, "Panels %d(BOTH)",					      cp->index);	if(cpinner->surf->type == CONDTR) fprintf(fp, " and %d(CONDTR)",						cpinner->index);	if(cpinner->surf->type == DIELEC) fprintf(fp, " and %d(DIELEC)",						cpinner->index);	if(cpinner->surf->type == BOTH) fprintf(fp, " and %d(BOTH)",					      cpinner->index);	fprintf(fp, " both have center (%.3g %.3g %.3g)\n",		cp->x, cp->y, cp->z);      }    }  }  if(no_duplicates) return(FALSE);  else return(TRUE);}#if DSQ2PD == ON/*  dump the condensed matrix for matlab use*/void dumpQ2PDiag(nextc)cube *nextc;{  int i, j, ind, pos_d, neg_d;  double temp[BUFSIZ], temp_mat[100][100], **rmat;  double pos_fact, neg_fact, panel_fact;  FILE *fp, *fopen();  /* dump the diag matrix to a matlab file along with its dummy vector */  /*   must complie on sobolev with /usr/local/matlab/loadsave/savemat.o */  if((fp = fopen("Q2PDiag.mat", "w")) == NULL) {    fprintf(stderr, "dumpQ2PDiag: can't open `Q2PDiag.mat' to write\n");    exit(1);  }  if(sizeof(temp) < nextc->upnumeles[0]*nextc->upnumeles[0]) {    fprintf(stderr, "dumpQ2PDiag: temporary arrays not big enough\n");    exit(1);  }  /* incorporate the electric field evaluation into the matrix */  /* if a row corresponds to a flux density difference, alter it */  rmat = nextc->directmats[0];  for(i = 0; i < nextc->upnumeles[0]; i++) {    if(nextc->chgs[i]->dummy) {      for(j = 0; j < nextc->upnumeles[0]; j++) temp_mat[i][j] = 0.0;      continue;    }    if(nextc->chgs[i]->surf->type == CONDTR) {      for(j = 0; j < nextc->upnumeles[0]; j++) {	temp_mat[i][j] = rmat[i][j];      }    }    else {      pos_fact 	  = nextc->chgs[i]->surf->outer_perm/nextc->chgs[i]->pos_dummy->area;      pos_d = nextc->chgs[i]->pos_dummy->index - 1;      neg_fact 	  = nextc->chgs[i]->surf->inner_perm/nextc->chgs[i]->neg_dummy->area;      neg_d = nextc->chgs[i]->neg_dummy->index - 1;      panel_fact = pos_fact + neg_fact;      for(j = 0; j < nextc->upnumeles[0]; j++) {	temp_mat[i][j] = pos_fact*rmat[pos_d][j] - panel_fact*rmat[i][j]	    + neg_fact*rmat[neg_d][j];      }    }  }    /* flatten the Q2PDiag matrix */  for(j = ind = 0; j < nextc->upnumeles[0]; j++) {    for(i = 0; i < nextc->upnumeles[0]; i++) {      temp[ind++] = temp_mat[i][j];    }  }  savemat(fp, 1000, "A", nextc->upnumeles[0], nextc->upnumeles[0],	  0, temp, (double *)NULL);  /* make the is_dummy vector a vector of doubles */  for(i = 0; i < nextc->upnumeles[0]; i++)       temp[i] = (double)(nextc->nbr_is_dummy[0][i]);  savemat(fp, 1000, "is_dummy", nextc->upnumeles[0], 1,	  0, temp, (double *)NULL);  /* make a vector with 0 => CONDTR 1 => DIELEC 2 => BOTH -1 => dummy */  for(i = 0; i < nextc->upnumeles[0]; i++) {    if(nextc->chgs[i]->dummy) temp[i] = -1.0;    else temp[i] = (double)(nextc->chgs[i]->surf->type);  }  savemat(fp, 1000, "surf_type", nextc->upnumeles[0], 1,	  0, temp, (double *)NULL);  fclose(fp);  fprintf(stdout, "Dumped Q2PDiag matrix to `Q2PDiag.mat'\n");}#endif#if 1 == 0/*  for debug only on SPARC2 -- NaN trap error handler (see man matherr)*/int matherr(exc)struct exception *exc;{  fprintf(stderr, "matherr: ");  if(exc->type == DOMAIN) fprintf(stderr, "DOMAIN error in");  else if(exc->type == SING) fprintf(stderr, "SING error in");  else if(exc->type == OVERFLOW) fprintf(stderr, "OVERFLOW error in");  else if(exc->type == UNDERFLOW) fprintf(stderr, "UNDERFLOW error in");  fprintf(stderr, " %s\n", exc->name);  fprintf(stderr, " args: %g %g returning: %g\n", exc->arg1, exc->arg2,	  exc->retval);  exit(1);}#endif/*  debug only - check a vector to make sure it has zeros in dummy entries*/int chkDummy(vector, is_dummy, size)double *vector;int *is_dummy;int size;{  int i, first = TRUE;  for(i = 0; i < size; i++) {    if(is_dummy[i] && vector[i] != 0.0) {      if(first) {	first = FALSE;	fprintf(stderr, "\nchkDummy: entries should be 0.0: %d", i);      }      else fprintf(stderr, " %d", i);    }  }  if(!first) fprintf(stderr, "\n");}/*  debug only - print message if dummy list doesn't match panel list*/void chkDummyList(panels, is_dummy, n_chgs)charge **panels;int *is_dummy;int n_chgs;{  int i;  int first = TRUE;    for(i = 0; i < n_chgs; i++) {    if(is_dummy[i] && !panels[i]->dummy || !is_dummy[i] && panels[i]->dummy) {      if(first) {	first = FALSE;	fprintf(stderr, "chkDummyList: inconsistent dummy list entries:\n");      }      fprintf(stderr, " %d is_dummy = %d, panel->dummy = %d\n", i,	      is_dummy[i], panels[i]->dummy);    }  }}/*  print the conductor names to a file*/void dumpCondNames(fp, name_list)FILE *fp;Name *name_list;{   int i;  char *last_alias();  Name *cur_name;  fprintf(fp, "CONDUCTOR NAMES\n");  for(cur_name = name_list, i = 0; cur_name != NULL;       cur_name = cur_name->next, i++) {    fprintf(fp, "  %d `%s'\n", i+1, last_alias(cur_name));  }}/*  debug only: dump state of internal conductor name list*/int dumpNameList(name_list)Name *name_list;{  Name *cur_name, *cur_alias;  for(cur_name = name_list; cur_name != NULL; cur_name = cur_name->next) {    fprintf(stdout, "`%s'\n", cur_name->name);    for(cur_alias = cur_name->alias_list; cur_alias != NULL; 	cur_alias = cur_alias->next) {      fprintf(stdout, "  `%s'\n", cur_alias->name);    }  }  return(TRUE);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -