Beispiel #1
0
// ---
void QGAMES::ObjectBuilder::preLoad ()
{
	if (_alreadyLoaded)
		return;

	TiXmlDocument doc (_fileName.c_str ());
	int e = doc.LoadFile ();
	assert (e); // Is it a valid doc?
	TiXmlElement* rootElement = doc.RootElement ();
	assert (rootElement); // One element minimum...

	// Reading all elements...
	for (TiXmlElement* groupElement = rootElement -> FirstChildElement ();
		groupElement != NULL; groupElement = groupElement -> NextSiblingElement ())
	{
		QGAMES::Object* obj = NULL;
		if (strcmp (groupElement -> Value (), __QGAMES_IMAGEBLOCK__) == 0)
			obj = readImage (groupElement); // An image...
		if (strcmp (groupElement -> Value (), __QGAMES_BACKGROUNDBLOCK__) == 0)
			obj = readBackground (groupElement); // A background...
		if (strcmp (groupElement -> Value (), __QGAMES_POLYLINEBLOCK__) == 0)
			obj = readGraphicalPolyline (groupElement); // A Polyline...
		if (strcmp (groupElement -> Value (), __QGAMES_POLYGONBLOCK__) == 0)
			obj = readGraphicalPolygon (groupElement); // A Polygon...
		if (strcmp (groupElement -> Value (), __QGAMES_ELLIPSEBLOCK__) == 0)
			obj = readEllipse (groupElement); // An ellipse...
		if (strcmp (groupElement -> Value (), __QGAMES_COMPOSITEBLOCK__) == 0)
			obj = readComposite (groupElement); // A composite made up of all of them...
		assert (obj != NULL);
		_objects.insert (std::map <int, QGAMES::Object*>::value_type (obj -> id (), obj));
	}

	_alreadyLoaded = true;
}
Beispiel #2
0
int main(int argc, char *argv[])
{
  register int n, k;

  char    rayFileName[14], inputLine[MAX_LINE_SIZE];
  bool_t  result, exit_on_EOF, to_obs, initialize, crosscoupling,
          analyze_output, equilibria_only;
  int     Nspect, Nread, Nrequired, checkPoint, *wave_index = NULL;
  double  muz, *S, *chi, *J;
  FILE   *fp_out, *fp_ray, *fp_stokes;
  XDR     xdrs;
  ActiveSet *as;

  setOptions(argc, argv);
  getCPU(0, TIME_START, NULL);
  SetFPEtraps();

  /* --- Read input data and initialize --             -------------- */

  readInput();
  spectrum.updateJ = FALSE;

  /* --- Read input data for atmosphere --             -------------- */

  getCPU(1, TIME_START, NULL);
  MULTIatmos(&atmos, &geometry);

  /* --- Read direction cosine for ray --              -------------- */

  if ((fp_ray = fopen(RAY_INPUT_FILE, "r")) == NULL) {
    sprintf(messageStr, "Unable to open inputfile %s", RAY_INPUT_FILE);
    Error(ERROR_LEVEL_2, argv[0], messageStr);
  }
  
  getLine(fp_ray, COMMENT_CHAR, inputLine, exit_on_EOF=TRUE);
  Nread = sscanf(inputLine, "%lf", &muz);
  checkNread(Nread, Nrequired=1, argv[0], checkPoint=1);

  if (muz <= 0.0  ||  muz > 1.0) {
    sprintf(messageStr,
	    "Value of muz = %f does not lie in interval <0.0, 1.0]\n", muz);
    Error(ERROR_LEVEL_2, argv[0], messageStr);
  }

  if (input.StokesMode == FIELD_FREE ||
      input.StokesMode == POLARIZATION_FREE) {
    input.StokesMode = FULL_STOKES;
  }
  /* --- redefine geometry for just this one ray --    -------------- */

  atmos.Nrays = geometry.Nrays = 1;
  geometry.muz[0] = muz;
  geometry.mux[0] = sqrt(1.0 - SQ(geometry.muz[0]));
  geometry.muy[0] = 0.0;
  geometry.wmu[0] = 1.0;
  if (atmos.Stokes) Bproject();

  input.startJ = OLD_J;

  readAtomicModels();
  readMolecularModels();
  SortLambda();

  getBoundary(&geometry);

  /* --- Open file with background opacities --        -------------- */

  if (atmos.moving || input.StokesMode) {
    strcpy(input.background_File, "background.ray");
    Background(analyze_output=FALSE, equilibria_only=FALSE);
  } else {
    Background(analyze_output=FALSE, equilibria_only=TRUE);

    if ((atmos.fd_background =
	 open(input.background_File, O_RDONLY, 0)) == -1) {
      sprintf(messageStr, "Unable to open inputfile %s",
	      input.background_File);
      Error(ERROR_LEVEL_2, argv[0], messageStr);
    }
    readBRS();
  }
  convertScales(&atmos, &geometry);

  getProfiles();
  initSolution();
  initScatter();

  getCPU(1, TIME_POLL, "Total initialize");

  /* --- Solve radiative transfer equations --         -------------- */

  solveSpectrum(FALSE, FALSE);

  /* --- Write emergent spectrum to output file --     -------------- */
 
  sprintf(rayFileName, "spectrum_%4.2f", muz);
  if ((fp_out = fopen(rayFileName, "w" )) == NULL) {
    sprintf(messageStr, "Unable to open output file %s", rayFileName);
    Error(ERROR_LEVEL_2, argv[0], messageStr);
  }
  xdrstdio_create(&xdrs, fp_out, XDR_ENCODE);

  result = xdr_double(&xdrs, &muz);
  result = xdr_vector(&xdrs, (char *) spectrum.I[0], spectrum.Nspect,
		      sizeof(double), (xdrproc_t) xdr_double);

  /* --- Read wavelength indices for which chi and S are to be
         written out for the specified direction --    -------------- */

  Nread = fscanf(fp_ray, "%d", &Nspect);
  checkNread(Nread, 1, argv[0], checkPoint=2);

  if (Nspect > 0) {
    wave_index = (int *) malloc(Nspect * sizeof(int));
    Nread = 0;
    while (fscanf(fp_ray, "%d", &wave_index[Nread]) != EOF) Nread++;
    checkNread(Nread, Nspect, argv[0], checkPoint=3);
    fclose(fp_ray);

    chi = (double *) malloc(atmos.Nspace * sizeof(double));
    if (atmos.Stokes)
      S = (double *) malloc(4 * atmos.Nspace * sizeof(double));
    else
      S = (double *) malloc(atmos.Nspace * sizeof(double));
  }
  result = xdr_int(&xdrs, &Nspect);

  /* --- Go through the list of wavelengths --         -------------- */

  if (Nspect > 0  &&  input.limit_memory)
    J = (double *) malloc(atmos.Nspace * sizeof(double));

  for (n = 0;  n < Nspect;  n++) {
    if (wave_index[n] < 0  ||  wave_index[n] >= spectrum.Nspect) {
      sprintf(messageStr, "Illegal value of wave_index[n]: %4d\n"
	      "Value has to be between 0 and %4d\n", 
	      wave_index[n], spectrum.Nspect);
      Error(ERROR_LEVEL_2, argv[0], messageStr);
      continue;
    }
    sprintf(messageStr, "Processing n = %4d, lambda = %9.3f [nm]\n",
	    wave_index[n], spectrum.lambda[wave_index[n]]);
    Error(MESSAGE, NULL, messageStr);

    as = &spectrum.as[wave_index[n]];
    alloc_as(wave_index[n], crosscoupling=FALSE);
    Opacity(wave_index[n], 0, to_obs=TRUE, initialize=TRUE);
    readBackground(wave_index[n], 0, to_obs=TRUE);

    if (input.limit_memory) {
      readJlambda(wave_index[n], J);
    } else
      J = spectrum.J[wave_index[n]];

    /* --- Add the continuum opacity and emissivity -- -------------- */   

    for (k = 0;  k < atmos.Nspace;  k++) {
      chi[k] = as->chi[k] + as->chi_c[k];
      S[k]   = (as->eta[k] + as->eta_c[k] + as->sca_c[k]*J[k]) / chi[k];
    }
    result = xdr_int(&xdrs, &wave_index[n]);
    result = xdr_vector(&xdrs, (char *) chi, atmos.Nspace,
			sizeof(double), (xdrproc_t) xdr_double);
    result = xdr_vector(&xdrs, (char *) S, atmos.Nspace,
			sizeof(double), (xdrproc_t) xdr_double);

    free_as(wave_index[n], crosscoupling=FALSE);
  }

  /* --- If magnetic fields are present --             -------------- */
  
  if (atmos.Stokes || input.backgr_pol) {
    result = xdr_vector(&xdrs, (char *) spectrum.Stokes_Q[0],
			spectrum.Nspect, sizeof(double),
			(xdrproc_t) xdr_double);
    result = xdr_vector(&xdrs, (char *) spectrum.Stokes_U[0],
			spectrum.Nspect, sizeof(double),
			(xdrproc_t) xdr_double);
    result = xdr_vector(&xdrs, (char *) spectrum.Stokes_V[0],
			spectrum.Nspect, sizeof(double),
			(xdrproc_t) xdr_double);
  }

  if (Nspect > 0  &&  input.limit_memory)
    free(J);

  xdr_destroy(&xdrs);
  fclose(fp_out);
  printTotalCPU();
}
Beispiel #3
0
Datei: escape.c Projekt: kouui/rh
/* ------- begin ----------------------------- Escape ------------------- */
void Escape(Atom *atom) {
    /*
      
      Calculates radiative rates using the escape probability approximation

      
      Notes: Escape is inserted in an atom loop. Whatever takes place here should be at
             atom-only level. Why? Because different atoms can have different starting solutions.
             Calling Opacity directly is probably overkill, as it does its own loops, and
             works per wavelength, not per atom.
             
              The line opacity has to be per transition, and thus averaged in wavelength.
              For bound-bound the procedure is the following:
                 
              1. Loop over wavelength to calculate opacity at all wavelengths. Keep an
                 array for each transition, accumulate there the opacity * wla for each
                 transition. (this opacity is depth-dependent as well)
                    
              2. Loop over transitions (and not wavelength!), calculate tau by integrating
                 over depth for each transition
                    
              3. Once we have tau for each transition, add to the gamma of each transition
                 (in the same loop) the nrb recipe.
                    
              For bound-free the procedure is the following:
              
              1. Calculate intensity only for the relevant wavelenths.
              
              2. Using intensity, calculate proper radiative rates and add them to rate matrix.
              
              
    Notes for continuum:

          * To see how rates are added, look at fillgamma.addtoRates or fillgamma.addtoGamma
          * For a simplified version of how to calculate intensity and update rates, look
            at formal.c:233 (the angle-independent case). They could be calculated by a single
            call of Formal, but there is too much rubbish in the main routine, and it could
            call opacity and readbackground more than once -- duplicating many tasks.
      
      
    */
    
    
    const char routineName[] = "Escape";
    register int     n, k, kr, i, ij, ji, nspect;
    int              la, j, nt,  mu, nact;
    double         **opa, *chi, *I, *S, *Psi, *Jdag, *J, tau, wlambda, hc_4PI, twohc,
                     twohnu3_c2, wmu, wlamu, Ieff;
    bool_t           initialize, to_obs;
    ActiveSet       *as;
    AtomicLine      *line;
    AtomicContinuum *continuum;
    
    
    /* --- Some useful constants --                        -------------- */
    hc_4PI = HPLANCK * CLIGHT / (4.0 * PI);
    twohc = 2.0*HPLANCK*CLIGHT / CUBE(NM_TO_M);
    

    opa  = matrix_double(atom->Nline, atmos.Nspace);
    Jdag = (double *) malloc(atmos.Nspace * sizeof(double));
    Psi  = (double *) malloc(atmos.Nspace * sizeof(double));
    chi  = (double *) malloc(atmos.Nspace * sizeof(double));
    I    = (double *) malloc(atmos.Nspace * sizeof(double));
    S    = (double *) malloc(atmos.Nspace * sizeof(double));


    nact = atom->activeindex;
    
    /* Calculate opacities */
    for (nspect = 0;  nspect < spectrum.Nspect;  nspect++) { 
        as = spectrum.as + nspect;
        alloc_as(nspect, FALSE);
        
        nt = nspect % input.Nthreads;

        /* Get line and background opacity */
        Opacity(nspect, 0, to_obs=TRUE, initialize=TRUE); 

	if (input.backgr_in_mem) {
	  loadBackground(nspect, 0, to_obs=TRUE);
	} else {
	  readBackground(nspect, 0, to_obs=TRUE);
	}
        
        /* --- For bound-bound: store opacity in array, per transition -- */
        for (kr = 0; kr < atom->Nline; kr++) {
            line = atom->line + kr;
            la = nspect - line->Nblue;
            
            if (la == 0)
                wlambda = getwlambda_line(line, la);
                
            if ((la >= 0) && (la < line->Nlambda)) {
                /* increment opacities with each wavelength, multiplying by the
                   integration weights */
                for (k = 0 ; k < atmos.Nspace; k++) 
                    opa[kr][k] += (as->chi[k] + as->chi_c[k]) * (wlambda * line->wphi[k] /
                                                                    hc_4PI);
            }
        }
        
        /* --- For bound-free: calculate intensity and update rates ----- */        
        for (n = 0;  n < as->Nactiveatomrt[nact];  n++) {      
            if (as->art[nact][n].type == ATOMIC_CONTINUUM) {
                
                continuum = as->art[nact][n].ptype.continuum;
                la = nspect - continuum->Nblue;
                i = continuum->i;
                j = continuum->j;
                ij = i*atom->Nlevel + j;
                ji = j*atom->Nlevel + i;
                
                twohnu3_c2 = twohc / CUBE(spectrum.lambda[nspect]);
                
                /* Use old J and zero new array */
                if (input.limit_memory) {
                    J = (double *) malloc(atmos.Nspace *sizeof(double));
                    //readJlambda_single(nspect, Jdag);
                } else {
                    J = spectrum.J[nspect];
                    for (k = 0;  k < atmos.Nspace;  k++) Jdag[k] = J[k];
                }
                for (k = 0;  k < atmos.Nspace;  k++) J[k] = 0.0;
                
                for (mu = 0; mu < atmos.Nrays; mu++) {
                    wmu = 0.5 * geometry.wmu[mu];
                        
                    for (k = 0;  k < atmos.Nspace;  k++) {
                        chi[k] = as->chi[k] + as->chi_c[k];
                        S[k]   = (as->eta[k] +
                            as->eta_c[k] + as->sca_c[k]*Jdag[k]) / chi[k];
                    } 
                     
                    /* Get intensity */
                    Piecewise_1D(nspect, mu, to_obs=TRUE, chi, S, I, Psi);
                    
                    /* Update rates */
                    for (k = 0;  k < atmos.Nspace;  k++) {
                        
                        Ieff = I[k] - Psi[k] * atom->rhth[nt].eta[k];
                        wlamu = atom->rhth[nt].Vij[n][k] * atom->rhth[nt].wla[n][k] * wmu;
                        
                        atom->Gamma[ji][k] += Ieff * wlamu;
                        atom->Gamma[ij][k] += (twohnu3_c2 + Ieff) * atom->rhth[nt].gij[n][k] * wlamu;
                        
                        /*  Accumulate mean intensity */
                        J[k] += wmu * I[k];
                    }                    
                }
                if (input.limit_memory) free(J);
            }
        }
        
        free_as(nspect, FALSE);
    }  

    /* Bound-bound: calculate optical depth and add approximation to rates */  
    for (kr = 0; kr < atom->Nline; kr++) {
        line = atom->line + kr;
        i  = line->i;
        j  = line->j;
        ij = i*atom->Nlevel + j;

        tau = 0.0;
        
        for (k = 0; k < atmos.Nspace ; k++) {
            if (k > 0) {
                tau += 0.5*(opa[kr][k-1] + opa[kr][k]) *
                    (geometry.height[k-1] - geometry.height[k]);
            }
            
            /* add escape probability approximation to the rates matrix */
            atom->Gamma[ij][k] += line->Aji * Pesc(tau);   
        }

    }
    
    freeMatrix((void **) opa);
    free(Jdag);
    free(chi);
    free(Psi);
    free(I);
    free(S);
}
Beispiel #4
0
void convertScales(Atmosphere *atmos, Geometry *geometry)
{
  register int k;

  bool_t hunt;
  int    ref_index, Ndep = geometry->Ndep;
  double *rho, *height, *cmass, *tau_ref, h_zero, unity;
  ActiveSet *as;

  /* --- Convert between different depth scales --       ------------ */

  height  = geometry->height;
  cmass   = geometry->cmass;
  tau_ref = geometry->tau_ref;

  rho = (double *) malloc(Ndep * sizeof(double));
  for (k = 0;  k < Ndep;  k++)
    rho[k] = (AMU * atmos->wght_per_H) * atmos->nHtot[k];

  /* --- Get opacity of reference wavelength --          ------------ */

  Locate(spectrum.Nspect, spectrum.lambda, atmos->lambda_ref, &ref_index);

  as = &spectrum.as[ref_index];
  alloc_as(ref_index, FALSE);
  readBackground(ref_index, 0, 0);

  /* --- Convert to missing depth scales --              ------------ */

  switch (geometry->scale) {
  case COLUMN_MASS:
    height[0] = 0.0;
    tau_ref[0] = as->chi_c[0] / rho[0] * cmass[0];
    for (k = 1;  k < Ndep;  k++) {
      height[k] = height[k-1] - 2.0*(cmass[k] - cmass[k-1]) / 
	(rho[k-1] + rho[k]);
      tau_ref[k] = tau_ref[k-1] + 0.5*(as->chi_c[k-1] + as->chi_c[k]) *
	(height[k-1] - height[k]);
    }
    break;
  case TAU500:
    height[0] = 0.0;
    cmass[0]  = (tau_ref[0] / as->chi_c[0]) * rho[0];
    for (k = 1;  k < Ndep;  k++) {
      height[k] = height[k-1] - 2.0 * (tau_ref[k] - tau_ref[k-1]) / 
	(as->chi_c[k-1] + as->chi_c[k]);
      cmass[k]  = cmass[k-1]  + 0.5*(rho[k-1] + rho[k]) *
	(height[k-1] - height[k]);
    }
    break;
  case GEOMETRIC:
    cmass[0] = (atmos->nHtot[0] * atmos->totalAbund + atmos->ne[0]) *
      (KBOLTZMANN * atmos->T[0] / atmos->gravity);
    tau_ref[0] = 0.5 * as->chi_c[0] * (height[0] - height[1]);
    if (tau_ref[0] > 1.0) tau_ref[0] = 0.0;
    for (k = 1;  k < Ndep;  k++) {
      cmass[k]  = cmass[k-1]  + 0.5*(rho[k-1] + rho[k]) *
	(height[k-1] - height[k]);
      tau_ref[k] = tau_ref[k-1] + 0.5*(as->chi_c[k-1] + as->chi_c[k]) *
	(height[k-1] - height[k]);
    }
    break;
  }
  free_as(ref_index, FALSE);

  if ((geometry->scale == COLUMN_MASS) || (geometry->scale == TAU500)) {
    unity = 1.0;
    Linear(Ndep, tau_ref, height, 1, &unity, &h_zero, hunt=FALSE);
    for (k = 0;  k < Ndep;  k++) height[k] = height[k] - h_zero;
  }

  free(rho);
}