Пример #1
0
  void Shader::compileFlat() {
    if (shader != 0) return;
      
    shader = glCreateShaderObjectARB(shaderType());
    if (shader == 0) {
      throw std::runtime_error("failed to create shader object");
    }
      
    std::list<std::string> all_source;
    s_tag++;
    _source(all_source);

    std::ostringstream _prog;
    std::copy(all_source.begin(), all_source.end(), std::ostream_iterator<std::string>(_prog, "\n"));
      
    GLint length = _prog.str().size();
    const char *_p = _prog.str().c_str();
    glShaderSourceARB(shader, 1, &_p, &length);
    glCompileShaderARB(shader);
      
    GLint compile_status = 0;
    glGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &compile_status);
    if (compile_status == 0) {
      std::ostringstream err;
      err << "failed to compile shader:" << std::endl << "----" << std::endl << glsl_log(shader) << std::endl << "----" << std::endl;

      glDeleteObjectARB(shader);
      shader = 0;
      throw std::runtime_error(err.str());
    }
  }
Пример #2
0
/**
 * @brief Returns the source for some energy group for a flat source region
 * @param fsr_id the ID for the FSR of interest
 * @param energy_group the energy group of interest
 * @return the flat source region source
 */
FP_PRECISION CPUSolver::getFSRSource(int fsr_id, int energy_group) {

  /* Error checking */
  if (fsr_id >= _num_FSRs)
    log_printf(ERROR, "Unable to return a source for FSR ID = %d in energy "
               "group %d since the solver only contains FSR with IDs less than "
               "or equal to %d", fsr_id, energy_group, _num_FSRs-1);

  if (fsr_id < 0)
    log_printf(ERROR, "Unable to return a source for FSR ID = %d "
               "in energy group %d since FSRs do not have negative IDs",
               fsr_id, energy_group);

  if (energy_group-1 >= _num_groups)
    log_printf(ERROR, "Unable to return a source for FSR ID = %d "
               "in energy group %d since the solver only has %d energy "
               "groups", fsr_id, energy_group, _num_groups);

  if (energy_group <= 0)
    log_printf(ERROR, "Unable to return a source for FSR ID = %d "
               "in energy group %d since energy groups are greater than "
               "or equal to 1", fsr_id, energy_group);

  return _source(fsr_id,energy_group-1);
}
Пример #3
0
/**
 * @brief Set the source for each FSR and energy group to some value.
 * @param value the value to assign to each FSR source
 */
void CPUSolver::flattenFSRSources(FP_PRECISION value) {

  #pragma omp parallel for schedule(guided)
  for (int r=0; r < _num_FSRs; r++) {
    for (int e=0; e < _num_groups; e++) {
      _source(r,e) = value;
      _old_source(r,e) = value;
    }
  }

  return;
}
Пример #4
0
  void HeatTransferSource<SourceFunction>::element_time_derivative( bool /*compute_jacobian*/,
								    AssemblyContext& context,
								    CachedValues& /*cache*/ )
  {
#ifdef GRINS_USE_GRVY_TIMERS
    this->_timer->BeginTimer("HeatTransferSource::element_time_derivative");
#endif
  
    // The number of local degrees of freedom in each variable.
    const unsigned int n_T_dofs = context.get_dof_indices(_temp_vars.T_var()).size();

    // Element Jacobian * quadrature weights for interior integration.
    const std::vector<libMesh::Real> &JxW =
      context.get_element_fe(_temp_vars.T_var())->get_JxW();

    // The temperature shape functions at interior quadrature points.
    const std::vector<std::vector<libMesh::Real> >& T_phi =
      context.get_element_fe(_temp_vars.T_var())->get_phi();

    // Locations of quadrature points
    const std::vector<libMesh::Point>& x_qp = context.get_element_fe(_temp_vars.T_var())->get_xyz();

    // Get residuals
    libMesh::DenseSubVector<libMesh::Number> &FT = context.get_elem_residual(_temp_vars.T_var()); // R_{T}

    // Now we will build the element Jacobian and residual.
    // Constructing the residual requires the solution and its
    // gradient from the previous timestep.  This must be
    // calculated at each quadrature point by summing the
    // solution degree-of-freedom values by the appropriate
    // weight functions.
    unsigned int n_qpoints = context.get_element_qrule().n_points();

    for (unsigned int qp=0; qp != n_qpoints; qp++)
      {
	libMesh::Real q = _source( x_qp[qp] );

	for (unsigned int i=0; i != n_T_dofs; i++)
	  {
	    FT(i) += q*T_phi[i][qp]*JxW[qp];
	  }
      }

#ifdef GRINS_USE_GRVY_TIMERS
    this->_timer->EndTimer("HeatTransferSource::element_time_derivative");
#endif

    return;
  }
