@@ -168,6 +168,11 @@ void neo_hookean(RXMeshStatic& rx, T dx)
168168 ceiling_barrier_energy (
169169 problem, contact_area, time_step, ground_n, ground_o, dhat, kappa);
170170
171+ DenseMatrix<T, Eigen::RowMajor> dir (
172+ rx, problem.grad .rows (), problem.grad .cols ());
173+
174+ DenseMatrix<T, Eigen::RowMajor> grad (
175+ rx, problem.grad .rows (), problem.grad .cols ());
171176
172177 T line_search_init_step = 0 ;
173178
@@ -193,6 +198,11 @@ void neo_hookean(RXMeshStatic& rx, T dx)
193198 timer.add (" LinearSolver" );
194199 timer.add (" Diff" );
195200
201+ // add_contact(
202+ // rx, problem.vv_pairs, v_dbc[0], v_dbc[1], v_dbc[2], is_dbc, x, dhat);
203+ // problem.update_hessian();
204+ // printf("\n");
205+
196206 auto step_forward = [&]() {
197207 // x_tilde = x + v*h
198208 timer.start (" Step" );
@@ -221,14 +231,22 @@ void neo_hookean(RXMeshStatic& rx, T dx)
221231 rx, is_dbc, x, v_dbc_vel, v_dbc_limit, time_step, dbc_target);
222232
223233 // evaluate energy
224- add_contact (rx, problem.vv_pairs , v_dbc[0 ], is_dbc, x, dhat);
234+ add_contact (rx,
235+ problem.vv_pairs ,
236+ v_dbc[0 ],
237+ v_dbc[1 ],
238+ v_dbc[2 ],
239+ is_dbc,
240+ x,
241+ dhat);
225242 problem.update_hessian ();
226243 problem.eval_terms ();
227244 {
228245 CUDA_ERROR (cudaGetLastError ());
229246 CUDA_ERROR (cudaDeviceSynchronize ());
230247 }
231248
249+ grad.copy_from (problem.grad , DEVICE, DEVICE);
232250 // DBC satisfied
233251 check_dbc_satisfied (
234252 rx, is_dbc_satisfied, x, is_dbc, dbc_target, time_step, tol);
@@ -244,18 +262,25 @@ void neo_hookean(RXMeshStatic& rx, T dx)
244262 // get newton direction
245263 newton_solver.compute_direction ();
246264
265+ dir.copy_from (newton_solver.dir , DEVICE, DEVICE);
247266 // residual is abs_max(newton_dir)/ h
248267 T residual = newton_solver.dir .abs_max () / time_step;
249268
250269 T f = problem.get_current_loss ();
251270 RXMESH_INFO (
252- " *******Step: {}, Energy: {}, Residual: {}" , steps, f, residual);
271+ " *******Step: {}, Energy: {}, Residual: {}, DBC_satisfied= {}" ,
272+ steps,
273+ f,
274+ residual,
275+ num_satisfied);
253276
254277 int iter = 0 ;
255278 while (residual > tol || num_satisfied != num_dbc_vertices) {
256279
257280 if (residual <= tol && num_satisfied != num_dbc_vertices) {
258281 dbc_stiff.multiply (T (2 ));
282+ problem.eval_terms ();
283+ newton_solver.compute_direction ();
259284 }
260285
261286 T nh_step = neo_hookean_step_size (rx, x, newton_solver.dir , alpha);
@@ -272,10 +297,22 @@ void neo_hookean(RXMeshStatic& rx, T dx)
272297 line_search_init_step = std::min (nh_step, bar_step);
273298
274299 // TODO: line search should pass the step to the friction energy
275- newton_solver.line_search (line_search_init_step, 0.5 );
300+ bool ls_success =
301+ newton_solver.line_search (line_search_init_step, 0.5 , 64 , 0.0 );
302+
303+ if (!ls_success) {
304+ RXMESH_WARN (" Line search failed!" );
305+ }
276306
277307 // evaluate energy
278- add_contact (rx, problem.vv_pairs , v_dbc[0 ], is_dbc, x, dhat);
308+ add_contact (rx,
309+ problem.vv_pairs ,
310+ v_dbc[0 ],
311+ v_dbc[1 ],
312+ v_dbc[2 ],
313+ is_dbc,
314+ x,
315+ dhat);
279316 problem.update_hessian ();
280317 problem.eval_terms ();
281318 {
@@ -301,9 +338,20 @@ void neo_hookean(RXMeshStatic& rx, T dx)
301338 // residual is abs_max(newton_dir)/ h
302339 residual = newton_solver.dir .abs_max () / time_step;
303340
304- RXMESH_INFO (" Subsetp: {}, F: {}, R: {}" , iter, f, residual);
341+ RXMESH_INFO (
342+ " Subsetp: {}, F: {}, R: {}, line_search_init_step={}, "
343+ " DBC_satisfied= {}" ,
344+ iter,
345+ f,
346+ residual,
347+ line_search_init_step,
348+ num_satisfied);
305349
306350 iter++;
351+
352+ if (iter > 10 ) {
353+ break ;
354+ }
307355 }
308356
309357 RXMESH_INFO (" \n ===================\n " );
@@ -325,7 +373,7 @@ void neo_hookean(RXMeshStatic& rx, T dx)
325373 };
326374
327375#if USE_POLYSCOPE
328- draw (rx, x, velocity, step_forward, steps);
376+ draw (rx, x, velocity, step_forward, dir, grad, steps);
329377#else
330378 while (steps < 5 ) {
331379 step_forward ();
0 commit comments