@@ -305,6 +305,104 @@ class Force<MemorySpace,
305
305
}
306
306
};
307
307
308
+ template <class MemorySpace , class MechanicsType , class ThermalType ,
309
+ class ... ModelParams>
310
+ class Force <MemorySpace, ForceModel<PMB, MechanicsType, Fracture, ThermalType,
311
+ DynamicDensity, ModelParams...>>
312
+ : public Force<MemorySpace,
313
+ ForceModel<PMB, MechanicsType, Fracture, ModelParams...>>,
314
+ public Dilatation<MemorySpace,
315
+ ForceModel<PMB, MechanicsType, Fracture, ThermalType,
316
+ DynamicDensity, ModelParams...>>
317
+ {
318
+ public:
319
+ // Using the default exec_space.
320
+ using exec_space = typename MemorySpace::execution_space;
321
+ using model_type = ForceModel<PMB, MechanicsType, Fracture, ModelParams...>;
322
+ using base_type = BaseForce<MemorySpace>;
323
+
324
+ protected:
325
+ model_type _model;
326
+
327
+ using base_type::_energy_timer;
328
+ using base_type::_timer;
329
+
330
+ public:
331
+ Force ( const model_type model )
332
+ : base_type()
333
+ , _model( model )
334
+ {
335
+ }
336
+
337
+ template <class ForceType , class PosType , class ParticleType ,
338
+ class NeighborType >
339
+ void computeForceFull ( ForceType& f, const PosType& x, const PosType& u,
340
+ const ParticleType& particles,
341
+ const NeighborType& neighbor )
342
+ {
343
+ _timer.start ();
344
+ using neighbor_list_type = typename NeighborType::list_type;
345
+ auto neigh_list = neighbor.list ();
346
+ const auto mu = neighbor.brokenBonds ();
347
+
348
+ auto model = _model;
349
+ const auto vol = particles.sliceVolume ();
350
+ const auto nofail = particles.sliceNoFail ();
351
+ auto theta = particles.sliceDilatation ();
352
+
353
+ auto force_full = KOKKOS_LAMBDA ( const int i )
354
+ {
355
+ std::size_t num_neighbors =
356
+ Cabana::NeighborList<neighbor_list_type>::numNeighbor (
357
+ neigh_list, i );
358
+ for ( std::size_t n = 0 ; n < num_neighbors; n++ )
359
+ {
360
+ double fx_i = 0.0 ;
361
+ double fy_i = 0.0 ;
362
+ double fz_i = 0.0 ;
363
+
364
+ std::size_t j =
365
+ Cabana::NeighborList<neighbor_list_type>::getNeighbor (
366
+ neigh_list, i, n );
367
+
368
+ // Get the reference positions and displacements.
369
+ double xi, r, s;
370
+ double rx, ry, rz;
371
+ getDistanceComponents ( x, u, i, j, xi, r, s, rx, ry, rz );
372
+
373
+ model.thermalStretch ( s, i, j );
374
+
375
+ model.updateDensity ( i, theta ( i ) );
376
+
377
+ // Break if beyond critical stretch unless in no-fail zone.
378
+ if ( model.criticalStretch ( i, j, r, xi ) && !nofail ( i ) &&
379
+ !nofail ( j ) )
380
+ {
381
+ mu ( i, n ) = 0 ;
382
+ }
383
+ // Else if statement is only for performance.
384
+ else if ( mu ( i, n ) > 0 )
385
+ {
386
+ const double coeff = model.forceCoeff ( i, n, s, vol ( j ) );
387
+
388
+ double muij = mu ( i, n );
389
+ fx_i = muij * coeff * rx / r;
390
+ fy_i = muij * coeff * ry / r;
391
+ fz_i = muij * coeff * rz / r;
392
+
393
+ f ( i, 0 ) += fx_i;
394
+ f ( i, 1 ) += fy_i;
395
+ f ( i, 2 ) += fz_i;
396
+ }
397
+ }
398
+ };
399
+
400
+ neighbor.iterateLinear ( exec_space{}, force_full, particles,
401
+ " CabanaPD::ForcePMBDamage::computeFull" );
402
+ _timer.stop ();
403
+ }
404
+ };
405
+
308
406
template <class MemorySpace , class ... ModelParams>
309
407
class Force <MemorySpace,
310
408
ForceModel<LinearPMB, Elastic, NoFracture, ModelParams...>>
0 commit comments