Esempio n. 1
0
def weighted_delta_tracking_no_absorption(lambda_):
  """
    pg. 111:5, Algorithm 1. (rhs).
    Modified as per Sec. 5.1.3.
    Removal of volume absorption/emission events.
  """
  sigma_t_majorante_lambda = ms.sigma_t_majorante[lambda_]
  x = 0.
  w = 1.
  while True:
    x += exp_sample(sigma_t_majorante_lambda)
    if x > ms.domain_length:
      return (x, 0.)
    else:
      sigma_s = ms.get_sigma_s(x)[lambda_]
      sigma_a = ms.get_sigma_a(x)[lambda_]
      sigma_n = sigma_t_majorante_lambda - sigma_s - sigma_a
      ps = sigma_s / (sigma_s + abs(sigma_n))
      pn = abs(sigma_n) / (sigma_s + abs(sigma_n))
      r = random.uniform(0.,1.)
      if r < ps:
        w *= sigma_s / sigma_t_majorante_lambda / ps * ms.get_integrand(x)[lambda_]
        return (x, w)
      else:
        w *= sigma_n / sigma_t_majorante_lambda / pn
Esempio n. 2
0
def ratio_tracking():
  """
    pg. 111:16, Eq (41)
  """
  sigma_t_majorante = ms.sigma_t_majorante_across_channels
  x = 0.
  weight = np.ones(2, np.float32)
  while True:
    x += exp_sample(sigma_t_majorante)
    if x > ms.domain_length:
      return weight
    else:
      sigma_s = ms.get_sigma_s(x)
      sigma_a = ms.get_sigma_a(x)
      sigma_n = sigma_t_majorante - sigma_s - sigma_a
      weight *= sigma_n / sigma_t_majorante
Esempio n. 3
0
def single_lambda_ratio_tracking(lambda_):
  """
    pg. 111:16, Eq (41)
  """
  sigma_t_majorante_lambda = ms.sigma_t_majorante[lambda_]
  x = 0.
  weight = 1.
  while True:
    x += exp_sample(sigma_t_majorante_lambda)
    if x > ms.domain_length:
      return weight
    else:
      sigma_s = ms.get_sigma_s(x)[lambda_]
      sigma_a = ms.get_sigma_a(x)[lambda_]
      sigma_n = sigma_t_majorante_lambda - sigma_s - sigma_a
      weight *= sigma_n / sigma_t_majorante_lambda
Esempio n. 4
0
def weighted_next_flight_estimator():
  """
    pg. 111:16, Eq (39)
    More variance than ratio tracking?!
  """
  sigma_t_majorante = ms.sigma_t_majorante_across_channels
  x = 0.
  weight_product = np.ones(2, np.float32)
  weight = np.zeros(2, np.float32)
  while True:
    weight += np.exp(sigma_t_majorante * (x - ms.domain_length)) * weight_product
    x += exp_sample(sigma_t_majorante)
    if x > ms.domain_length:
      return weight
    else:
      sigma_s = ms.get_sigma_s(x)
      sigma_a = ms.get_sigma_a(x)
      sigma_n = sigma_t_majorante - sigma_s - sigma_a
      weight_product *= sigma_n / sigma_t_majorante
Esempio n. 5
0
def delta_tracking(lambda_):
  """
    pg. 111:5, Algorithm 1. (lhs). Although this is a very
    well known algorithm. Also known as woodcock tracking.
  """
  sigma_t_majorante_lambda = ms.sigma_t_majorante[lambda_]
  x = 0.
  while True:
    x += exp_sample(sigma_t_majorante_lambda)
    if x > ms.domain_length:
      return (x, 0.)
    else:
      sigma_s = ms.get_sigma_s(x)[lambda_]
      sigma_a = ms.get_sigma_a(x)[lambda_]
      sigma_n = sigma_t_majorante_lambda - sigma_s - sigma_a
      r = random.uniform(0.,1.)
      if r < (sigma_a / sigma_t_majorante_lambda):
        return (x, 0.)
      elif r < (1. - (sigma_n / sigma_t_majorante_lambda)):
        return (x, ms.get_integrand(x)[lambda_])
      else:
        pass # Null collision
Esempio n. 6
0
def spectral_tracking_no_absorption(x = 0, weights = None):
  """
    pg.  111:10, Algorithm 4.
    Modified as per Sec. 5.1.3.
    Removal of volume absorption/emission events.
  """
  weights = weights.copy() if weights is not None else np.ones(2, np.float32)
  while True:
    x += exp_sample(ms.sigma_t_majorante_across_channels)
    if x > ms.domain_length:
      return (x, weights)
    else:
      sigma_s = ms.get_sigma_s(x)
      sigma_a = ms.get_sigma_a(x)
      sigma_n = ms.sigma_t_majorante_across_channels - sigma_s - sigma_a
      pt, pn = the_probability_scheme(weights, sigma_s, sigma_n)
      r = random.uniform(0.,1.)
      if r < pt:
        weights *= sigma_s / ms.sigma_t_majorante_across_channels * ms.get_integrand(x) / pt
        return (x, weights)
      else:
        weights *= sigma_n / ms.sigma_t_majorante_across_channels / pn
Esempio n. 7
0
def spectral_tracking():
  """
    pg.  111:10, Algorithm 4
  """
  weights = np.ones(2, np.float32)
  x = 0.
  while True:
    x += exp_sample(ms.sigma_t_majorante_across_channels)
    if x > ms.domain_length:
      return (x, weights)
    else:
      sigma_s = ms.get_sigma_s(x)
      sigma_a = ms.get_sigma_a(x)
      sigma_n = ms.sigma_t_majorante_across_channels - sigma_s - sigma_a
      ps, pa, pn = the_probability_scheme(weights, sigma_s, sigma_a, sigma_n)
      r = random.uniform(0.,1.)
      if r < pa:
        return (x, np.zeros(2, np.float32))
      elif r < 1. - pn:
        weights *= sigma_s / ms.sigma_t_majorante_across_channels * ms.get_integrand(x) / ps
        return (x, weights)
      else:
        weights *= sigma_n / ms.sigma_t_majorante_across_channels / pn
Esempio n. 8
0
def construct_piecewise_constant_transmittance():
  """
    By ratio tracking.
    We have positions xi, and associated weight wi. If we want to obtain
    an estimate of the transmittance of some point y, T(y) we look up
    the next xi which comes afterwards and use the estimate T^(y) = wi.
    In expectation T^(y) equals the true transmittance T(y).

  """
  sigma_t_majorante = ms.sigma_t_majorante_across_channels
  x = 0.
  weight = np.ones(2, np.float32)
  points_and_weights = [c_(x, weight)]
  while True:
    x += exp_sample(sigma_t_majorante)
    if x > ms.domain_length:
      points_and_weights += [c_(x,weight)]
      break
    else:
      points_and_weights += [c_(x, weight)]
      sigma_s = ms.get_sigma_s(x)
      sigma_a = ms.get_sigma_a(x)
      sigma_n = sigma_t_majorante - sigma_s - sigma_a
      weight *= sigma_n / sigma_t_majorante
      term_criterion = np.amax(weight)
      # Russian roulette termination. Otherwise I would have to traverse
      # through the entire domain which would be very inefficient if the
      # mean free path length is short
      r = random.uniform(0., 1.)
      survival_probability = term_criterion
      if r < survival_probability:  # live on
        weight /= survival_probability
      else:
        points_and_weights += [c_(ms.domain_length*1.1,np.zeros_like(weight))]
        break
  return np.asarray(points_and_weights)