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)
58 Eigen::Matrix<double, -1, 1>
61 constexpr int64_t size = S == 6 ? 2 : 3;
62 Eigen::Matrix<double, size, 1> tmp;
64 for (int64_t d = 0; d < size; ++d) {
65 tmp(d) = m_cells[0][d];
75 for (
auto c : m_cells) {
76 if constexpr (S == 6) {
77 assert(x.size() == 2);
86 assert(x.size() == 3);
107 constexpr int64_t size = S == 6 ? 2 : 3;
110 Eigen::Matrix<double, size, 1> tmp(size);
115 for (
auto c : m_cells) {
116 if constexpr (S == 6) {
117 assert(x.size() == 2);
125 assert(x.size() == 3);
135 gradv += double(p) *
pow(tmp2, p - 1) * tmp;
145 Eigen::MatrixXd& hessian)
148 constexpr int64_t size = S == 6 ? 2 : 3;
149 hessian.resize(size, size);
151 Eigen::Matrix<double, size, size> tmp;
154 Eigen::Matrix<double, size, 1> tmpj(size);
157 for (
auto c : m_cells) {
158 if constexpr (S == 6) {
159 assert(x.size() == 2);
168 assert(x.size() == 3);
179 hessian += (p) * (p - 1) *
std::pow(tmp2, p - 2) * tmpj * tmpj.transpose() +
197 constexpr int64_t size = S == 6 ? 2 : 3;
198 Eigen::Matrix<double, size, 1> p0 = x1, p1, p2, p3;
199 if constexpr (S == 6) {
200 for (
const auto& c : m_cells) {
207 for (
const auto& c : m_cells) {
208 p1 << c[3], c[4], c[5];
209 p2 << c[6], c[7], c[8];
210 p3 << c[9], c[10], c[11];
219 Eigen::Matrix<double, size, 1> x0m = x0;
239 ,
m_amips(position_mesh, coords)
255 m_solver = polysolve::nonlinear::Solver::create(
271 assert(child_simplices.size() > 0);
272 if (child_simplices.size() == 1) {
276 mesh().top_simplex_type());
281 std::vector<std::array<double, 12>> cells;
288 cell.primitive_type(),
302 std::cout <<
"error here" << std::endl;
306 std::array<double, 12> single_cell;
307 std::vector<Vector3d> ps;
308 for (
size_t i = 0; i < 4; ++i) {
311 const auto p = accessor.const_vector_attribute(v);
313 single_cell[3 * i + 0] = p[0];
314 single_cell[3 * i + 1] = p[1];
315 single_cell[3 * i + 2] = p[2];
321 cells.emplace_back(single_cell);
330 std::cout <<
"step is not valid!!!!!!!!!!!!!!!!" << std::endl;
340 }
catch (
const std::exception&) {
359 accessor.vector_attribute(simplex.
tuple())[d] = (1 - alpha) * x0[d] + alpha * x[d];
366 }
else if (child_simplices.size() == 2) {
376 auto pos_0 = accessor.const_vector_attribute(child_simplices[0].tuple());
377 auto pos_1 = accessor.const_vector_attribute(child_simplices[1].tuple());
379 double space_x = 0, space_y = 0, space_z = 0;
380 auto dist = pos_1 - pos_0;
381 if (
abs(dist[0]) >
abs(dist[1])) {
382 if (
abs(dist[0]) >
abs(dist[2])) {
388 if (
abs(dist[1]) >
abs(dist[2])) {
398 std::vector<std::array<double, 12>> cells;
405 cell.primitive_type(),
416 std::array<double, 12> single_cell;
417 std::vector<Vector3d> ps;
418 for (
size_t i = 0; i < 4; ++i) {
421 const auto p = accessor.const_vector_attribute(v);
423 single_cell[3 * i + 0] = p[0];
424 single_cell[3 * i + 1] = p[1];
425 single_cell[3 * i + 2] = p[2];
431 cells.emplace_back(single_cell);
441 cell.primitive_type(),
452 std::array<double, 12> single_cell;
453 std::vector<Vector3d> ps;
454 for (
size_t i = 0; i < 4; ++i) {
457 const auto p = accessor.const_vector_attribute(v);
459 single_cell[3 * i + 0] = p[0] - space_x;
460 single_cell[3 * i + 1] = p[1] - space_y;
461 single_cell[3 * i + 2] = p[2] - space_z;
467 cells.emplace_back(single_cell);
478 std::cout <<
"step is not valid!!!!!!!!!!!!!!!!" << std::endl;
488 }
catch (
const std::exception&) {
502 accessor.vector_attribute(child_simplices[0].tuple()) = x;
503 accessor.vector_attribute(child_simplices[1].tuple()) =
504 x +
Vector3d(space_x, space_y, space_z);
508 accessor.vector_attribute(child_simplices[0].tuple())[0] = pos_0[0];
509 accessor.vector_attribute(child_simplices[1].tuple())[0] = pos_0[0] + space_x;
510 }
else if (space_y > 0) {
511 accessor.vector_attribute(child_simplices[0].tuple())[1] = pos_0[1];
512 accessor.vector_attribute(child_simplices[1].tuple())[1] = pos_0[1] + space_y;
513 }
else if (space_z > 0) {
514 accessor.vector_attribute(child_simplices[0].tuple())[2] = pos_0[2];
515 accessor.vector_attribute(child_simplices[1].tuple())[2] = pos_0[2] + space_z;
attribute::Accessor< T, Mesh, D > create_accessor(const attribute::MeshAttributeHandle &handle)
simplex::Simplex map_to_parent(const simplex::Simplex &my_simplex) const
optimized map from a simplex from this mesh to its direct parent
std::vector< simplex::Simplex > map_to_child(const Mesh &child_mesh, const simplex::Simplex &my_simplex) const
optimized map fromsimplex from this mesh to one of its direct children
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 >()> &
void gradient(const TVector &x, TVector &gradv) override
void solution_changed(const TVector &new_x) override
bool is_step_valid(const TVector &x0, const TVector &x1) override
double value(const TVector &x) override
WMTKAMIPSProblem(std::vector< std::array< double, S >> &cells)
void hessian(const TVector &x, THessian &hessian) override
TVector initial_value() const
std::vector< std::array< double, S > > m_cells
const attribute::MeshAttributeHandle & m_coordinate_handle
AMIPSOptimizationSmoothingPeriodic(Mesh &periodic_mesh, Mesh &position_mesh, const attribute::MeshAttributeHandle &coords)
std::shared_ptr< polysolve::nonlinear::Solver > m_solver
std::vector< simplex::Simplex > execute(const simplex::Simplex &simplex) override
returns an empty vector in case of failure
polysolve::json m_linear_solver_params
polysolve::json m_nonlinear_solver_params
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)
Rational abs(const Rational &r0)
Vector< double, 3 > Vector3d
spdlog::logger & opt_logger()
Retrieves the logger for the optimization.
Rational pow(const Rational &x, int p)