27#ifndef rdlm_inclusions
28#define rdlm_inclusions
46#include <boost/algorithm/string.hpp>
63template <
int spacedim>
67 template <
int dim,
typename number,
int n_components>
77 ,
inclusions_rhs(
"/Immersed Problem/Immersed inclusions/Boundary data",
81 static_assert(spacedim > 1,
"Not implemented in dim = 1");
87 "Number of fourier coefficients",
89 "This represents the number of scalar harmonic functions used "
90 "for the representation of the data (boundary data or forcing data) "
91 "of the inclusion. The provided input files should contain at least "
92 "a number of entries which is equal to this number multiplied by the "
93 "number of vector components of the problem. Any additional entry is "
94 "ignored by program. If fewer entries are specified, an exception is "
97 "Selection of Fourier coefficients",
99 "This allows one to select a subset of the components of the harmonic functions "
100 "used for the representation of the data (boundary data or forcing data). Notice "
101 "that these indices are w.r.t. to the total number of components of the problem, "
102 "that is, number of Fourier coefficients x number of vector components. In "
103 "particular any entry of this list must be in the set "
104 "[0,n_coefficients*n_vector_components). ");
109 auto reset_function = [
this]() {
110 this->
prm.set(
"Function expression",
111 (spacedim == 2 ?
"0; 0" :
"0; 0; 0"));
113 inclusions_rhs.declare_parameters_call_back.connect(reset_function);
172 "Refinement of inclusions must be greater than zero."));
175 "Number of coefficients must be greater than zero."));
206 double buffer_double;
208 const unsigned int size = (spacedim == 2 ? 3 : 8);
209 std::vector<double> inclusion(
size);
211 while (infile >> buffer_double)
213 inclusion[0] = buffer_double;
214 for (
unsigned int i = 1; i <
size; ++i)
217 infile >> inclusion[i];
229 while (std::getline(infile, line))
231 std::vector<double> double_line;
232 std::istringstream iss(line);
233 double buffer_double;
234 while (iss >> buffer_double)
236 double_line.push_back(buffer_double);
248 AssertThrow(
l.size() == N, ExcDimensionMismatch(
l.size(), N));
254 <<
": Read " << N <<
" coefficients per "
255 <<
inclusions.size() <<
" inclusion" << std::endl;
276 std::vector<types::global_dof_index>
307 auto inclusions_set =
311 std::vector<Point<spacedim>> particles_positions;
313 for (
const auto i : inclusions_set)
316 particles_positions.insert(particles_positions.end(),
321 std::vector<BoundingBox<spacedim>> all_boxes;
324 if (cell->is_locally_owned())
325 all_boxes.emplace_back(cell->bounding_box());
329 auto global_bounding_boxes =
332 Assert(!global_bounding_boxes.empty(),
334 "I was expecting the "
335 "global_bounding_boxes to be filled at this stage. "
336 "Make sure you fill this vector before trying to use it "
337 "here. Bailing out."));
339 global_bounding_boxes);
458 if constexpr (spacedim == 2)
491 const std::vector<double> &
506 unsigned int basis_local_id = 0;
507 for (
unsigned int basis :
512 const unsigned int fourier_index =
514 unsigned int omega = (fourier_index + 1) / 2;
516 double scaling_factor = (omega == 1 ? 1 : s1);
518 if (fourier_index == 0)
520 else if ((fourier_index - 1) % 2 == 0)
554 const auto &inclusion =
inclusions[inclusion_id];
555 Assert(inclusion.size() > spacedim, ExcInternalError());
557 for (
unsigned int d = 0;
d < spacedim; ++
d)
558 center[
d] = inclusion[
d];
573 const auto &inclusion =
inclusions[inclusion_id];
574 if constexpr (spacedim == 2)
577 return inclusion[spacedim];
582 return inclusion[2 * spacedim];
596 if constexpr (spacedim == 2)
616 if constexpr (spacedim == 2)
625 const auto &inclusion =
inclusions[inclusion_id];
628 for (
unsigned int d = 0;
d < spacedim; ++
d)
629 direction[
d] = inclusion[spacedim +
d];
631 ExcMessage(
"Expecting a direction with non-zero norm"));
647 if constexpr (spacedim == 2)
651 else if constexpr (spacedim == 3)
654 direction /= direction.norm();
658 auto v = cross_product_3d(z_axis, direction);
659 const auto cos_t = direction * z_axis;
673 rotation += vx + vx2 * (1 / (1 + cos_t));
682 const std::vector<Point<spacedim>> &
715#ifdef DEAL_II_WITH_HDF5
719 data_file_h = std::make_unique<HDF5::File>(
data_file,
720 HDF5::File::FileAccessMode::open,
722 auto group = data_file_h->open_group(
"data");
725 auto h5data = group.open_dataset(
"displacement_data");
726 auto vector_of_data = h5data.template read<Vector<double>>();
728 auto inclusions_set =
731 for (
const auto i : inclusions_set)
741 AssertThrow(
l.size() == N, ExcDimensionMismatch(
l.size(), N));
761 if constexpr (spacedim == 2)
768 std::map<unsigned int, std::vector<types::global_dof_index>>::iterator
774 for (
auto inclusion_id : it->second)
776 new_data[it->first]);
780 else if (new_data.size() ==
inclusions.size())
782 for (
long unsigned int id = 0;
id < new_data.size(); ++id)
787 new_data.size() == 0,
789 "dimensions of new data for the update does not match the inclusions"));
797 if constexpr (spacedim == 2)
803 "dimensions of new data for the update does not match the inclusions"));
805 for (
unsigned int current_vessel = 0; current_vessel <
n_vessels;
809 auto ¤t_new_data = new_data[current_vessel];
812 auto N1 = current_inclusions.size();
813 auto N2 = current_new_data.size();
818 "dimensions of new data for the update does not match the inclusions"));
822 "insufficient number of inclusion int the vessel for the update"));
825 for (
unsigned int i = 0; i < N1 - 1; ++i)
832 double current_vessel_new_data;
835 for (
unsigned int i = 1; i < N1 - 1; ++i)
837 auto X = i / (N1 - 1) * (N2 - 1);
839 Assert(j < N2, ExcInternalError());
841 current_vessel_new_data =
842 (1 -
w) * current_new_data[j] + (
w)*current_new_data[j + 1];
844 i, current_vessel_new_data);
848 current_new_data[N2 - 1]);
874 const auto &inclusion =
inclusions[inclusion_id];
875 if constexpr (spacedim == 2)
882 return int(inclusion[2 * spacedim + 1]);
911 const std::vector<double>)
944 if constexpr (spacedim == 3)
951 for (
long unsigned int inclusion_id = 0;
962 std::vector<double> rotated_phi(
964 for (
long unsigned int phi_i = 0;
965 (phi_i * spacedim + spacedim - 1) <
970 for (
unsigned int d = 0;
d < spacedim; ++
d)
974 auto rotated_phi_i = tensorR * coef_phii;
975 rotated_phi_i.
unroll(&rotated_phi[phi_i * spacedim],
976 &rotated_phi[phi_i * spacedim + 3]);
1029#ifdef DEAL_II_WITH_HDF5
1030 mutable std::unique_ptr<HDF5::File> data_file_h;
1036 std::map<unsigned int, std::vector<types::global_dof_index>>
1072 if constexpr (spacedim == 2)
1082 std::map<unsigned int, std::vector<types::global_dof_index>>::iterator
1093 "Vessel Ids from data file should be sequential, missing vessels ID(s)"));
void write_vtu_in_parallel(const std::string &filename, const MPI_Comm comm) const
ParameterAcceptor(const std::string §ion_name="")
static ParameterHandler prm
void add_parameter(const std::string &entry, ParameterType ¶meter, const std::string &documentation="", ParameterHandler &prm_=prm, const Patterns::PatternBase &pattern=*Patterns::Tools::Convert< ParameterType >::to_pattern())
void build_patches(const Particles::ParticleHandler< dim, spacedim > &particles, const std::vector< std::string > &data_component_names={}, const std::vector< DataComponentInterpretation::DataComponentInterpretation > &data_component_interpretations={})
numbers::NumberTraits< Number >::real_type norm() const
void unroll(const Iterator begin, const Iterator end) const
MPI_Comm get_communicator() const
std::vector< unsigned int > selected_coefficients
unsigned int get_fourier_component(const types::global_dof_index &dof_index) const
Get the ith Fourier component for the given dof index.
std::vector< Tensor< 1, spacedim > > normals
double get_JxW(const types::global_dof_index &particle_id) const
return weight for integration normal direction of an inclusion at a quadrature point
unsigned int n_dofs_per_inclusion() const
Number of degrees of freedom associated to each inclusion.
std::vector< double > theta
double get_inclusion_data(const types::global_dof_index &inclusion_id, const types::global_dof_index &dof_index) const
Get the Fourier data for the given local dof index.
void set_n_coefficients(unsigned int n_coefficients)
unsigned int get_n_coefficients() const
void output_particles(const std::string &filename) const
print the inclusions in parallel on a .vtu file
std::map< unsigned int, std::vector< types::global_dof_index > > map_vessel_inclusions
unsigned int rtree_extraction_level
std::vector< double > current_fe_values
Inclusions(const unsigned int n_vector_components=1)
Class for computing the inclusions of a given mesh.
void update_inclusions_data(std::vector< std::vector< double > > new_data)
unsigned int get_component(const types::global_dof_index &dof_index) const
Get the ith component for the given dof index.
const unsigned int n_vector_components
const std::vector< double > & get_fe_values(const types::global_dof_index particle_id) const
types::global_dof_index get_inclusion_id(const types::global_dof_index &quadrature_id) const
unsigned int n_coefficients
void update_inclusions_data(std::vector< double > new_data)
Update the displacement data after the initialization, 3D case only.
double get_section_measure(const types::global_dof_index &inclusion_id) const
Get the measure of the section of the inclusion.
std::vector< std::vector< double > > inclusions
std::vector< std::vector< double > > rotated_inclusion_data
std::vector< double > reference_inclusion_data
types::global_dof_index n_inclusions() const
Returns the number of inclusions in the mesh.
std::vector< types::global_dof_index > get_dof_indices(const types::global_dof_index &quadrature_id) const
Returns the degrees of freedom indices associated with a given quadrature point.
std::vector< double > get_rotated_inclusion_data(const types::global_dof_index &inclusion_id) const
return the rotate the data of a given inclusion
unsigned int get_n_vessels() const
void set_n_q_points(unsigned int n_q)
void compute_rotated_inclusion_data()
std::vector< Point< spacedim > > current_support_points
std::vector< Point< spacedim > > support_points
void check_vessels()
Check that all vesselsID are present and create the map vessel_inclusions.
std::vector< std::vector< double > > inclusions_data
unsigned int get_inclusions_in_vessel(unsigned int vessel_id) const
unsigned int offset_coefficients
Tensor< 1, spacedim > get_direction(const types::global_dof_index &inclusion_id) const
Get the direction of the inclusion.
types::global_dof_index n_particles() const
unsigned int get_offset_coefficients() const
int get_vesselID(const types::global_dof_index &inclusion_id) const
3D return the vessel that a given inclusion belongs to, 2D return 0
double get_inclusion_data(const types::global_dof_index &inclusion_id, const types::global_dof_index &dof_index, const Point< spacedim > &point) const
Get the Fourier data for the given local dof index.
friend class CouplingOperator
const Tensor< 1, spacedim > & get_normal(const types::global_dof_index &quadrature_id) const
Get the normal.
Point< spacedim > get_center(const types::global_dof_index &inclusion_id) const
Get the center of the inclusion.
MPI_Comm mpi_communicator
ParameterAcceptorProxy< Functions::ParsedFunction< spacedim > > inclusions_rhs
Particles::ParticleHandler< spacedim > inclusions_as_particles
void update_displacement_hdf5()
Update the displacement data after the initialization reading from a hdf5 file.
void setup_inclusions_particles(const parallel::distributed::Triangulation< spacedim > &tria)
Sets up the inclusions particles for the given triangulation.
std::string inclusions_file
void update_single_inclusion_data_along_normal(const types::global_dof_index &inclusion_id, const double nd)
double get_radius(const types::global_dof_index &inclusion_id) const
Get the radius of the inclusion.
const std::vector< Point< spacedim > > & get_current_support_points(const types::global_dof_index &inclusion_id) const
void update_single_vessel_data(const types::global_dof_index &, const std::vector< double >)
Tensor< 2, spacedim > get_rotation(const types::global_dof_index &inclusion_id) const
Get the rotation of the inclusion.
types::global_dof_index n_dofs() const
unsigned int n_locally_owned_active_cells() const
IteratorRange< active_cell_iterator > active_cell_iterators() const
#define Assert(cond, exc)
#define AssertDimension(dim1, dim2)
#define AssertIndexRange(index, range)
#define AssertThrow(cond, exc)
Expression floor(const Expression &x)
Tensor< 2, dim, Number > w(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > e(const Tensor< 2, dim, Number > &F)
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
std::vector< T > all_gather(const MPI_Comm comm, const T &object_to_send)
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
IndexSet create_evenly_distributed_partitioning(const MPI_Comm comm, const types::global_dof_index total_size)
::VectorizedArray< Number, width > cos(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sin(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
unsigned int global_dof_index
std::vector< BoundingBox< boost::geometry::dimension< typename Rtree::indexable_type >::value > > extract_rtree_level(const Rtree &tree, const unsigned int level)
RTree< typename LeafTypeIterator::value_type, IndexType, IndexableGetter > pack_rtree(const LeafTypeIterator &begin, const LeafTypeIterator &end)
static MappingQ< dim, spacedim > mapping
DEAL_II_HOST constexpr SymmetricTensor< 2, dim, Number > unit_symmetric_tensor()