3 #include <polysolve/nonlinear/Problem.hpp>
12 #include <polysolve/nonlinear/Solver.hpp>
22 using typename polysolve::nonlinear::Problem::Scalar;
23 using typename polysolve::nonlinear::Problem::THessian;
24 using typename polysolve::nonlinear::Problem::TVector;
30 double value(
const TVector& x)
override;
31 void gradient(
const TVector& x, TVector& gradv)
override;
34 throw std::runtime_error(
"Sparse functions do not exist, use dense solver");
40 bool is_step_valid(
const TVector& x0,
const TVector& x1)
override;
43 std::vector<std::array<double, S>>
m_cells;
53 std::vector<std::array<double, S>>& cells)
60 constexpr int64_t size = S == 6 ? 2 : 3;
61 Eigen::Matrix<double, size, 1> tmp;
63 for (int64_t d = 0; d < size; ++d) {
64 tmp(d) = m_cells[0][d];
74 for (
auto c : m_cells) {
75 if constexpr (S == 6) {
76 assert(x.size() == 2);
85 assert(x.size() == 3);
104 constexpr int64_t size = S == 6 ? 2 : 3;
107 Eigen::Matrix<double, size, 1> tmp(size);
112 for (
auto c : m_cells) {
113 if constexpr (S == 6) {
114 assert(x.size() == 2);
122 assert(x.size() == 3);
132 gradv += double(p) *
pow(tmp2, p - 1) * tmp;
142 Eigen::MatrixXd& hessian)
145 constexpr int64_t size = S == 6 ? 2 : 3;
146 hessian.resize(size, size);
148 Eigen::Matrix<double, size, size> tmp;
151 Eigen::Matrix<double, size, 1> tmpj(size);
154 for (
auto c : m_cells) {
155 if constexpr (S == 6) {
156 assert(x.size() == 2);
165 assert(x.size() == 3);
176 hessian += (p) * (p - 1) *
std::pow(tmp2, p - 2) * tmpj * tmpj.transpose() +
194 constexpr int64_t size = S == 6 ? 2 : 3;
195 Eigen::Matrix<double, size, 1> p0 = x1, p1, p2, p3;
196 if constexpr (S == 6) {
197 for (
const auto& c : m_cells) {
204 for (
const auto& c : m_cells) {
205 p1 << c[3], c[4], c[5];
206 p2 << c[6], c[7], c[8];
207 p3 << c[9], c[10], c[11];
216 Eigen::Matrix<double, size, 1> x0m = x0;
249 m_solver = polysolve::nonlinear::Solver::create(
265 mesh().top_simplex_type());
268 std::vector<std::array<double, 6>> cells;
280 accessor.vector_attribute(simplex.
tuple())[d] =
Rational(x[d],
true);
282 }
catch (
const std::exception&) {
288 std::vector<std::array<double, 12>> cells;
318 cell.primitive_type(),
332 std::cout <<
"error here" << std::endl;
336 std::array<double, 12> single_cell;
337 std::vector<Vector3r> ps;
338 for (
size_t i = 0; i < 4; ++i) {
341 const auto p = accessor.const_vector_attribute(v);
343 single_cell[3 * i + 0] = p[0].to_double();
344 single_cell[3 * i + 1] = p[1].to_double();
345 single_cell[3 * i + 2] = p[2].to_double();
347 if (!p[0].is_rounded() || !p[1].is_rounded() || !p[2].is_rounded())
return {};
353 cells.emplace_back(single_cell);
362 std::cout <<
"step is not valid!!!!!!!!!!!!!!!!" << std::endl;
372 }
catch (
const std::exception&) {
391 accessor.vector_attribute(simplex.
tuple())[d] =
392 Rational((1 - alpha) * x0[d] + alpha * x[d],
true);
405 mesh().top_simplex_type());
408 std::vector<std::array<double, 6>> cells;
420 accessor.vector_attribute(simplex.
tuple())[d] = x[d];
422 }
catch (
const std::exception&) {
428 std::vector<std::array<double, 12>> cells;
435 cell.primitive_type(),
449 std::cout <<
"error here" << std::endl;
453 std::array<double, 12> single_cell;
454 std::vector<Vector3d> ps;
455 for (
size_t i = 0; i < 4; ++i) {
458 const auto p = accessor.const_vector_attribute(v);
460 single_cell[3 * i + 0] = p[0];
461 single_cell[3 * i + 1] = p[1];
462 single_cell[3 * i + 2] = p[2];
468 cells.emplace_back(single_cell);
477 std::cout <<
"step is not valid!!!!!!!!!!!!!!!!" << std::endl;
487 }
catch (
const std::exception&) {
506 accessor.vector_attribute(simplex.
tuple())[d] = (1 - alpha) * x0[d] + alpha * x[d];
attribute::Accessor< T, Mesh, D > create_accessor(const attribute::MeshAttributeHandle &handle)
std::vector< std::shared_ptr< Mesh > > get_child_meshes() const
returns the direct multimesh child meshes for the current mesh
int64_t dimension() const
auto as() const -> const held_handle_type< held_type_from_primitive< T >()> &
std::array< double, NV *DIM > get_raw_coordinates(const simplex::Simplex &domain_simplex, const std::optional< simplex::Simplex > &variable_simplex={}) const
std::vector< std::array< double, S > > m_cells
void hessian(const TVector &x, THessian &hessian) override
bool is_step_valid(const TVector &x0, const TVector &x1) override
WMTKAMIPSProblem(std::vector< std::array< double, S >> &cells)
void solution_changed(const TVector &new_x) override
double value(const TVector &x) override
void gradient(const TVector &x, TVector &gradv) override
TVector initial_value() const
polysolve::json m_linear_solver_params
polysolve::json m_nonlinear_solver_params
std::vector< simplex::Simplex > execute(const simplex::Simplex &simplex) override
returns an empty vector in case of failure
std::shared_ptr< polysolve::nonlinear::Solver > m_solver
const attribute::MeshAttributeHandle & m_coordinate_handle
AMIPSOptimizationSmoothing(Mesh &mesh, const attribute::MeshAttributeHandle &coords)
virtual std::vector< simplex::Simplex > execute(const simplex::Simplex &simplex) override
returns an empty vector in case of failure
const Mesh & mesh() const
const Tuple & tuple() const
static bool equal(const Mesh &m, const Simplex &s0, const Simplex &s1)
bool is_ccw(const Tuple &t)
void Tet_AMIPS_jacobian(const std::array< double, 12 > &T, Eigen::Vector3d &result_0)
void Tri_AMIPS_hessian(const std::array< double, 6 > &T, Eigen::Matrix2d &result_0)
void Tri_AMIPS_jacobian(const std::array< double, 6 > &T, Eigen::Vector2d &result_0)
double Tet_AMIPS_energy(const std::array< double, 12 > &T)
void Tet_AMIPS_hessian(const std::array< double, 12 > &T, Eigen::Matrix3d &result_0)
double Tri_AMIPS_energy(const std::array< double, 6 > &T)
std::vector< Tuple > vertices(const Mesh &m, const Simplex &simplex)
std::vector< Simplex > cofaces_single_dimension_simplices(const Mesh &mesh, const Simplex &simplex, PrimitiveType cofaces_type)
SimplexCollection faces_single_dimension(const Mesh &mesh, const Simplex &simplex, const PrimitiveType face_type)
Returns a vector with all faces in the boundary of a simplex of the given dimension.
int wmtk_orient3d(const Eigen::Ref< const Eigen::Vector3< Rational >> &p0, const Eigen::Ref< const Eigen::Vector3< Rational >> &p1, const Eigen::Ref< const Eigen::Vector3< Rational >> &p2, const Eigen::Ref< const Eigen::Vector3< Rational >> &p3)
int wmtk_orient2d(double p0x, double p0y, double p1x, double p1y, double p2x, double p2y)
Vector< double, 3 > Vector3d
spdlog::logger & opt_logger()
Retrieves the logger for the optimization.
Rational pow(const Rational &x, int p)