Esempio n. 1
0
geom::FieldCell<Scal> CalcRadiationField(
    const Mesh& mesh,
    const geom::MapFace<std::shared_ptr<solver::ConditionFace>>&
    mf_cond_radiation_shared,
    const geom::FieldCell<Scal>& fc_absorption_rate,
    Vect radiation_direction,
    geom::FieldCell<Scal> initial_guess) {

  if (radiation_direction.norm() == 0.) {
    return initial_guess;
  }

  radiation_direction /= radiation_direction.norm();

  geom::FieldFace<Scal> ff_flux(mesh);
  for (auto idxface : mesh.Faces()) {
    ff_flux[idxface] =
        radiation_direction.dot(mesh.GetSurface(idxface));
  }

  Scal time_step = 1e16;
  for (auto idxcell : mesh.Cells()) {
    for (size_t i = 0; i < mesh.GetNumNeighbourFaces(idxcell); ++i) {
      auto idxface = mesh.GetNeighbourFace(idxcell, i);
      Vect vect = mesh.GetCenter(idxcell) - mesh.GetCenter(idxface);
      Scal vel_dot_vect = std::abs(radiation_direction.dot(vect));
      if (vel_dot_vect != 0.) {
        time_step = std::min(time_step, vect.sqrnorm() / vel_dot_vect);
      }
    }
  }

  geom::FieldCell<Scal> fc_source(mesh, 0.);

  solver::AdvectionSolverExplicit<Mesh, geom::FieldFace<Scal>>
  advection(
      mesh, initial_guess, mf_cond_radiation_shared, &ff_flux,
      &fc_source, 0., time_step);

  Scal error = 1e16;
  size_t count = 0;
  for (; count < 10 && error > 1e-3; ++count) {
    for (auto idxcell : mesh.Cells()) {
      fc_source[idxcell] =
          -fc_absorption_rate[idxcell] * advection.GetField()[idxcell];
    }
    advection.StartStep();
    advection.MakeIteration();
    error = advection.GetConvergenceIndicator();
    advection.FinishStep();
  }
  return advection.GetField();
}