Пример #5
0
/**
 * @brief Computes the total source (fission and scattering) in each FSR.
 * @details This method computes the total source in each FSR based on
 *          this iteration's current approximation to the scalar flux. A
 *          residual for the source with respect to the source compute on
 *          the previous iteration is computed and returned. The residual
 *          is determined as follows:
 *          /f$ res = \sqrt{\frac{\displaystyle\sum \displaystyle\sum
 *                    \left(\frac{Q^i - Q^{i-1}{Q^i}\right)^2}{\# FSRs}}} \f$
 *
 * @return the residual between this source and the previous source
 */
FP_PRECISION CPUSolver::computeFSRSources() {

  int tid;
  Material* material;
  FP_PRECISION scatter_source;
  FP_PRECISION fission_source;
  FP_PRECISION* nu_sigma_f;
  FP_PRECISION* sigma_s;
  FP_PRECISION* sigma_t;
  FP_PRECISION* chi;

  FP_PRECISION source_residual = 0.0;

  FP_PRECISION inverse_k_eff = 1.0 / _k_eff;

  /* For all FSRs, find the source */
  #pragma omp parallel for private(tid, material, nu_sigma_f, chi, \
    sigma_s, sigma_t, fission_source, scatter_source) schedule(guided)
  for (int r=0; r < _num_FSRs; r++) {

    tid = omp_get_thread_num();
    material = _FSR_materials[r];
    nu_sigma_f = material->getNuSigmaF();
    chi = material->getChi();
    sigma_s = material->getSigmaS();
    sigma_t = material->getSigmaT();

    /* Initialize the source residual to zero */
    _source_residuals[r] = 0.;

    /* Compute fission source for each group */
    if (material->isFissionable()) {
      for (int e=0; e < _num_groups; e++)
        _fission_sources(r,e) = _scalar_flux(r,e) * nu_sigma_f[e];

        fission_source = pairwise_sum<FP_PRECISION>(&_fission_sources(r,0),
                                                     _num_groups);
        fission_source *= inverse_k_eff;
    }

    else
      fission_source = 0.0;

    /* Compute total scattering source for group G */
    for (int G=0; G < _num_groups; G++) {
      scatter_source = 0;

      for (int g=0; g < _num_groups; g++)
        _scatter_sources(tid,g) = sigma_s[G*_num_groups+g] * _scalar_flux(r,g);

        scatter_source=pairwise_sum<FP_PRECISION>(&_scatter_sources(tid,0),
                                                   _num_groups);

      /* Set the total source for FSR r in group G */
      _source(r,G) = (fission_source * chi[G] + scatter_source) *
                      ONE_OVER_FOUR_PI;

      _reduced_source(r,G) = _source(r,G) / sigma_t[G];

      /* Compute the norm of residual of the source in the FSR */
      if (fabs(_source(r,G)) > 1E-10)
        _source_residuals[r] += pow((_source(r,G) - _old_source(r,G))
                                / _source(r,G), 2);

      /* Update the old source */
      _old_source(r,G) = _source(r,G);
    }
  }

  /* Sum up the residuals from each FSR */
  source_residual = pairwise_sum<FP_PRECISION>(_source_residuals, _num_FSRs);
  source_residual = sqrt(source_residual / (_num_FSRs * _num_groups));

  return source_residual;
}
Пример #6
0
/**
 * @brief Computes the total source (fission and scattering) in each FSR.
 * @details This method computes the total source in each FSR based on
 *          this iteration's current approximation to the scalar flux. A
 *          residual for the source with respect to the source compute on
 *          the previous iteration is computed and returned. The residual
 *          is determined as follows:
 *          /f$ res = \sqrt{\frac{\displaystyle\sum \displaystyle\sum
 *                    \left(\frac{Q^i - Q^{i-1}{Q^i}\right)^2}{# FSRs}}} \f$
 *
 * @return the residual between this source and the previous source
 */
