/* SPDX-FileCopyrightText: Copyright (c) 2016 - 2026, the adamantine authors. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception */ #ifndef THERMAL_OPERATOR_HH #define THERMAL_OPERATOR_HH #include #include #include #include #include #include #include #include namespace adamantine { /** * This class is the operator associated with the heat equation, i.e., vmult * performs \f$ dst = -\nabla k \nabla src \f$. */ template class ThermalOperator final : public ThermalOperatorBase { public: ThermalOperator( MPI_Comm const &communicator, Boundary const &boundary, MaterialProperty &material_properties, std::vector>> const &heat_sources); /** * Associate the AffineConstraints and the MatrixFree objects to the * underlying Triangulation. */ void reinit(dealii::DoFHandler const &dof_handler, dealii::AffineConstraints const &affine_constraints, dealii::hp::QCollection<1> const &quad) override; /** * Compute the inverse of the mass matrix. */ void compute_inverse_mass_matrix( dealii::DoFHandler const &dof_handler, dealii::AffineConstraints const &affine_constraints) override; /** * Resize the inverse of the mass matrix to zero. */ void clear() override; dealii::types::global_dof_index m() const override; dealii::types::global_dof_index n() const override; /** * Return a shared pointer to the inverse of the mass matrix. */ std::shared_ptr> get_inverse_mass_matrix() const override; /** * Return a shared pointer to the underlying MatrixFree object. */ dealii::MatrixFree const &get_matrix_free() const; void vmult(dealii::LA::distributed::Vector &dst, dealii::LA::distributed::Vector const &src) const override; void vmult_add(dealii::LA::distributed::Vector &dst, dealii::LA::distributed::Vector const &src) const override; void initialize_dof_vector( dealii::LA::distributed::Vector &vector) const override; void get_state_from_material_properties() override; void set_state_to_material_properties() override; /** * Set the deposition cosine and sine angles and convert the data from * std::vector to dealii::Table<2, dealii::VectorizedArray> */ void set_material_deposition_orientation( std::vector const &deposition_cos, std::vector const &deposition_sin) override; void set_time(double t) override; private: /** * Update the ratios of the material state. * @note The input variables are not used when the only valid state is solid. */ void update_state_ratios( [[maybe_unused]] unsigned int cell, [[maybe_unused]] unsigned int q, [[maybe_unused]] dealii::VectorizedArray temperature, std::array, MaterialStates::n_material_states> &state_ratios) const; /** * Update the ratios of the material state at the face quadrature points. * @note The input variables are not used when the only valid state is solid. */ void update_face_state_ratios( [[maybe_unused]] unsigned int face, [[maybe_unused]] unsigned int q, [[maybe_unused]] dealii::VectorizedArray temperature, std::array, MaterialStates::n_material_states> &state_ratios) const; /** * Return the value of \f$ \frac{1}{\rho C_p} \f$ for a given matrix-free * cell/face and quadrature point. */ dealii::VectorizedArray get_inv_rho_cp( std::array::size()> const &material_id, std::array, MaterialStates::n_material_states> const &state_ratios, dealii::VectorizedArray const &temperature, dealii::AlignedVector> const &temperature_powers) const; /** * Apply the operator on a given set of quadrature points inside each cell. */ void cell_local_apply( dealii::MatrixFree const &data, dealii::LA::distributed::Vector &dst, dealii::LA::distributed::Vector const &src, std::pair const &cell_range) const; /** * Apply the operator on a given set of quadrature points on each face. */ void face_local_apply( dealii::MatrixFree const &data, dealii::LA::distributed::Vector &dst, dealii::LA::distributed::Vector const &src, std::pair const &face_range) const; /** * Apply the mass operator on a given set of quadrature points. */ void cell_local_mass( dealii::MatrixFree const &data, dealii::LA::distributed::Vector &dst, dealii::LA::distributed::Vector const &src, std::pair const &cell_range) const; /** * MPI communicator. */ MPI_Comm const &_communicator; /** * Flag set to true if all the boundary conditions are adiabatic. It is set to * false otherwise. */ bool _adiabatic_only_bc = true; /** * Flag set to true if at least one heat source is on at the current time. */ bool _heat_sources_on = true; /** * Boundary ids associated to the domain. */ Boundary _boundary; /** * Data to configure the MatrixFree object. */ typename dealii::MatrixFree::AdditionalData _matrix_free_data; /** * Table of thermal conductivity coefficient. */ dealii::Table<2, dealii::VectorizedArray> _thermal_conductivity; /** * Material properties associated with the domain. */ MaterialProperty &_material_properties; /** * Vector of heat sources. */ std::vector>> _heat_sources; /** * Underlying MatrixFree object. */ dealii::MatrixFree _matrix_free; /** * Non-owning pointer to the AffineConstraints from ThermalPhysics. */ dealii::AffineConstraints const *_affine_constraints; /** * The inverse of the mass matrix is computed using an inexact * Gauss-Lobatto quadrature. This inexact quadrature makes the mass matrix * and therefore also its inverse, a diagonal matrix. */ std::shared_ptr> _inverse_mass_matrix; /** * Map between the cell iterator and the position in _inv_rho_cp table. */ std::map::cell_iterator, std::pair> _cell_it_to_mf_cell_map; /** * Table of the powder fraction inside cells; mutable so that it can be * changed in cell_local_apply which is const. */ mutable dealii::Table<2, dealii::VectorizedArray> _liquid_ratio; /** * Table of the powder fraction inside cells; mutable so that it can be * changed in cell_local_apply which is const. */ mutable dealii::Table<2, dealii::VectorizedArray> _powder_ratio; /** * Table of the powder fraction on faces; mutable so that it can be changed in * face_local_apply which is const. */ mutable dealii::Table<2, dealii::VectorizedArray> _face_powder_ratio; /** * Table of the material index inside cells; mutable so that it can be changed * in cell_local_apply which is const. */ mutable dealii::Table<2, std::array::size()>> _material_id; /** * Table of the material index on faces; mutable so that it can be changed in * face_local_apply which is const. */ mutable dealii::Table<2, std::array::size()>> _face_material_id; /** * Table of the material deposition cosine angles. */ dealii::Table<2, dealii::VectorizedArray> _deposition_cos; /** * Table of the material deposition cosine angles. */ dealii::Table<2, dealii::VectorizedArray> _deposition_sin; }; template inline dealii::types::global_dof_index ThermalOperator::m() const { return _matrix_free.get_vector_partitioner()->size(); } template inline dealii::types::global_dof_index ThermalOperator::n() const { return _matrix_free.get_vector_partitioner()->size(); } template inline std::shared_ptr> ThermalOperator::get_inverse_mass_matrix() const { return _inverse_mass_matrix; } template inline dealii::MatrixFree const & ThermalOperator::get_matrix_free() const { return _matrix_free; } template inline void ThermalOperator:: initialize_dof_vector( dealii::LA::distributed::Vector &vector) const { _matrix_free.initialize_dof_vector(vector); } template inline void ThermalOperator::set_time(double t) { _heat_sources_on = false; for (auto &beam : _heat_sources) { beam->update_time(t); if (beam->is_source_on()) _heat_sources_on = true; } } } // namespace adamantine #endif