• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

src/mg/vpmgp.c

Go to the documentation of this file.
00001 
00049 #include "apbscfg.h"
00050 #include "apbs/vpmgp.h"
00051 #include "apbs/mgparm.h"
00052 
00053 VEMBED(rcsid="$Id: vpmgp.c 1605 2010-09-13 15:12:09Z yhuang01 $")
00054 
00055 /* ///////////////////////////////////////////////////////////////////////////
00056 // Class Vpmgp: Inlineable methods
00058 #if !defined(VINLINE_VACC)
00059 #endif /* if !defined(VINLINE_VACC) */
00060 
00061 /* ///////////////////////////////////////////////////////////////////////////
00062 // Class Vpmgp: Non-inlineable methods
00064 
00065 /* ///////////////////////////////////////////////////////////////////////////
00066 // Routine:  Vpmgp_ctor
00067 //
00068 // Author:   Nathan Baker
00070 VPUBLIC Vpmgp* Vpmgp_ctor(MGparm *mgparm) {
00071 
00072     Vpmgp *thee = VNULL;
00073 
00074     /* Set up the structure */
00075     thee = Vmem_malloc(VNULL, 1, sizeof(Vpmgp) );
00076     VASSERT( thee != VNULL);
00077     VASSERT(Vpmgp_ctor2(thee,mgparm));
00078 
00079     return thee;
00080 }
00081 
00082 /* ///////////////////////////////////////////////////////////////////////////
00083 // Routine:  Vpmgp_ctor2
00084 //
00085 // Author:   Nathan Baker
00087 VPUBLIC int Vpmgp_ctor2(Vpmgp *thee,MGparm *mgparm) {
00088  
00089  /* Specified parameters */
00090     thee->nx = mgparm->dime[0];
00091     thee->ny = mgparm->dime[1];
00092     thee->nz = mgparm->dime[2];
00093     thee->hx = mgparm->grid[0];
00094     thee->hy = mgparm->grid[1];
00095     thee->hzed = mgparm->grid[2];
00096     thee->xlen = ((double)(mgparm->dime[0]-1))*mgparm->grid[0];
00097     thee->ylen = ((double)(mgparm->dime[1]-1))*mgparm->grid[1];
00098     thee->zlen = ((double)(mgparm->dime[2]-1))*mgparm->grid[2];
00099     thee->nlev = mgparm->nlev;
00100  
00101     thee->nonlin = mgparm->nonlintype;
00102  thee->meth = mgparm->method;
00103  
00104 #ifdef DEBUG_MAC_OSX_OCL
00105 #include "mach_chud.h"
00106  if(kOpenCLAvailable)
00107   thee->meth = 4;
00108 #endif
00109  
00110     if (thee->nonlin == NONLIN_LPBE) thee->ipkey = IPKEY_LPBE; /* LPBE case */
00111  else if(thee->nonlin == NONLIN_SMPBE) thee->ipkey = IPKEY_SMPBE; /* SMPBE case */
00112     else thee->ipkey = IPKEY_NPBE; /* NPBE standard case */
00113  
00114     /* Default parameters */
00115     if (mgparm->setetol) { /* If etol is set by the user in APBS input file, then use this custom-defined etol */
00116         thee->errtol = mgparm->etol; 
00117         Vnm_print(1, "  Error tolerance (etol) is now set to user-defined \
00118 value: %g \n", thee->errtol);
00119         Vnm_print(0, "Error tolerance (etol) is now set to user-defined \
00120 value: %g \n", thee->errtol);
00121     } else thee->errtol = 1.0e-6;   /* Here are a few comments.  Mike had this set to
00122   * 1e-9; convential wisdom sets this at 1e-6 for
00123   * the PBE; Ray Luo sets this at 1e-3 for his
00124   * accelerated PBE (for dynamics, etc.) */
00125     thee->itmax = 200;
00126     thee->istop = 1;
00127     thee->iinfo = 1;         /* I'd recommend either 1 (for debugging LPBE) or 2 (for debugging NPBE), higher values give too much output */
00128  
00129     thee->bcfl = BCFL_SDH;
00130     thee->key = 0;
00131     thee->iperf = 0;
00132  thee->mgcoar = 2;
00133  thee->mgkey = 0;
00134  thee->nu1 = 2;
00135  thee->nu2 = 2;
00136  thee->mgprol = 0;
00137  thee->mgdisc = 0;
00138  thee->omegal = 19.4e-1;
00139  thee->omegan = 9.0e-1;
00140  thee->ipcon = 3;
00141  thee->irite = 8;
00142  thee->xcent = 0.0;
00143  thee->ycent = 0.0;
00144  thee->zcent = 0.0;
00145  
00146  /* Default value for all APBS runs */
00147  thee->mgsmoo = 1;
00148     if (thee->nonlin == NONLIN_NPBE || thee->nonlin == NONLIN_SMPBE) { 
00149   /* SMPBE Added - SMPBE needs to mimic NPBE */
00150   Vnm_print(0, "Vpmp_ctor2:  Using meth = 1, mgsolv = 0\n");
00151         thee->mgsolv = 0;
00152  } else {        
00153   /* Most rigorous (good for testing) */
00154   Vnm_print(0, "Vpmp_ctor2:  Using meth = 2, mgsolv = 1\n");
00155         thee->mgsolv = 1;
00156     }
00157 
00158  /* TEMPORARY USEAQUA */
00159  /* If we are using aqua, our solution method is either VSOL_CGMGAqua or VSOL_NewtonAqua
00160   * so we need to temporarily override the mgsolve value and set it to 0
00161   */
00162  if(mgparm->useAqua == 1) thee->mgsolv = 0;
00163  
00164  return 1;
00165 }
00166 
00167 /* ///////////////////////////////////////////////////////////////////////////
00168 // Routine:  Vpmgp_dtor
00169 //
00170 // Author:   Nathan Baker
00172 VPUBLIC void Vpmgp_dtor(Vpmgp **thee) {
00173     
00174     if ((*thee) != VNULL) {
00175         Vpmgp_dtor2(*thee);
00176         Vmem_free(VNULL, 1, sizeof(Vpmgp), (void **)thee);
00177         (*thee) = VNULL;
00178     }
00179 
00180 }
00181 
00182 /* ///////////////////////////////////////////////////////////////////////////
00183 // Routine:  Vpmgp_dtor2
00184 //
00185 // Author:   Nathan Baker
00187 VPUBLIC void Vpmgp_dtor2(Vpmgp *thee) { ; }
00188 
00189 
00190 VPUBLIC void Vpmgp_size(
00191  Vpmgp *thee
00192  )
00193 {
00194 
00195  int num_nf = 0;
00196  int num_narr = 2;
00197  int num_narrc = 27;
00198  int nxf, nyf, nzf, level, num_nf_oper, num_narrc_oper, n_band, nc_band, num_band, iretot;
00199 
00200  thee->nf = thee->nx * thee->ny * thee->nz;
00201  thee->narr = thee->nf;
00202  nxf = thee->nx;
00203  nyf = thee->ny;
00204  nzf = thee->nz;
00205  thee->nxc = thee->nx;
00206  thee->nyc = thee->ny;
00207  thee->nzc = thee->nz;
00208 
00209  for (level=2; level<=thee->nlev; level++) {
00210   Vpmgp_makeCoarse(1, nxf, nyf, nzf, &(thee->nxc), &(thee->nyc), &(thee->nzc)); /* NAB TO-DO -- implement this function and check which variables need to be passed by reference... */
00211   nxf = thee->nxc;
00212   nyf = thee->nyc;
00213   nzf = thee->nzc;
00214   thee->narr = thee->narr + (nxf * nyf * nzf);
00215  }
00216 
00217  thee->nc = thee->nxc * thee->nyc * thee->nzc;
00218  thee->narrc = thee->narr - thee->nf;
00219 
00220  /* Box or FEM discretization on fine grid? */
00221  switch (thee->mgdisc) { /* NAB TO-DO:  This needs to be changed into an enumeration */
00222  case 0:
00223   num_nf_oper = 4;
00224   break;
00225  case 1:
00226   num_nf_oper = 14;
00227   break;
00228  default:
00229   Vnm_print(2, "Vpmgp_size:  Invalid mgdisc value (%d)!\n", thee->mgdisc);
00230   VASSERT(0);
00231  }
00232 
00233  /* Galerkin or standard coarsening? */
00234  switch (thee->mgcoar) { /* NAB TO-DO:  This needs to be changed into an enumeration */
00235  case 0:
00236   if (thee->mgdisc != 0) {
00237    Vnm_print(2, "Vpmgp_size:  Invalid mgcoar value (%d); must be used with mgdisc 0!\n", thee->mgcoar);
00238    VASSERT(0);
00239   }
00240   num_narrc_oper = 4;
00241   break;
00242  case 1:
00243   if (thee->mgdisc != 0) {
00244    Vnm_print(2, "Vpmgp_size:  Invalid mgcoar value (%d); must be used with mgdisc 0!\n", thee->mgcoar);
00245    VASSERT(0);
00246   }
00247   num_narrc_oper = 14;
00248   break;
00249  case 2:
00250   num_narrc_oper = 14;
00251   break;
00252  default:
00253   Vnm_print(2, "Vpmgp_size:  Invalid mgcoar value (%d)!\n", thee->mgcoar);
00254   VASSERT(0);
00255  }
00256 
00257  /* LINPACK storage on coarse grid */
00258  switch (thee->mgsolv) { /* NAB TO-DO:  This needs to be changed into an enumeration */
00259  case 0:
00260   n_band = 0;
00261   break;
00262  case 1:
00263   if ( ( (thee->mgcoar == 0) || (thee->mgcoar == 1)) && (thee->mgdisc == 0) ) {
00264    num_band = 1 + (thee->nxc-2)*(thee->nyc-2);
00265   } else {
00266    num_band = 1 + (thee->nxc-2)*(thee->nyc-2) + (thee->nxc-2) + 1;
00267   }
00268   nc_band = (thee->nxc-2)*(thee->nyc-2)*(thee->nzc-2);
00269   n_band  = nc_band * num_band;
00270   break;
00271  default:
00272   Vnm_print(2, "Vpmgp_size:  Invalid mgsolv value (%d)!\n", thee->mgsolv);
00273   VASSERT(0);
00274  }
00275  
00276  /* Real storage parameters */
00277  thee->n_rpc = 100*(thee->nlev+1);
00278 
00279  /* Resulting total required for real storage */
00280  thee->nrwk = num_narr*thee->narr + (num_nf + num_nf_oper)*thee->nf + (num_narrc + num_narrc_oper)*thee->narrc + n_band + thee->n_rpc;
00281 
00282  /* Integer storage parameters */
00283  thee->n_iz = 50*(thee->nlev+1);
00284  thee->n_ipc = 100*(thee->nlev+1);
00285  thee->niwk = thee->n_iz + thee->n_ipc;
00286 }
00287 
00288 VPRIVATE int coarsenThis(nOld) {
00289 
00290  int nOut;
00291 
00292  nOut = (nOld - 1) / 2 + 1;
00293 
00294  if (((nOut-1)*2) != (nOld-1)) {
00295   Vnm_print(2, "Vpmgp_makeCoarse:  Warning!  The grid dimensions you have chosen are not consistent with the nlev you have specified!\n");
00296   Vnm_print(2, "Vpmgp_makeCoarse:  This calculation will only work if you are running with mg-dummy type.\n");
00297  }
00298  if (nOut < 1) {
00299   Vnm_print(2, "D'oh!  You coarsened the grid below zero!  How did you do that?\n");
00300   VASSERT(0);
00301  }
00302 
00303  return nOut;
00304 }
00305 
00306 VPUBLIC void Vpmgp_makeCoarse(
00307  int numLevel,
00308  int nxOld,
00309  int nyOld,
00310  int nzOld,
00311  int *nxNew,
00312  int *nyNew,
00313  int *nzNew
00314  )
00315 {
00316  int nxtmp, nytmp, nztmp, iLevel;
00317 
00318  for (iLevel=0; iLevel<numLevel; iLevel++) {
00319   nxtmp = *nxNew;
00320   nytmp = *nyNew;
00321   nztmp = *nzNew;
00322   *nxNew = coarsenThis(nxtmp);
00323   *nyNew = coarsenThis(nytmp);
00324   *nzNew = coarsenThis(nztmp);
00325  }
00326 
00327 
00328 }

Generated on Wed Oct 20 2010 12:01:34 for APBS by  doxygen 1.7.2