Exemple #1
0
 void Ref::Call(CallHelper& call) const
 {
     this->ToStack();
     if (!lua_isfunction(this->_state, -1))
     {
         lua_pop(this->_state, 1);
         throw std::runtime_error("Luasel::Ref: Calling a value that is not a function");
     }
     call.ClearRets();
     auto const& args = call.GetArgList();
     if (!lua_checkstack(this->_state, (int)args.size()))
     {
         lua_pop(this->_state, 1);
         throw std::runtime_error("Luasel::Ref: Insufficient Lua stack size for arguments");
     }
     auto it = args.rbegin();
     auto itEnd = args.rend();
     for (; it != itEnd; ++it)
         it->ToStack();
     if (lua_pcall(this->_state, static_cast<int>(args.size()), LUA_MULTRET, 0))
     {
         std::string e = "Luasel::Ref: Error in function call: ";
         e += lua_tostring(this->_state, -1);
         lua_pop(this->_state, 1);
         throw std::runtime_error(e);
     }
     while (lua_gettop(this->_state))
     {
         Ref ret(this->_state);
         ret.FromStack();
         call.PushRet(ret);
     }
 }
void Rendezvous(long *nsrc0, double *wgt0)
{
#ifdef OLD_HIST
#ifdef MPI

  long n, ntot, *ntsk, *buf, ptr, i, i0, sz1, sz2, nhist, pth, id;
  double totwgt, *src1, *src2;

  /* Check mode */

  if ((long)RDB[DATA_OPTI_MPI_REPRODUCIBILITY] == NO)
    return;

  Die(FUNCTION_NAME, "Tää ei toimi uuden historiarakenteen kanssa");

  /* Check number of mpi tasks */

  if (mpitasks == 1)
    return;

  /* Start timers */

  StartTimer(TIMER_MPI_OVERHEAD);
  StartTimer(TIMER_MPI_OVERHEAD_TOTAL);

  /* Allocate memory for task-wise sizes */

  ntsk = (long *)Mem(MEM_ALLOC, mpitasks, sizeof(long));
  buf = (long *)Mem(MEM_ALLOC, mpitasks, sizeof(long));

  /* Put task-wise value */

  buf[mpiid] = *nsrc0;

  /* Reduce data */

  MPI_Barrier(MPI_COMM_WORLD);
  if (MPI_Reduce(buf, ntsk, mpitasks, MPI_LONG, MPI_SUM, 0, MPI_COMM_WORLD)
      != MPI_SUCCESS)
    Die(FUNCTION_NAME, "MPI Error");

  /* Broadcast data */

  MPI_Barrier(MPI_COMM_WORLD);
  if (MPI_Bcast(ntsk, mpitasks, MPI_LONG, 0, MPI_COMM_WORLD) != MPI_SUCCESS)
    Die(FUNCTION_NAME, "MPI Error");    

  /* Calculate total size */
      
  ntot = 0;
  for (n = 0; n < mpitasks; n++)
    ntot = ntot + ntsk[n];
    
  /* Free buffer */

  Mem(MEM_FREE, buf);

  /* Get size of particle and history data blocks */

  sz1 = PARTICLE_BLOCK_SIZE - LIST_DATA_SIZE;
  sz2 = HIST_BLOCK_SIZE - LIST_DATA_SIZE;

  /* Get size of history array */

  if ((nhist = (long)RDB[DATA_HIST_LIST_SIZE]) < 0)
    nhist = 0;

  /* Allocate memory for histories */

  src1 = Mem(MEM_ALLOC, (sz1 + nhist*sz2)*ntot, sizeof(double));
  
  /* Calculate starting point */

  i0 = 0;
  for (i = 0; i < mpiid; i++)
    i0 = i0 + ntsk[i]*(sz1 + nhist*sz2);

  /* Reset OpenMP id */

  id = 0;

  /* Loop over distribution and read data into block */
  
  while (1 != 2)
    {
      /* Pointer to source distribution */

      ptr = (long)RDB[DATA_PART_PTR_SOURCE];
      CheckPointer(FUNCTION_NAME, "(ptr)", DATA_ARRAY, ptr);
      
      /* Pointer to first after dummy */
      
      if ((ptr = NextItem(ptr)) < VALID_PTR)
	break;

      /* Remove particle from source */

      RemoveItem(ptr);

      /* Copy particle data */

      memcpy(&src1[i0], &RDB[ptr + LIST_DATA_SIZE], sz1*sizeof(double));

      /* Update pointer */

      i0 = i0 + sz1;

      /* Pointer to history data */

      pth = (long)RDB[ptr + PARTICLE_PTR_HIST];

      /* Loop over histories */

      for (i = 0; i < nhist; i++)
	{
	  /* Check pointer */

	  CheckPointer(FUNCTION_NAME, "(pth1)", DATA_ARRAY, pth);

	  /* Copy history data */

	  memcpy(&src1[i0], &RDB[pth + LIST_DATA_SIZE], sz2*sizeof(double));

	  /* Update pointer */

	  i0 = i0 + sz2;

	  /* Next */

	  pth = NextItem(pth);
	}

      /* Put particle in stack */

      ToStack(ptr, id++);

      /* Check OpenMP id */

      if (id > (long)RDB[DATA_OMP_MAX_THREADS] - 1)
	id = 0;
    }

  /* Allocate memory for temporary data */

  if (mpiid == 0)
    src2 = Mem(MEM_ALLOC, (sz1 + nhist*sz2)*ntot, sizeof(double));
  else
    src2 = NULL;

  /* Reduce data */

  MPI_Barrier(MPI_COMM_WORLD);
  MPITransfer(src1, src2, (sz1 + nhist*sz2)*ntot, 0, MPI_METH_RED);

  /* Move data back to original */

  if (mpiid == 0)
    memcpy(src1, src2, (sz1 + nhist*sz2)*ntot*sizeof(double));

  /* Free temporary array */

  if (mpiid == 0)
    Mem(MEM_FREE, src2);

  /* Broadcast data */

  MPI_Barrier(MPI_COMM_WORLD);
  MPITransfer(src1, NULL, (sz1 + nhist*sz2)*ntot, 0, MPI_METH_BC);

  /* Reset pointer and  OpenMP id */

  i0 = 0;
  id = 0;

  /* Read data back to source */

  for (n = 0; n < ntot; n++)
    {
      /* Get new particle from stack */

      ptr = FromStack(PARTICLE_TYPE_NEUTRON, id++);

      /* Check OpenMP id */

      if (id > (long)RDB[DATA_OMP_MAX_THREADS] - 1)
	id = 0;

      /* Get pointer to history data (done here to avoid overwrite) */

      pth = (long)RDB[ptr + PARTICLE_PTR_HIST];      

      /* Copy particle data */

      memcpy(&WDB[ptr + LIST_DATA_SIZE], &src1[i0], sz1*sizeof(double));

      /* Put pointer to history data */

      WDB[ptr + PARTICLE_PTR_HIST] = (double)pth;

      /* Update pointer */

      i0 = i0 + sz1;

      /* Loop over histories */

      for (i = 0; i < nhist; i++)
	{
	  /* Check pointer */

	  CheckPointer(FUNCTION_NAME, "(pth2)", DATA_ARRAY, pth);

	  /* Copy history data */

	  memcpy(&WDB[pth + LIST_DATA_SIZE], &src1[i0], sz2*sizeof(double));

	  /* Update pointer */

	  i0 = i0 + sz2;

	  /* Next */

	  pth = NextItem(pth);
	}      

      /* Put particle back to source */
      
      AddItem(DATA_PART_PTR_SOURCE, ptr);
    }

  /* Free memory */

  Mem(MEM_FREE, src1);
  Mem(MEM_FREE, ntsk);

  /* Calculate number of particles and total weight */
  
  totwgt = 0.0;
  n = 0;

  /* Pointer to first after dummy */

  ptr = (long)RDB[DATA_PART_PTR_SOURCE];
  CheckPointer(FUNCTION_NAME, "(ptr)", DATA_ARRAY, ptr);
  ptr = NextItem(ptr);

  /* Loop over remaining */

  while (ptr > VALID_PTR)
    {
      /* Add to counter and weight */

      n++;
      totwgt = totwgt + RDB[ptr + PARTICLE_WGT];

      /* Next */

      ptr = NextItem(ptr);
    }

  /* Check */

  if (n != ntot)
    Die(FUNCTION_NAME, "Error in count");

  /* Put values */

  *nsrc0 = ntot;
  *wgt0 = totwgt;

  MPI_Barrier(MPI_COMM_WORLD);

  /* Stop timers */

  StopTimer(TIMER_MPI_OVERHEAD);
  StopTimer(TIMER_MPI_OVERHEAD_TOTAL);

#endif
#endif
}
Exemple #3
0
long Collision(long mat, long part, double x, double y, double z, double *u, 
	       double *v, double *w, double *E, double *wgt, double t, long id)
{
  long type, rea, nuc, ptr, mt, scatt, icapt;
  double totxs, absxs, E0, u0, v0, w0, mu, wgt0, wgt1, wgt2, dE;

  /* Check input parameters */

  CheckPointer(FUNCTION_NAME, "(mat)", DATA_ARRAY, mat);
  CheckPointer(FUNCTION_NAME, "(part)", DATA_ARRAY, part);
  CheckValue(FUNCTION_NAME, "x", "", x, -INFTY, INFTY);
  CheckValue(FUNCTION_NAME, "y", "", y, -INFTY, INFTY);
  CheckValue(FUNCTION_NAME, "z", "", z, -INFTY, INFTY);
  CheckValue(FUNCTION_NAME, "cos", "", *u**u+*v**v+*w**w - 1.0, -1E-5, 1E-5);
  CheckValue(FUNCTION_NAME, "E", "", *E, ZERO, INFTY);
  CheckValue(FUNCTION_NAME, "t", "", t, ZERO, INFTY);
  CheckValue(FUNCTION_NAME, "wgt", "", *wgt, ZERO, INFTY);

  /* Get particle type */

  type = (long)RDB[part + PARTICLE_TYPE];

  /* Get pointer to total xs */

  if (type == PARTICLE_TYPE_NEUTRON)
    ptr = (long)RDB[mat + MATERIAL_PTR_TOTXS];
  else
    ptr = (long)RDB[mat + MATERIAL_PTR_TOTPHOTXS];
    
  /* Get implicit capture flag */

  icapt = (long)RDB[DATA_OPT_IMPL_CAPT];

  /* Get initial weight and reset others */

  wgt0 = *wgt;
  wgt1 = -1.0;
  wgt2 = -1.0;

  /* Remember values before collision */

  E0 = *E;
  u0 = *u;
  v0 = *v;
  w0 = *w;

  /* Reset change in change in particle energy */

  dE = E0;

  /* Weight reduction by implicit capture */

  if ((icapt == YES) && (type == PARTICLE_TYPE_NEUTRON))
    {
      /* Get total xs */

      totxs = TotXS(mat, type, *E, id);

      /* Get material total absorption xs (may be zero for He) */
      
      if ((ptr = (long)RDB[mat + MATERIAL_PTR_ABSXS]) > VALID_PTR)
	absxs = MacroXS(ptr, *E, id);
      else
	absxs = 0.0;

      /* Score capture reaction */

      ScoreCapture(mat, -1, wgt0*absxs/totxs, id);

      /* Calculate weight reduction */
      
      wgt1 = wgt0*(1.0 - absxs/totxs);
    }
  else
    wgt1 = wgt0;

  /* Sample reaction */

  if ((rea = SampleReaction(mat, type, *E, wgt1, id)) < VALID_PTR)
    {
      /* Sample rejected, set final weight */

      *wgt = wgt1;
      
      /* Score efficiency */

      ptr = (long)RDB[RES_REA_SAMPLING_EFF];
      CheckPointer(FUNCTION_NAME, "(ptr)", DATA_ARRAY, ptr);
      AddBuf1D(1.0, 1.0, ptr, id, 4 - type);
      
      /* Return virtual */

      return TRACK_END_VIRT;
    }
  else
    {
      /* Score efficiency */

      ptr = (long)RDB[RES_REA_SAMPLING_EFF];
      CheckPointer(FUNCTION_NAME, "(ptr)", DATA_ARRAY, ptr);
      AddBuf1D(1.0, 1.0, ptr, id, 2 - type);
    }

  /* Update collision index */

  WDB[part + PARTICLE_COL_IDX] = RDB[part + PARTICLE_COL_IDX] + 1.0;

  /* Pointer to nuclide */

  nuc = (long)RDB[rea + REACTION_PTR_NUCLIDE];
  CheckPointer(FUNCTION_NAME, "(nuc)", DATA_ARRAY, nuc);
  
  /* Produce photons */
  
  PhotonProd(nuc, x, y, z, *u, *v, *w, *E, *wgt, t, id);

  /* Get reaction mt */

  mt = (long)RDB[rea + REACTION_MT];

  /* Reset scattering flag */

  scatt = NO;

  /* Check particle type */

  if (type == PARTICLE_TYPE_NEUTRON)
    {
      /***********************************************************************/

      /***** Neutron reactions ***********************************************/

      /* Check reaction type */
      
      if (mt == 2)
	{
	  /* Check sampling */

	  if ((long)RDB[DATA_NPHYS_SAMPLE_SCATT] == NO)
	    return TRACK_END_SCAT;
	    
	  /* Elastic scattering */
	  
	  ElasticScattering(mat, rea, E, u, v, w, id);
	  
	  /* Set scattering flag and calculate change in energy */

	  scatt = YES;
	  dE = dE - *E;

	  /* Weight is preserved */

	  wgt2 = wgt1;
	}
      else if ((mt == 1002) || (mt == 1004))
	{
	  /* Check sampling */

	  if ((long)RDB[DATA_NPHYS_SAMPLE_SCATT] == NO)
	    return TRACK_END_SCAT;

	  /* Scattering by S(a,b) laws */ 
	  
	  SabScattering(rea, E, u, v, w, id);

	  /* Set scattering flag and calculate change in energy */

	  scatt = YES;
	  dE = dE - *E;

	  /* Weight is preserved */

	  wgt2 = wgt1;
	}
      else if ((mt == 2002) || (mt == 2004))
	{
	  /* S(a,b) scattering with on-the-fly interpolation */

	 /* Check sampling */

	 if ((long)RDB[DATA_NPHYS_SAMPLE_SCATT] == NO)
	   return TRACK_END_SCAT;

	 /* Scattering by S(a,b) laws */ 
	 
	 OTFSabScattering(rea, E, u, v, w, id);

	  /* Set scattering flag and calculate change in energy */

	  scatt = YES;
	  dE = dE - *E;
	 
	 /* Weight is preserved */
	 
	 wgt2 = wgt1;
	}
      else if (RDB[rea + REACTION_TY] == 0.0)
	{
	  /* Capture */

	  if (icapt == YES)
	    {
	      /* Not possible in implicit mode */

	      Die(FUNCTION_NAME, "Capture reaction in implicit mode");
	    }
	  else if ((long)RDB[DATA_NPHYS_SAMPLE_CAPT] == NO)
	    {
	      /* Not sampled, return scattering */

	      return TRACK_END_SCAT;
	    }
	  else
	    {
	      /* Score capture reaction */

	      ScoreCapture(mat, rea, wgt1, id);

	      /* Put particle back in stack */
	      
	      ToStack(part, id);
	      
	      /* Exit subroutine */

	      return TRACK_END_CAPT;
	    }
	}
      else if (fabs(RDB[rea + REACTION_TY]) > 100.0)
	{
	  /* Complex reaction */

	  ComplexRea(rea, part, E, x, y, z, u, v, w, wgt1, &wgt2, t, &dE, id);

	  /* Check weight */

	  if (wgt2 > 0.0)
	    {
	      /* Set scattering */

	      scatt = YES;
	    }
	  else
	    {
	      /* Score capture reaction */

	      ScoreCapture(mat, rea, wgt1, id);

	      /* Put particle back in stack */
	      
	      ToStack(part, id);
	      
	      /* Exit subroutine */

	      return TRACK_END_CAPT;
	    }
	}
      else if (((mt > 17) && (mt < 22)) || (mt == 38))
	{
	  /* Check sampling */

	  if ((long)RDB[DATA_NPHYS_SAMPLE_FISS] == NO)
	    {
	      /* Tätä muutettiin 18.7.2013 / 2.1.15 sillai että   */
	      /* readacefile.c:ssä fission TY laitetaan nollaksi, */
	      /* eli koko listaa ei pitäisi luoda. */

	      Die(FUNCTION_NAME, "Shouldn't be here");

	      /* Check if capture is sampled */

	      if ((long)RDB[DATA_NPHYS_SAMPLE_CAPT] == NO)
		return TRACK_END_SCAT;
	      else
		{
		  /* Put particle back in stack */
		  
		  ToStack(part, id);
		  
		  /* Exit subroutine */
		  
		  return TRACK_END_CAPT;
		}
	    }

	  /* Sample fission */
	  
	  Fission(mat, rea, part, E, t, x, y, z, u, v, w, wgt1, &wgt2, id);
	  
	  /* Put particle back in stack */
	      
	  ToStack(part, id);
	  
	  /* Exit subroutine */
	  
	  return TRACK_END_FISS;
	}
      else if ((mt > 50) && (mt < 91))
	{
	  /* Check sampling */

	  if ((long)RDB[DATA_NPHYS_SAMPLE_SCATT] == NO)
	    return TRACK_END_SCAT;

	  /* Inelastic level scattering */

	  LevelScattering(rea, E, u, v, w, id);

	  /* Set scattering flag and calculate change in energy */

	  scatt = YES;
	  dE = dE - *E;

	  /* Weight is preserved */

	  wgt2 = wgt1;
	}
      else if (RDB[rea + REACTION_WGT_F] > 1.0)
	{
	  /* Check sampling */

	  if ((long)RDB[DATA_NPHYS_SAMPLE_SCATT] == NO)
	    return TRACK_END_SCAT;
	  
	  /* Multiplying scattering reaction */

	  Nxn(rea, part, E, x, y, z, u, v, w, wgt1, &wgt2, t, &dE, id);

	  /* Set scattering flag */

	  scatt = YES;
	}
      else if (mt < 100)
	{
	  /* Check sampling */

	  if ((long)RDB[DATA_NPHYS_SAMPLE_SCATT] == NO)
	    return TRACK_END_SCAT;

	  /* Continuum single neutron reactions */

	  InelasticScattering(rea, E, u, v, w, id);

	  /* Set scattering flag and calculate change in energy */

	  scatt = YES;
	  dE = dE - *E;

	  /* Weight is preserved */

	  wgt2 = wgt1;
	}
      else
	{
	  /* Unknown reaction mode */
	  
	  Die(FUNCTION_NAME, "Unknown reaction mode %ld sampled", mt);
	}

      /***********************************************************************/
    }
  else
    {
      /***** Photon reactions ************************************************/

      if (mt == 504)
	{
	  /* Incoherent (Compton) scattering */

	  ComptonScattering(mat, rea, part, E, x, y, z, u, v, w, *wgt, t, id);

	  /* Set scattering flag and calculate change in energy */

	  scatt = YES;
	  dE = dE - *E;
	}
      else if (mt == 502)
	{
	  /* Coherent (Rayleigh) scattering */

	  RayleighScattering(rea, *E, u, v, w, id);

	  /* Set scattering flag and calculate change in energy */

	  scatt = YES;
	  dE = dE - *E;
	}
      else if (mt == 522)
	{
	  /* Score capture rate */

	  ptr = (long)RDB[RES_PHOTOELE_CAPT_RATE];
	  CheckPointer(FUNCTION_NAME, "(ptr)", DATA_ARRAY, ptr);
	  AddBuf1D(1.0, *wgt, ptr, id, 0);

	  /* Photoelectric effect */

	  Photoelectric(mat, rea, part, *E, x, y, z, *u, *v, *w, *wgt, t, id);

	  /* Incident photon is killed */
	  
	  return TRACK_END_CAPT;
	}
      else if (mt == 516)
	{
	  /* Score capture rate */

	  ptr = (long)RDB[RES_PAIRPROD_CAPT_RATE];
	  CheckPointer(FUNCTION_NAME, "(ptr)", DATA_ARRAY, ptr);
	  AddBuf1D(1.0, *wgt, ptr, id, 0);

	  /* Pair production */

	  PairProduction(mat, rea, part, *E, x, y, z, *u, *v, *w, *wgt, t, id);

	  /* Incident photon is killed */

	  return TRACK_END_CAPT;
	}
      else
	Die(FUNCTION_NAME, "Invalid reaction mode %ld sampled", mt);

      /* Set weight */

      wgt2 = wgt1;

      /***********************************************************************/
    }

  /* Check final weight */

  if (wgt2 < 0.0)
    Die(FUNCTION_NAME, "Error in weight");

  /* Apply weight window */

  if (WeightWindow(-1, part, x, y, z, *u, *v, *w, *E, &wgt2, t, NO, id)
      == TRACK_END_WCUT)
    {
      /* Exit subroutine */
      
      return TRACK_END_WCUT;
    }

  /* Russian roulette */

  if (wgt2 < RDB[DATA_OPT_ROULETTE_W0])
    {
      if (RandF(id) < RDB[DATA_OPT_ROULETTE_P0])
	wgt2 = wgt2/RDB[DATA_OPT_ROULETTE_P0];
      else
	{
	  /* Put particle back in stack */
	  
	  ToStack(part, id);
	  
	  /* Exit subroutine */

	  return TRACK_END_WCUT;
	}
    }

  /* Set final weight */

  *wgt = wgt2;  

  /* Check energy, weight and cosines */

  CheckValue(FUNCTION_NAME, "E", "", *E, ZERO, INFTY);
  CheckValue(FUNCTION_NAME, "wgt", "", *wgt, ZERO, INFTY);
  CheckValue(FUNCTION_NAME, "r", "", *u**u + *v**v + *w**w - 1.0, -1E-5, 1E-5);

  /* Check with boundaries */

  if (type == PARTICLE_TYPE_NEUTRON)
    {
      /* Adjust neutron energy */

      if (*E < 1.0000001*RDB[DATA_NEUTRON_EMIN])
	*E = 1.000001*RDB[DATA_NEUTRON_EMIN];
      else if (*E > 0.999999*RDB[DATA_NEUTRON_EMAX])
	*E = 0.999999*RDB[DATA_NEUTRON_EMAX];

      /* Check scattering flag */

      if (scatt == YES)
	{
	  /* Calculate scattering cosine */

	  mu = *u*u0 + *v*v0 + *w*w0;
	  
	  /* Score scattering */
	  
	  ScoreScattering(mat, rea, mu, E0, *E, wgt1, wgt2, id);

	  /* Score recoil detector */
	  
	  RecoilDet(mat, dE, x, y, z, u0, v0, w0, E0, t, wgt1, id);

	  /* Score mesh */

	  ScoreMesh(part, mat, 0.0, dE, x, y, z, E0, t, wgt1, 1.0, id);
	}

      /* Set time of thermalization */

      if ((RDB[part + PARTICLE_TT] == 0.0) && (*E < 0.625E-6))
	WDB[part + PARTICLE_TT] = t;
    }
  else
    {
      /* Do energy cut-off for photons or adjust upper boundary */

      if (*E < RDB[DATA_PHOTON_EMIN])
	{
	  /* Put particle back in stack */
	  
	  ToStack(part, id);
	  
	  /* Score cut-off */

	  ptr = (long)RDB[RES_TOT_PHOTON_CUTRATE];
	  CheckPointer(FUNCTION_NAME, "(ptr)", DATA_ARRAY, ptr);
	  AddBuf1D(1.0, *wgt, ptr, id, 0);

	  /* Exit subroutine */

	  return TRACK_END_ECUT;
	}
      else if (*E > 0.999999*RDB[DATA_PHOTON_EMAX])
	*E = 0.999999*RDB[DATA_PHOTON_EMAX];
    }

  /* Check that reaction was scattering */

  if (scatt == NO)
    Die(FUNCTION_NAME, "not a scattering reaction");

  /* Exit subroutine */    

  return TRACK_END_SCAT;
  
  /***************************************************************************/
}