FP_PRECISION VectorizedSolver::computeFSRSources() {

  int tid;
  FP_PRECISION scatter_source;
  FP_PRECISION fission_source;
  FP_PRECISION* nu_sigma_f;
  FP_PRECISION* sigma_s;
  FP_PRECISION* sigma_t;
  FP_PRECISION* chi;
  Material* material;

  FP_PRECISION source_residual = 0.0;

  FP_PRECISION inverse_k_eff = 1.0 / _k_eff;

  /* For all FSRs, find the source */
  #pragma omp parallel for private(material, nu_sigma_f, chi, \
    sigma_s, sigma_t, fission_source, scatter_source) schedule(guided)
  for (int r=0; r < _num_FSRs; r++) {

    tid = omp_get_thread_num();
    material = _FSR_materials[r];
    nu_sigma_f = material->getNuSigmaF();
    chi = material->getChi();
    sigma_s = material->getSigmaS();
    sigma_t = material->getSigmaT();

    /* Initialize the source residual to zero */
    _source_residuals[r] = 0.;

    /* Compute fission source for each group */
    if (material->isFissionable()) {
      for (int v=0; v < _num_vector_lengths; v++) {

        /* Compute fission source for each group */
        #pragma simd vectorlength(VEC_LENGTH)
        for (int e=v*VEC_LENGTH; e < (v+1)*VEC_LENGTH; e++)
          _fission_sources(r,e) = _scalar_flux(r,e) * nu_sigma_f[e];
      }

      #ifdef SINGLE
      fission_source = cblas_sasum(_num_groups, &_fission_sources(r,0),1);
      #else
      fission_source = cblas_dasum(_num_groups, &_fission_sources(r,0),1);
      #endif

      fission_source *= inverse_k_eff;
    }

    else
      fission_source = 0.0;

    /* Compute total scattering source for group G */
    for (int G=0; G < _num_groups; G++) {
      scatter_source = 0;

      for (int v=0; v < _num_vector_lengths; v++) {

        #pragma simd vectorlength(VEC_LENGTH)
        for (int g=v*VEC_LENGTH; g < (v+1)*VEC_LENGTH; g++)
          _scatter_sources(tid,g) = sigma_s[G*_num_groups+g] *
                                    _scalar_flux(r,g);
      }

      #ifdef SINGLE
      scatter_source=cblas_sasum(_num_groups,&_scatter_sources(tid,0),1);
      #else
      scatter_source=cblas_dasum(_num_groups,&_scatter_sources(tid,0),1);
      #endif

      /* Set the total source for FSR r in group G */
      _source(r,G) = (fission_source * chi[G] + scatter_source)
                        * ONE_OVER_FOUR_PI;

      _reduced_source(r,G) = _source(r,G) / sigma_t[G];

      /* Compute the norm of residual of the source in the FSR */
      if (fabs(_source(r,G)) > 1E-10)
        _source_residuals[r] += pow((_source(r,G) - _old_source(r,G))
                                / _source(r,G), 2);

      /* Update the old source */
      _old_source(r,G) = _source(r,G);
    }
  }

  /* Sum up the residuals from each group and in each FSR */
  #ifdef SINGLE
  source_residual = cblas_sasum(_num_FSRs,_source_residuals,1);
  #else
  source_residual = cblas_dasum(_num_FSRs,_source_residuals,1);
  #endif

  source_residual = sqrt(source_residual / (_num_groups * _num_FSRs));

  return source_residual;
}