Program Listing for File data_handler.hxx
↰ Return to documentation for file (mesh_handle/data_handler.hxx)
/*
This file is part of t8code.
t8code is a C library to manage a collection (a forest) of multiple
connected adaptive space-trees of general element classes in parallel.
Copyright (C) 2026 the developers
t8code is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
t8code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with t8code; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#pragma once
#include <t8.h>
#include "concepts.hxx"
#include <t8_forest/t8_forest_general.h>
#include <t8_types/t8_crtp.hxx>
#include <type_traits>
#include <vector>
namespace t8_mesh_handle
{
// --- Mesh competence for element data management. ---
template <typename TUnderlying, T8MPISafeType TElementDataType>
class element_data_mesh_competence_impl: public t8_crtp_basic<TUnderlying> {
public:
using ElementDataType = TElementDataType;
void
set_element_data (std::vector<TElementDataType> element_data)
{
T8_ASSERT (element_data.size () == static_cast<size_t> (this->underlying ().get_num_local_elements ()));
// element_data is moved, not copied.
m_element_data = std::move (element_data);
}
const std::vector<TElementDataType>&
get_element_data () const
{
return m_element_data;
}
void
exchange_ghost_data ()
{
// t8_forest_ghost_exchange_data expects an sc_array, so we need to wrap our data array to one.
sc_array* sc_array_wrapper;
const auto num_local_elements = this->underlying ().get_num_local_elements ();
const auto num_ghosts = this->underlying ().get_num_ghosts ();
m_element_data.resize (num_local_elements + num_ghosts);
sc_array_wrapper
= sc_array_new_data (m_element_data.data (), sizeof (ElementDataType), num_local_elements + num_ghosts);
// Data exchange: entries with indices > num_local_elements will get overwritten.
t8_forest_ghost_exchange_data (this->underlying ().get_forest (), sc_array_wrapper);
sc_array_destroy (sc_array_wrapper);
}
protected:
std::vector<TElementDataType> m_element_data;
};
template <T8MPISafeType TElementDataType>
struct element_data_mesh_competence
{
template <typename TUnderlying>
using type = element_data_mesh_competence_impl<TUnderlying, TElementDataType>;
};
// --- Element competence for element data management. ---
template <typename TUnderlying>
struct element_data_element_competence: public t8_crtp_basic<TUnderlying>
{
public:
// --- Getter and setter for element data. ---
void
set_element_data (auto element_data)
{
T8_ASSERT (this->underlying ().m_mesh->has_element_data_handler_competence ());
SC_CHECK_ABORT (!this->underlying ().is_ghost_element (), "Element data cannot be set for ghost elements.\n");
// Resize to num_local_elements on first use so that operator[] is valid.S
if (static_cast<t8_locidx_t> (this->underlying ().m_mesh->m_element_data.size ())
<= this->underlying ().get_element_handle_id ()) {
this->underlying ().m_mesh->m_element_data.resize (this->underlying ().m_mesh->get_num_local_elements ());
}
// element_data is moved, not copied.
this->underlying ().m_mesh->m_element_data[this->underlying ().get_element_handle_id ()] = std::move (element_data);
}
const auto&
get_element_data () const
{
T8_ASSERT (this->underlying ().m_mesh->has_element_data_handler_competence ());
const t8_locidx_t handle_id = this->underlying ().get_element_handle_id ();
T8_ASSERTF (static_cast<size_t> (handle_id) < this->underlying ().m_mesh->m_element_data.size (),
"Element data not set.\n");
return this->underlying ().m_mesh->m_element_data[handle_id];
}
};
} // namespace t8_mesh_handle