Commit: 2c2243c012d1844e459631593839ccd70d3f51be
Author: mattoverby
Date:   Tue Jul 28 19:14:06 2020 -0500
Branches: soc-2020-soft-body
https://developer.blender.org/rB2c2243c012d1844e459631593839ccd70d3f51be

cleanup

===================================================================

M       extern/softbody/src/admmpd_linsolve.cpp
M       extern/softbody/src/admmpd_linsolve.h
M       extern/softbody/src/admmpd_solver.cpp
M       extern/softbody/src/admmpd_solver.h
M       extern/softbody/src/admmpd_types.h
M       intern/softbody/admmpd_api.cpp
M       release/scripts/startup/bl_ui/properties_physics_softbody.py
M       source/blender/makesrna/intern/rna_object_force.c

===================================================================

diff --git a/extern/softbody/src/admmpd_linsolve.cpp 
b/extern/softbody/src/admmpd_linsolve.cpp
index 95751957a39..e926c36db15 100644
--- a/extern/softbody/src/admmpd_linsolve.cpp
+++ b/extern/softbody/src/admmpd_linsolve.cpp
@@ -23,6 +23,7 @@ void ConjugateGradients::init_solve(
                return;
 
        A3_PtP_CtC.resize(nx3,nx3);
+       b.resize(data->x.rows(),data->x.cols());
        CtC.resize(nx3,nx3);
        Ctd.resize(nx3);
        Ptq.resize(nx3);
@@ -45,7 +46,6 @@ void ConjugateGradients::solve(
        BLI_assert(options != NULL);
        int nx = data->x.rows();
        BLI_assert(nx > 0);
-       BLI_assert(data->b.rows() == nx);
        BLI_assert(data->C.cols() == nx*3);
        BLI_assert(data->d.rows() > 0);
        BLI_assert(data->C.rows() == data->d.rows());
@@ -68,11 +68,11 @@ void ConjugateGradients::solve(
 
        // Compute RHS
        VectorXd x3(nx*3);
-       data->b.noalias() = data->M_xbar + data->DtW2*(data->z-data->u);
+       b.noalias() = data->M_xbar + data->DtW2*(data->z-data->u);
        for (int i=0; i<nx; ++i)
        {
                b3_Ptq_Ctd.segment<3>(i*3) =
-                       data->b.row(i).transpose() + 
+                       b.row(i).transpose() + 
                        Ptq.segment<3>(i*3) +
                        Ctd.segment<3>(i*3);
                x3.segment<3>(i*3) = data->x.row(i);
diff --git a/extern/softbody/src/admmpd_linsolve.h 
b/extern/softbody/src/admmpd_linsolve.h
index eaed804afa2..1df2d4b35a3 100644
--- a/extern/softbody/src/admmpd_linsolve.h
+++ b/extern/softbody/src/admmpd_linsolve.h
@@ -39,6 +39,7 @@ public:
 protected:
        RowSparseMatrix<double> A3_PtP_CtC;
        RowSparseMatrix<double> CtC;
+       Eigen::MatrixXd b; // M xbar + DtW2(z-u)
        Eigen::VectorXd Ctd; // ck * Ct d
        Eigen::VectorXd Ptq; // pk * Pt q
        Eigen::VectorXd b3_Ptq_Ctd; // M xbar + DtW2(z-u) + ck Ct d + pk Pt q
diff --git a/extern/softbody/src/admmpd_solver.cpp 
b/extern/softbody/src/admmpd_solver.cpp
index 6302384f388..2f8214821d2 100644
--- a/extern/softbody/src/admmpd_solver.cpp
+++ b/extern/softbody/src/admmpd_solver.cpp
@@ -39,11 +39,12 @@ bool Solver::init(
        data->x = mesh->rest_prim_verts();
        data->v.resize(data->x.rows(), 3);
        data->v.setZero();
-       data->tets = mesh->prims();
        mesh->compute_masses(data->x, options->density_kgm3, data->m);
-       init_matrices(options,data);
+       init_matrices(mesh,options,data);
 
-       printf("Solver::init:\n\tNum tets: %d\n\tNum verts: 
%d\n",(int)data->tets.rows(),(int)data->x.rows());
+       int nt = mesh->prims().rows();
+       int nx = data->x.rows();
+       printf("Solver::init:\n\tNum tets: %d\n\tNum verts: %d\n",nt,nx);
 
        return true;
 } // end init
@@ -60,8 +61,8 @@ int Solver::solve(
        BLI_assert(data->x.rows() > 0);
        BLI_assert(options->max_admm_iters > 0);
 
-       update_pin_matrix(mesh,options,data);
-       update_global_matrix(options,data);
+       update_pin_matrix(mesh,options,data); // P,q
+       update_global_matrix(options,data); // A+PtP
 
        ConjugateGradients cg;
        cg.init_solve(options,data);
@@ -83,8 +84,16 @@ int Solver::solve(
                update_collisions(options,data,collision);
 
                // Solve Ax=b s.t. Px=q and Cx=d
+               data->x_prev = data->x;
                cg.solve(options,data,collision);
 
+               // Check convergence
+               if (options->min_res>0)
+               {
+                       if (residual_norm(options,data) < options->min_res)
+                               break;
+               }
+
        } // end solver iters
 
        // Update velocity (if not static solve)
@@ -94,6 +103,16 @@ int Solver::solve(
        return iters;
 } // end solve
 
+double Solver::residual_norm(
+       const Options *options,
+       SolverData *data)
+{
+       (void)(options);
+       double ra = ((data->D*data->x) - data->z).norm();
+       double rx = (data->D*(data->x-data->x_prev)).norm();
+       return ra + rx;
+}
+
 void Solver::init_solve(
        const Mesh *mesh,
        const Options *options,
@@ -220,6 +239,7 @@ void Solver::update_collisions(
 } // end update constraints
 
 void Solver::init_matrices(
+       const Mesh *mesh,
        const Options *options,
        SolverData *data)
 {
@@ -243,15 +263,15 @@ void Solver::init_matrices(
 
        // Add per-element energies to data
        std::vector<Triplet<double> > trips;
-       append_energies(options,data,trips);
+       append_energies(mesh,options,data,trips);
        if (trips.size()==0)
        {
                throw_err("compute_matrices","No reduction coeffs");
        }
        int n_row_D = trips.back().row()+1;
 
-       RowSparseMatrix<double> W2;
-       compute_weight_matrix_squared(options,data,n_row_D,&W2);
+       update_weight_matrix(options,data,n_row_D);
+       RowSparseMatrix<double> W2 = data->W*data->W;
 
        // Constraint data
        data->C.resize(1,nx*3);
@@ -263,8 +283,6 @@ void Solver::init_matrices(
        data->D.resize(n_row_D,nx);
        data->D.setFromTriplets(trips.begin(), trips.end());
        data->DtW2 = data->D.transpose() * W2;
-       data->b.resize(nx,3);
-       data->b.setZero();
        update_global_matrix(options,data);
 
        // Perform factorization
@@ -278,30 +296,29 @@ void Solver::init_matrices(
 
 } // end compute matrices
 
-void Solver::compute_weight_matrix_squared(
+void Solver::update_weight_matrix(
        const Options *options,
        SolverData *data,
-       int rows,
-       RowSparseMatrix<double> *W2) const
+       int rows)
 {
        (void)(options);
-       W2->resize(rows,rows);
+       data->W.resize(rows,rows);
        VectorXi W_nnz = VectorXi::Ones(rows);
-       W2->reserve(W_nnz);
+       data->W.reserve(W_nnz);
        int ne = data->indices.size();
        if (ne != (int)data->weights.size())
-               throw_err("compute_weight_matrix","bad num indices/weights");
+               throw_err("update_weight_matrix","bad num indices/weights");
 
        for (int i=0; i<ne; ++i)
        {
                const Vector3i &idx = data->indices[i];
                if (idx[0]+idx[1] > rows)
-                       throw_err("compute_weight_matrix","bad matrix dim");
+                       throw_err("update_weight_matrix","bad matrix dim");
 
                for (int j=0; j<idx[1]; ++j)
-                       W2->coeffRef(idx[0]+j,idx[0]+j) = 
data->weights[i]*data->weights[i];
+                       data->W.coeffRef(idx[0]+j,idx[0]+j) = data->weights[i];
        }
-       W2->finalize();
+       data->W.finalize();
 }
 
 void Solver::update_pin_matrix(
@@ -354,30 +371,32 @@ void Solver::update_global_matrix(
        if (dt2 < 0) // static solve
                dt2 = 1.0;
 
-       SparseMatrix<double> A = data->DtW2 * data->D;
+       data->A = data->DtW2 * data->D;
        data->A_diag_max = 0;
        for (int i=0; i<nx; ++i)
        {
-               A.coeffRef(i,i) += data->m[i]/dt2;
-               double Aii = A.coeff(i,i);
+               data->A.coeffRef(i,i) += data->m[i]/dt2;
+               double Aii = data->A.coeff(i,i);
                if (Aii>data->A_diag_max)
                        data->A_diag_max = Aii;
        }
 
        SparseMatrix<double> A3;
-       geom::make_n3<double>(A,A3);
+       geom::make_n3<double>(data->A,A3);
        double pk = options->mult_pk * data->A_diag_max;
        data->A3_plus_PtP = A3 + pk * data->P.transpose()*data->P;
 }
 
 void Solver::append_energies(
+       const Mesh *mesh,
        const Options *options,
        SolverData *data,
        std::vector<Triplet<double> > &D_triplets)
 {
        BLI_assert(data != NULL);
        BLI_assert(options != NULL);
-       int nt = data->tets.rows();
+       Ref<const MatrixXi> tets = mesh->prims();
+       int nt = tets.rows();
        BLI_assert(nt > 0);
 
        int nx = data->x.rows();
@@ -398,7 +417,7 @@ void Solver::append_energies(
        int energy_index = 0;
        for (int i=0; i<nt; ++i)
        {
-               RowVector4i ele = data->tets.row(i);
+               RowVector4i ele = tets.row(i);
 
                // Initialize the energy
                data->rest_volumes.emplace_back();
diff --git a/extern/softbody/src/admmpd_solver.h 
b/extern/softbody/src/admmpd_solver.h
index 3514d768d50..d3b1a99c329 100644
--- a/extern/softbody/src/admmpd_solver.h
+++ b/extern/softbody/src/admmpd_solver.h
@@ -32,31 +32,45 @@ public:
 
 protected:
 
-    void update_collisions(
+    // Returns the combined residual norm
+    double residual_norm(
         const Options *options,
-        SolverData *data,
-        Collision *collision);
+        SolverData *data);
 
+    // Computes start-of-solve quantites
     void init_solve(
         const Mesh *mesh,
         const Options *options,
         SolverData *data,
         Collision *collision);
 
+    // Performs collision detection
+    // and updates C, d
+    void update_collisions(
+        const Options *options,
+        SolverData *data,
+        Collision *collision);
+
+    // Update z and u in parallel
        void solve_local_step(
         const Options *options,
         SolverData *data);
 
+    // Called once at start of simulation.
+    // Computes constant quantities
     void init_matrices(
+        const Mesh *mesh,
         const Options *options,
         SolverData *data);
 
-    void compute_weight_matrix_squared(
+    // Computes the W matrix
+    // from the current weights
+    void update_weight_matrix(
         const Options *options,
         SolverData *data,
-        int rows,
-        RowSparseMatrix<double> *W2) const;
+        int rows);
 
+    // Linearizes pin constraints P, q
     void update_pin_matrix(
         const Mesh *mesh,
         const Options *options,
@@ -67,7 +81,9 @@ protected:
         const Options *options,
         SolverData *data);
 
+    // Generates energies from the mesh
        void append_energies(
+        const Mesh *mesh,
                const Options *options,
                SolverData *data,
                std::vector<Eigen::Triplet<double> > &D_triplets);
diff --git a/extern/softbody/src/admmpd_types.h 
b/extern/softbody/src/admmpd_types.h
index 55a15f3c44f..4f9ea607b53 100644
--- a/extern/softbody/src/admmpd_types.h
+++ b/extern/softbody/src/admmpd_types.h
@@ -58,20 +58,19 @@ struct Options {
 };
 
 struct SolverData {
-    // Set from input
-    Eigen::MatrixXi tets; // elements t x 4, copy from mesh
     Eigen::MatrixXd x; // vertices, n x 3
     Eigen::MatrixXd v; // velocity, n x 3
- 
     Eigen::MatrixXd x_start; // x at t=0 (and goal if k>0), n x 3
+    Eigen::MatrixXd x_prev; // x at k-1
     Eigen::VectorXd m; // masses, n x 1
     Eigen::MatrixXd z; // ADMM z variable
     Eigen::MatrixXd u; // ADMM u aug lag with W inv
     Eigen::MatrixXd M_xbar; // M*(x + dt v)
     Eigen::MatrixXd Dx; // D * x
-    Eigen::MatrixXd b; // M xbar + DtW2(z-u)
     RowSparseMatrix<double> D; // reduction matrix
     RowSparseMatrix<double> DtW2; // D'W'W
+    RowSparseMatrix<double> A; // M + DtW'WD
+    RowSparseMatrix<double> W; // weight matrix
 
     double A_diag_max; // Max coeff of diag of A
     RowSparseMatrix<double> A3_plus_PtP; // A + pk PtP replicated
diff --git a/intern/softbody/admmpd_api.cpp b/intern/softbody/admmpd_api.cpp
index c599f59391d..c4be926aa88 100644
--- a/intern/softbody/admmpd_api.cpp
+++ b/intern/softbody/admmpd_api.cpp
@@ -178,6 +178,7 @@ static inline int 
admmpd_init_with_tetgen(ADMMPDInterfaceData *iface, Object *ob
         if (di

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to