@@ -36,14 +36,14 @@ FrictionEnergy<T, dim>::FrictionEnergy(const FrictionEnergy<T, dim> &rhs)
3636 : pimpl_{std::make_unique<Impl>(*rhs.pimpl_ )} {}
3737
3838template <typename T, int dim>
39- FrictionEnergy<T, dim>::FrictionEnergy(const std::vector<T> &v, const std::vector<T> &mu_lambda, T hhat, const Eigen::Matrix<T, dim, 1 > &n)
39+ FrictionEnergy<T, dim>::FrictionEnergy(const std::vector<T> &v, T hhat, const std::vector<T > &n)
4040 : pimpl_{std::make_unique<Impl>()}
4141{
4242 pimpl_->N = v.size () / dim;
4343 pimpl_->device_v .copy_from (v);
44- pimpl_->device_mu_lambda .copy_from (mu_lambda );
44+ pimpl_->device_mu_lambda .resize (pimpl_-> N );
4545 pimpl_->hhat = hhat;
46- pimpl_->n = n ;
46+ pimpl_->n = Eigen::Map< const Eigen::Matrix<T, dim, 1 >>(n. data ()) ;
4747 pimpl_->device_grad .resize (pimpl_->N * dim);
4848 pimpl_->device_hess .resize_triplets (pimpl_->N * dim * dim);
4949 pimpl_->device_hess .reshape (v.size (), v.size ());
@@ -54,9 +54,14 @@ void FrictionEnergy<T, dim>::update_v(const DeviceBuffer<T> &v)
5454{
5555 pimpl_->device_v .view ().copy_from (v);
5656}
57+ template <typename T, int dim>
58+ void FrictionEnergy<T, dim>::update_mu_lambda(const DeviceBuffer<T> &mu_lambda)
59+ {
60+ pimpl_->device_mu_lambda .view ().copy_from (mu_lambda);
61+ }
5762
5863template <typename T, int dim>
59- T FrictionEnergy<T, dim>::f0(T vbarnorm, T Epsv, T hhat)
64+ T __device__ FrictionEnergy<T, dim>::f0(T vbarnorm, T Epsv, T hhat)
6065{
6166 if (vbarnorm >= Epsv)
6267 {
@@ -65,13 +70,13 @@ T FrictionEnergy<T, dim>::f0(T vbarnorm, T Epsv, T hhat)
6570 else
6671 {
6772 T vbarnormhhat = vbarnorm * hhat;
68- T Epsvhhat = Epsv * hhat;
73+ T epsvhhat = Epsv * hhat;
6974 return vbarnormhhat * vbarnormhhat * (-vbarnormhhat / 3.0 + epsvhhat) / (epsvhhat * epsvhhat) + epsvhhat / 3.0 ;
7075 }
7176}
7277
7378template <typename T, int dim>
74- T FrictionEnergy<T, dim>::f1_div_vbarnorm(T vbarnorm, T Epsv)
79+ T __device__ FrictionEnergy<T, dim>::f1_div_vbarnorm(T vbarnorm, T Epsv)
7580{
7681 if (vbarnorm >= Epsv)
7782 {
@@ -84,7 +89,7 @@ T FrictionEnergy<T, dim>::f1_div_vbarnorm(T vbarnorm, T Epsv)
8489}
8590
8691template <typename T, int dim>
87- T FrictionEnergy<T, dim>::f_hess_term(T vbarnorm, T Epsv)
92+ T __device__ FrictionEnergy<T, dim>::f_hess_term(T vbarnorm, T Epsv)
8893{
8994 if (vbarnorm >= Epsv)
9095 {
@@ -97,7 +102,7 @@ T FrictionEnergy<T, dim>::f_hess_term(T vbarnorm, T Epsv)
97102}
98103
99104template <typename T, int dim>
100- T Energy <T, dim>::val()
105+ T FrictionEnergy <T, dim>::val()
101106{
102107 auto &device_v = pimpl_->device_v ;
103108 auto &device_mu_lambda = pimpl_->device_mu_lambda ;
@@ -111,7 +116,11 @@ T Energy<T, dim>::val()
111116 Eigen::Matrix<T, dim, dim> T_mat = Eigen::Matrix<T, dim, dim>::Identity () - n * n.transpose ();
112117 if (device_mu_lambda (i) > 0 )
113118 {
114- Eigen::Matrix<T, dim, 1 > v = device_v.segment (i * dim, dim);
119+ Eigen::Matrix<T, dim, 1 > v;
120+ for (int j = 0 ; j < dim; ++j)
121+ {
122+ v (j) = device_v (i * dim + j);
123+ }
115124 Eigen::Matrix<T, dim, 1 > vbar = T_mat * v;
116125 T vbarnorm = vbar.norm ();
117126 T val = f0 (vbarnorm, epsv, hhat);
@@ -123,7 +132,7 @@ T Energy<T, dim>::val()
123132}
124133
125134template <typename T, int dim>
126- const DeviceBuffer<T> &Energy <T, dim>::grad()
135+ const DeviceBuffer<T> &FrictionEnergy <T, dim>::grad()
127136{
128137 auto &device_v = pimpl_->device_v ;
129138 auto &device_mu_lambda = pimpl_->device_mu_lambda ;
@@ -138,7 +147,11 @@ const DeviceBuffer<T> &Energy<T, dim>::grad()
138147 Eigen::Matrix<T, dim, dim> T_mat = Eigen::Matrix<T, dim, dim>::Identity () - n * n.transpose ();
139148 if (device_mu_lambda (i) > 0 )
140149 {
141- Eigen::Matrix<T, dim, 1 > v = device_v.segment (i * dim, dim);
150+ Eigen::Matrix<T, dim, 1 > v;
151+ for (int j = 0 ; j < dim; ++j)
152+ {
153+ v (j) = device_v (i * dim + j);
154+ }
142155 Eigen::Matrix<T, dim, 1 > vbar = T_mat * v;
143156 T vbarnorm = vbar.norm ();
144157 T grad_factor = f1_div_vbarnorm (vbarnorm, epsv);
@@ -153,7 +166,6 @@ const DeviceBuffer<T> &Energy<T, dim>::grad()
153166
154167 return device_grad;
155168}
156-
157169template <typename T, int dim>
158170const DeviceTripletMatrix<T, 1 > &FrictionEnergy<T, dim>::hess()
159171{
@@ -168,64 +180,38 @@ const DeviceTripletMatrix<T, 1> &FrictionEnergy<T, dim>::hess()
168180 int N = device_v.size () / dim;
169181 ParallelFor (256 ).apply (N, [device_v = device_v.cviewer (), device_mu_lambda = device_mu_lambda.cviewer (), device_hess_val = device_hess_val.viewer (), device_hess_row_idx = device_hess_row_idx.viewer (), device_hess_col_idx = device_hess_col_idx.viewer (), hhat, n, N, this ] __device__ (int i) mutable
170182 {
171- T T_mat[dim][dim];
172- for (int r = 0 ; r < dim; ++r)
173- {
174- for (int c = 0 ; c < dim; ++c)
175- {
176- T_mat[r][c] = (r == c ? 1.0 : 0.0 ) - n (r) * n (c);
177- }
178- }
183+ Eigen::Matrix<T, dim, dim> T_mat = Eigen::Matrix<T, dim, dim>::Identity () - n * n.transpose ();
179184 if (device_mu_lambda (i) > 0 )
180185 {
181- T vbar[ dim] = { 0 } ;
186+ Eigen::Matrix<T, dim, 1 > v ;
182187 for (int j = 0 ; j < dim; ++j)
183188 {
184- for (int k = 0 ; k < dim; ++k)
185- {
186- vbar[j] += T_mat[j][k] * device_v (i * dim + k);
187- }
188- }
189- T vbarnorm = 0 ;
190- for (int j = 0 ; j < dim; ++j)
191- {
192- vbarnorm += vbar[j] * vbar[j];
193- }
194- vbarnorm = sqrt (vbarnorm);
195- T inner_term[dim][dim];
196- for (int r = 0 ; r < dim; ++r)
197- {
198- for (int c = 0 ; c < dim; ++c)
199- {
200- inner_term[r][c] = (r == c ? 1.0 : 0.0 );
201- }
189+ v (j) = device_v (i * dim + j);
202190 }
203- T hess_factor = f_hess_term (vbarnorm, epsv);
191+ Eigen::Matrix<T, dim, 1 > vbar = T_mat * v;
192+ T vbarnorm = vbar.norm ();
193+ Eigen::Matrix<T, dim, dim> inner_term = Eigen::Matrix<T, dim, dim>::Identity () * f1_div_vbarnorm (vbarnorm, epsv);
204194 if (vbarnorm != 0 )
205195 {
206- for (int r = 0 ; r < dim; ++r)
207- {
208- for (int c = 0 ; c < dim; ++c)
209- {
210- inner_term[r][c] += hess_factor / vbarnorm * vbar[r] * vbar[c];
211- }
212- }
196+ inner_term += f_hess_term (vbarnorm, epsv) / vbarnorm * vbar * vbar.transpose ();
213197 }
214- for (int j = 0 ; j < dim; ++j)
198+ Eigen::Matrix<T, dim, dim> local_hess;
199+ make_PSD (inner_term, local_hess);
200+ local_hess = device_mu_lambda (i) * T_mat * local_hess * T_mat.transpose () / hhat;
201+ for (int j = 0 ; j < dim; ++j)
215202 {
216- for (int k = 0 ; k < dim; ++k)
203+ for (int k = 0 ; k < dim; ++k)
217204 {
218205 int idx = i * dim * dim + j * dim + k;
219206 device_hess_row_idx (idx) = i * dim + j;
220207 device_hess_col_idx (idx) = i * dim + k;
221- device_hess_val (idx) = device_mu_lambda (i) * inner_term[j][k] / hhat ;
208+ device_hess_val (idx) = local_hess (j, k) ;
222209 }
223210 }
224211 } })
225212 .wait ();
226213 return device_hess;
227214}
228-
229215template class FrictionEnergy <float , 2 >;
230216template class FrictionEnergy <float , 3 >;
231217template class FrictionEnergy <double , 2 >;
0 commit comments