4#include <boost/geometry.hpp>
5#include <boost/geometry/index/rtree.hpp>
11#include <deal.II/base/conditional_ostream.h>
12#include <deal.II/lac/vector.h>
13#include <deal.II/lac/la_parallel_vector.h>
14#include <deal.II/lac/solver_control.h>
15#include <deal.II/lac/lapack_full_matrix.h>
16#include <deal.II/base/point.h>
17#include <deal.II/fe/fe_values.h>
18#include <deal.II/dofs/dof_handler.h>
19#include <deal.II/base/work_stream.h>
20#include <deal.II/base/exceptions.h>
21#include <deal.II/dofs/dof_tools.h>
22#include <deal.II/grid/filtered_iterator.h>
23#include <deal.II/numerics/rtree.h>
24#include <deal.II/base/mpi.h>
25#include <deal.II/base/utilities.h>
26#include <deal.II/base/multithread_info.h>
27#include <deal.II/optimization/solver_bfgs.h>
28#include <deal.II/base/utilities.h>
29#include <deal.II/base/multithread_info.h>
30#include <deal.II/base/timer.h>
31#include <deal.II/fe/fe_values.h>
32#include <deal.II/base/work_stream.h>
33#include <deal.II/dofs/dof_tools.h>
34#include <deal.II/fe/fe_simplex_p.h>
35#include <deal.II/fe/fe_q.h>
36#include <deal.II/fe/mapping_fe.h>
37#include <deal.II/fe/mapping_q1.h>
38#include <deal.II/lac/generic_linear_algebra.h>
44using namespace dealii;
54template <
int dim,
int spacedim=dim>
61 using RTree = boost::geometry::index::rtree<IndexedPoint, RTreeParams>;
69 SmartPointer<const Mapping<dim, spacedim>>
mapping;
70 SmartPointer<const FiniteElement<dim, spacedim>>
fe;
71 SmartPointer<const LinearAlgebra::distributed::Vector<double, MemorySpace::Host>>
density;
79 const Mapping<dim, spacedim>& mapping_,
80 const FiniteElement<dim, spacedim>& fe_,
81 const LinearAlgebra::distributed::Vector<double, MemorySpace::Host>& density_,
82 const unsigned int quadrature_order_)
122 for (std::size_t
i = 0;
i <
points.size(); ++
i) {
134 const Mapping<dim, spacedim>& mapping,
135 const Quadrature<dim>& quadrature)
137 update_values | update_quadrature_points | update_JxW_values)
144 update_values | update_quadrature_points | update_JxW_values)
186 void setup_source(
const DoFHandler<dim, spacedim>& dof_handler,
187 const Mapping<dim, spacedim>& mapping,
188 const FiniteElement<dim, spacedim>& fe,
189 const LinearAlgebra::distributed::Vector<double, MemorySpace::Host>& source_density,
190 const unsigned int quadrature_order);
197 void setup_target(
const std::vector<Point<spacedim>>& target_points,
198 const Vector<double>& target_density);
211 void solve(Vector<double>& potential,
221 void solve(Vector<double>& potential,
222 const SourceMeasure& source,
223 const TargetMeasure& target,
233 const Vector<double>& potentials,
234 std::vector<Point<spacedim>>& barycenters_out,
297 const Vector<double>& potentials,
298 const double epsilon,
299 const double tolerance)
const;
316 const DoFHandler<dim, spacedim> &dof_handler,
317 const Mapping<dim, spacedim> &mapping,
318 const Vector<double> &potential,
319 const std::vector<unsigned int> &potential_indices,
320 std::vector<LinearAlgebra::distributed::Vector<double, MemorySpace::Host>> &conditioned_densities);
335 Vector<double>& gradient_out);
343 LAPACKFullMatrix<double>& hessian_out);
358 : SolverControl(n, tol)
377 virtual State
check(
unsigned int step,
double value)
override
380 ExcMessage(
"Gradient vector not set in VerboseSolverControl"));
382 double check_value = 0.0;
383 std::string check_description;
389 ExcMessage(
"Target measure not set for component-wise check"));
393 double max_scaled_residual = -std::numeric_limits<double>::infinity();
394 for (
unsigned int j = 0; j <
gradient->size(); ++j) {
396 max_scaled_residual = std::max(max_scaled_residual, scaled_residual);
398 check_value = max_scaled_residual;
400 if (check_value < tolerance()) {
402 }
else if (check_value < 0) {
408 check_description =
"Max Scaled Residual (max |g_i| - T_i*tol): ";
410 <<
" - L-2 gradient norm: " << color << value <<
RESET
411 <<
" - " << check_description << color << check_value <<
RESET << std::endl;
424 if (check_value < tolerance()) {
426 }
else if (rel_residual < 0.5) {
432 check_description =
"L-1 gradient norm: ";
434 <<
" - L-2 gradient norm: " << color << value <<
RESET
435 <<
" - " << check_description << color << check_value <<
RESET
436 <<
" - Relative L-1 residual: " << color << rel_residual <<
RESET << std::endl;
440 return SolverControl::check(step, check_value);
457 const typename DoFHandler<dim, spacedim>::active_cell_iterator& cell,
461 const Point<spacedim>&,
462 const std::vector<std::size_t>&,
463 const std::vector<double>&,
464 const std::vector<double>&,
469 const double&)> function_call);
475 const Vector<double>& potentials,
479 double current_functional_val)
const;
486 const Vector<double>& potentials,
487 std::vector<Vector<double>>& barycenters_gradients_out,
488 std::vector<Point<spacedim>>& barycenters_out
491 const Vector<double>& potentials,
492 std::vector<Point<spacedim>>& barycenters_out);
A collection of distance functions, their gradients, and exponential maps.
A verbose solver control class that prints the progress of the solver.
double user_tolerance_for_componentwise
void set_target_measure(const Vector< double > &target_density, double user_tolerance)
const Vector< double > * target_measure
ConditionalOStream & pcout
VerboseSolverControl(unsigned int n, double tol, bool use_componentwise, ConditionalOStream &pcout_)
bool use_componentwise_check
void set_gradient(const Vector< double > &grad)
const Vector< double > * gradient
double get_last_check_value() const
virtual State check(unsigned int step, double value) override
A solver for semi-discrete optimal transport problems.
Vector< double > gradient
Vector< double > barycenters
unsigned int get_last_iteration_count() const
Returns the number of iterations of the last solve.
const unsigned int this_mpi_process
double get_last_functional_value() const
Returns the value of the functional at the last iteration.
std::function< Vector< double >(const Point< spacedim > &, const Point< spacedim > &)> distance_function_gradient
The gradient of the distance function.
Vector< double > barycenters_gradients
boost::geometry::index::rstar< 8 > RTreeParams
std::vector< Point< spacedim > > barycenters_points
SourceMeasure source_measure
The source measure.
double compute_geometric_radius_bound(const Vector< double > &potentials, const double epsilon, const double tolerance) const
Computes the geometric radius bound for truncating quadrature rules.
void set_distance_threshold(double threshold)
Sets the distance threshold for the solver.
bool validate_measures() const
const Vector< double > * current_potential
void local_assemble(const typename DoFHandler< dim, spacedim >::active_cell_iterator &cell, ScratchData &scratch, CopyData ©, std::function< void(CopyData &, const Point< spacedim > &, const std::vector< std::size_t > &, const std::vector< double > &, const std::vector< double > &, const double &, const double &, const double &, const double &, const double &)> function_call)
std::function< double(const Point< spacedim > &, const Point< spacedim > &)> distance_function
The distance function.
void compute_hessian(const Vector< double > &potential, LAPACKFullMatrix< double > &hessian_out)
Computes the Hessian matrix of the dual functional.
std::pair< Point< spacedim >, std::size_t > IndexedPoint
std::unique_ptr< SolverControl > solver_control
double get_last_distance_threshold() const
Returns the distance threshold used in the last solve.
void get_potential_conditioned_density(const DoFHandler< dim, spacedim > &dof_handler, const Mapping< dim, spacedim > &mapping, const Vector< double > &potential, const std::vector< unsigned int > &potential_indices, std::vector< LinearAlgebra::distributed::Vector< double, MemorySpace::Host > > &conditioned_densities)
Computes the conditional density of the source measure given a potential.
void set_distance_function(const std::string &distance_name)
Sets the distance function to be used by the solver.
double current_distance_threshold
void setup_target(const std::vector< Point< spacedim > > &target_points, const Vector< double > &target_density)
Sets up the target measure for the solver.
void compute_weighted_barycenters_non_euclidean(const Vector< double > &potentials, std::vector< Vector< double > > &barycenters_gradients_out, std::vector< Point< spacedim > > &barycenters_out)
void solve(Vector< double > &potential, const SotParameterManager::SolverParameters ¶ms)
Solves the optimal transport problem.
double compute_covering_radius() const
Computes the covering radius of the target measure with respect to the source domain.
boost::geometry::index::rtree< IndexedPoint, RTreeParams > RTree
void compute_weighted_barycenters_euclidean(const Vector< double > &potentials, std::vector< Point< spacedim > > &barycenters_out)
std::function< Point< spacedim >(const Point< spacedim > &, const Vector< double > &)> distance_function_exponential_map
The exponential map of the distance function.
const unsigned int n_mpi_processes
double effective_distance_threshold
std::vector< std::size_t > find_nearest_target_points(const Point< spacedim > &query_point) const
double min_target_density
std::string distance_name
The name of the distance function.
void setup_source(const DoFHandler< dim, spacedim > &dof_handler, const Mapping< dim, spacedim > &mapping, const FiniteElement< dim, spacedim > &fe, const LinearAlgebra::distributed::Vector< double, MemorySpace::Host > &source_density, const unsigned int quadrature_order)
Sets up the source measure for the solver.
void evaluate_weighted_barycenters(const Vector< double > &potentials, std::vector< Point< spacedim > > &barycenters_out, const SotParameterManager::SolverParameters ¶ms)
Evaluates the weighted barycenters of the power cells.
SotParameterManager::SolverParameters current_params
double get_C_global() const
Returns the global C value.
void compute_distance_threshold() const
std::vector< Vector< double > > barycenters_grads
TargetMeasure target_measure
The target measure.
bool get_convergence_status() const
Returns the convergence status of the last solve.
MPI_Comm mpi_communicator
double evaluate_functional(const Vector< double > &potential, Vector< double > &gradient_out)
Evaluates the dual functional and its gradient.
void configure(const SotParameterManager::SolverParameters ¶ms)
Configures the solver with the given parameters.
double compute_integral_radius_bound(const Vector< double > &potentials, double epsilon, double tolerance, double C_value, double current_functional_val) const
A struct to hold copy data for parallel assembly.
double functional_value
The value of the functional on the current cell.
Vector< double > barycenters_values
The barycenter values for the current cell.
CopyData(const unsigned int n_target_points)
Vector< double > gradient_values
The local contribution to the gradient.
double local_C_sum
The sum of the scale terms for this cell.
Vector< double > potential_values
The potential values at the target points.
A struct to hold scratch data for parallel assembly.
ScratchData(const ScratchData &other)
FEValues< dim, spacedim > fe_values
FEValues object for the current cell.
ScratchData(const FiniteElement< dim, spacedim > &fe, const Mapping< dim, spacedim > &mapping, const Quadrature< dim > &quadrature)
std::vector< double > density_values
The density values at the quadrature points of the current cell.
A struct to hold all the necessary information about the source measure.
SmartPointer< const Mapping< dim, spacedim > > mapping
Pointer to the mapping for the source mesh.
SmartPointer< const DoFHandler< dim, spacedim > > dof_handler
Pointer to the DoF handler for the source mesh.
unsigned int quadrature_order
The order of the quadrature rule to use for integration.
SourceMeasure(const DoFHandler< dim, spacedim > &dof_handler_, const Mapping< dim, spacedim > &mapping_, const FiniteElement< dim, spacedim > &fe_, const LinearAlgebra::distributed::Vector< double, MemorySpace::Host > &density_, const unsigned int quadrature_order_)
Constructor for the SourceMeasure struct.
SmartPointer< const LinearAlgebra::distributed::Vector< double, MemorySpace::Host > > density
Pointer to the density vector of the source measure.
SmartPointer< const FiniteElement< dim, spacedim > > fe
Pointer to the finite element for the source mesh.
bool initialized
Flag to check if source measure is set up.
A struct to hold all the necessary information about the target measure.
bool initialized
Flag to check if target measure is set up.
std::vector< Point< spacedim > > points
The points of the discrete target measure.
void initialize_rtree()
Initializes the R-tree with the target points.
Vector< double > density
The weights of the discrete target measure.
TargetMeasure(const std::vector< Point< spacedim > > &points_, const Vector< double > &density_)
Constructor for the TargetMeasure struct.
RTree rtree
An R-tree for fast spatial queries on the target points.