void NSNeutronEqResid<EvalT, Traits>::
evaluateFields(typename Traits::EvalData workset)
{
  typedef Intrepid::FunctionSpaceTools FST;

  FST::scalarMultiplyDataData<ScalarT> (flux, NeutronDiff, NGrad);

  FST::integrate<ScalarT>(NResidual, flux, wGradBF, Intrepid::COMP_CPP, false); // "false" overwrites
  
  for (std::size_t cell=0; cell < workset.numCells; ++cell) {
    for (std::size_t qp=0; qp < numQPs; ++qp) {
      abscoeff(cell,qp) = 
	(Absorp(cell,qp) - nu(cell,qp)*Fission(cell,qp)) * Neutron(cell,qp);
      if (haveNeutSource) abscoeff(cell,qp) -= Source(cell,qp);
    }
  }

  FST::integrate<ScalarT>(NResidual, abscoeff, wBF, Intrepid::COMP_CPP, true); // "true" sums into

}
Esempio n. 2
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;
  
  /***************************************************************************/
}