Skip to content
Snippets Groups Projects
Select Git revision
  • b1509644aa0f6163056002f9d951ebb0c4a9f39f
  • develop default protected
  • save_clemence
  • feature/composite-scheme-other-fluxes
  • feature/advection
  • origin/stage/bouguettaia
  • feature/local-dt-fsi
  • feature/variational-hydro
  • feature/gmsh-reader
  • feature/reconstruction
  • feature/kinetic-schemes
  • feature/composite-scheme-sources
  • feature/serraille
  • feature/composite-scheme
  • hyperplastic
  • feature/polynomials
  • feature/gks
  • feature/implicit-solver-o2
  • feature/coupling_module
  • feature/implicit-solver
  • feature/merge-local-dt-fsi
  • v0.5.0 protected
  • v0.4.1 protected
  • v0.4.0 protected
  • v0.3.0 protected
  • v0.2.0 protected
  • v0.1.0 protected
  • Kidder
  • v0.0.4 protected
  • v0.0.3 protected
  • v0.0.2 protected
  • v0 protected
  • v0.0.1 protected
33 results

WriterBase.cpp

Blame
  • WriterBase.cpp 6.81 KiB
    #include <output/WriterBase.hpp>
    
    #include <mesh/IMesh.hpp>
    #include <output/OutputNamedItemValueSet.hpp>
    #include <scheme/DiscreteFunctionP0.hpp>
    #include <scheme/IDiscreteFunction.hpp>
    #include <scheme/IDiscreteFunctionDescriptor.hpp>
    #include <utils/Exceptions.hpp>
    
    template <size_t Dimension, typename DataType>
    void
    WriterBase::registerDiscreteFunctionP0(const std::string& name,
                                           const IDiscreteFunction& i_discrete_function,
                                           OutputNamedItemValueSet& named_item_value_set)
    {
      const DiscreteFunctionP0<Dimension, DataType>& discrete_function =
        dynamic_cast<const DiscreteFunctionP0<Dimension, DataType>&>(i_discrete_function);
      named_item_value_set.add(NamedItemValue{name, discrete_function.cellValues()});
    }
    
    template <size_t Dimension>
    void
    WriterBase::registerDiscreteFunctionP0(const std::string& name,
                                           const IDiscreteFunction& i_discrete_function,
                                           OutputNamedItemValueSet& named_item_value_set)
    {
      const ASTNodeDataType& data_type = i_discrete_function.dataType();
      switch (data_type) {
      case ASTNodeDataType::bool_t: {
        registerDiscreteFunctionP0<Dimension, bool>(name, i_discrete_function, named_item_value_set);
        break;
      }
      case ASTNodeDataType::unsigned_int_t: {
        registerDiscreteFunctionP0<Dimension, uint64_t>(name, i_discrete_function, named_item_value_set);
        break;
      }
      case ASTNodeDataType::int_t: {
        registerDiscreteFunctionP0<Dimension, int64_t>(name, i_discrete_function, named_item_value_set);
        break;
      }
      case ASTNodeDataType::double_t: {
        registerDiscreteFunctionP0<Dimension, double>(name, i_discrete_function, named_item_value_set);
        break;
      }
      case ASTNodeDataType::vector_t: {
        switch (data_type.dimension()) {
        case 1: {
          registerDiscreteFunctionP0<Dimension, TinyVector<1, double>>(name, i_discrete_function, named_item_value_set);
          break;
        }
        case 2: {
          registerDiscreteFunctionP0<Dimension, TinyVector<2, double>>(name, i_discrete_function, named_item_value_set);
          break;
        }
        case 3: {
          registerDiscreteFunctionP0<Dimension, TinyVector<3, double>>(name, i_discrete_function, named_item_value_set);
          break;
        }
        default: {
          throw UnexpectedError("invalid vector dimension");
        }
        }
        break;
      }
      case ASTNodeDataType::matrix_t: {
        Assert(data_type.nbRows() == data_type.nbColumns(), "invalid matrix dimensions");
        switch (data_type.nbRows()) {
        case 1: {
          registerDiscreteFunctionP0<Dimension, TinyMatrix<1, double>>(name, i_discrete_function, named_item_value_set);
          break;
        }
        case 2: {
          registerDiscreteFunctionP0<Dimension, TinyMatrix<2, double>>(name, i_discrete_function, named_item_value_set);
          break;
        }
        case 3: {
          registerDiscreteFunctionP0<Dimension, TinyMatrix<3, double>>(name, i_discrete_function, named_item_value_set);
          break;
        }
        default: {
          throw UnexpectedError("invalid matrix dimension");
        }
        }
        break;
      }
      default: {
        throw UnexpectedError("invalid data type " + dataTypeName(data_type));
      }
      }
    }
    
    void
    WriterBase::registerDiscreteFunctionP0(const NamedDiscreteFunction& named_discrete_function,
                                           OutputNamedItemValueSet& named_item_value_set)
    {
      const IDiscreteFunction& i_discrete_function = *named_discrete_function.discreteFunction();
      const std::string& name                      = named_discrete_function.name();
      switch (i_discrete_function.mesh()->dimension()) {
      case 1: {
        registerDiscreteFunctionP0<1>(name, i_discrete_function, named_item_value_set);
        break;
      }
      case 2: {
        registerDiscreteFunctionP0<2>(name, i_discrete_function, named_item_value_set);
        break;
      }
      case 3: {
        registerDiscreteFunctionP0<3>(name, i_discrete_function, named_item_value_set);
        break;
      }
      default: {
        throw UnexpectedError("invalid mesh dimension");
      }
      }
    }
    
    std::shared_ptr<const IMesh>
    WriterBase::_getMesh(
      const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list) const
    {
      Assert(named_discrete_function_list.size() > 0);
    
      std::shared_ptr mesh = named_discrete_function_list[0]->discreteFunction()->mesh();
      for (size_t i = 1; i < named_discrete_function_list.size(); ++i) {
        if (mesh != named_discrete_function_list[i]->discreteFunction()->mesh()) {
          std::ostringstream error_msg;
          error_msg << "discrete functions must be defined on the same mesh!\n"
                    << rang::fgB::yellow << "note:" << rang::style::reset << " cannot write " << rang::fgB::blue
                    << named_discrete_function_list[0]->name() << rang::style::reset << " and " << rang::fgB::blue
                    << named_discrete_function_list[i]->name() << rang::style::reset << " in the same file.";
          throw NormalError(error_msg.str());
        }
      }
    
      return mesh;
    }
    
    OutputNamedItemValueSet
    WriterBase::_getOutputNamedItemValueSet(
      const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list) const
    {
      OutputNamedItemValueSet named_item_value_set;
    
      for (auto& named_discrete_function : named_discrete_function_list) {
        const IDiscreteFunction& i_discrete_function = *named_discrete_function->discreteFunction();
    
        switch (i_discrete_function.descriptor().type()) {
        case DiscreteFunctionType::P0: {
          WriterBase::registerDiscreteFunctionP0(*named_discrete_function, named_item_value_set);
          break;
        }
        default: {
          std::ostringstream error_msg;
          error_msg << "the type of discrete function of " << rang::fgB::blue << named_discrete_function->name()
                    << rang::style::reset << " is not supported";
          throw NormalError(error_msg.str());
        }
        }
      }
    
      return named_item_value_set;
    }
    
    double
    WriterBase::getLastTime() const
    {
      if (m_saved_times.size() > 0) {
        return m_saved_times[m_saved_times.size() - 1];
      } else {
        return -std::numeric_limits<double>::max();
      }
    }
    
    WriterBase::WriterBase(const std::string& base_filename, const double& time_period)
      : m_base_filename{base_filename}, m_time_period{time_period}
    {}
    
    void
    WriterBase::writeIfNeeded(const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list,
                              double time) const
    {
      const double last_time = getLastTime();
      if (time == last_time)
        return;   // output already performed
    
      if (time >= last_time + m_time_period) {
        this->write(named_discrete_function_list, time);
        m_saved_times.push_back(time);
      }
    }
    
    void
    WriterBase::writeForced(const std::vector<std::shared_ptr<const NamedDiscreteFunction>>& named_discrete_function_list,
                            double time) const
    {
      if (time == getLastTime())
        return;   // output already performed
    
      this->write(named_discrete_function_list, time);
      m_saved_times.push_back(time);
    }