PeriDEM 0.3.0
PeriDEM -- Peridynamics-based high-fidelity model for granular media
Loading...
Searching...
No Matches
material.h
Go to the documentation of this file.
1/*
2 * -------------------------------------------
3 * Copyright (c) 2021 - 2026 Prashant K. Jha
4 * -------------------------------------------
5 * PeriDEM https://github.com/prashjha/PeriDEM
6 *
7 * Distributed under the Boost Software License, Version 1.0. (See accompanying
8 * file LICENSE)
9 */
10
11#ifndef MATERIAL_PARTILCE_MATERIAL_H
12#define MATERIAL_PARTILCE_MATERIAL_H
13
14#include "influenceFn.h"
15#include "util/io.h"
16#include <stdexcept>
17#include "inp/materialDeck.h"
18#include "util/function.h"
19#include "util/point.h" // definition of Point
20#include <limits>
21#include <memory>
22#include <string>
23#include <vector>
24
25namespace {
26
28size_t dimension = 0;
29
31bool is_plane_strain = false;
32
34std::shared_ptr<material::BaseInfluenceFn> influence_fn;
35
42double getGlobalInfFn(const double &r) {
43 return influence_fn->getInfFn(r);
44}
45
55double getGlobalMoment(const size_t &i) {return influence_fn->getMoment(i);}
56
70double getModelBulkModulus(const size_t &dim, const bool &plane_strain,
71 const double &K, const double &G) {
72 if (dim != 2)
73 return K;
74 return plane_strain ? K + G / 3. : 9. * K * G / (3. * K + 4. * G);
75}
76}
77
78namespace material {
79
98class Material {
99
100public:
105 explicit Material(std::string name = "") : d_name(name) {}
106
112 virtual ~Material() {}
113
118 std::string name() { return d_name; }
119
124 size_t getDimension() const { return dimension; }
125
130 bool isPlaneStrain() const { return is_plane_strain; }
131
136 virtual bool isStateActive() const = 0;
137
147 virtual std::pair<double, double>
148 getBondEF(const double &r, const double &s, bool &fs,
149 const bool &break_bonds) const = 0;
150
161 virtual std::pair<double, double>
162 getBondEF(const double &r, const double &s, bool &fs, const double
163 &mx, const double &thetax) const = 0;
164
173 const util::Point &du) const = 0;
174
181 virtual double getS(const util::Point &dx, const util::Point &du) const = 0;
182
189 virtual double getSc(const double &r) const = 0;
190
197 virtual double getBreakSc(const double &r) const { return getSc(r); }
198
207 virtual double getDilatationEnergyDensity(const double &thetax) const {
208 return 0.;
209 }
210
215 virtual double getDensity() const = 0;
216
223 virtual double getInfFn(const double &r) const = 0;
224
234 virtual double getMoment(const size_t &i) const = 0;
235
241 virtual double getHorizon() const = 0;
242
250 virtual inp::MatData computeMaterialProperties(const size_t &dim) const = 0;
251
259 virtual std::string printStr(int nt, int lvl) const {
260
261 auto tabS = util::io::getTabS(nt);
262 std::ostringstream oss;
263 oss << tabS << "------- particle::Material --------" << std::endl
264 << std::endl;
265 oss << tabS << "Abstract class of peridynamic materials" << std::endl;
266 oss << tabS << "See RnpMaterial and PmbMaterial for implementation"
267 << std::endl;
268 oss << tabS << std::endl;
269
270 return oss.str();
271 }
272
279 virtual void print(int nt, int lvl) const { std::cout << printStr(nt, lvl); }
280
282 virtual void print() const { print(0, 0); }
283
284private:
286 std::string d_name;
287};
288
293class RnpMaterial : public Material {
294
295public:
302 RnpMaterial(inp::MaterialDeck &deck, const size_t &dim, const double &horizon)
303 : Material("RNPBond"), d_horizon(horizon), d_density(deck.d_density),
304 d_C(0.), d_beta(0.), d_rbar(0.), d_invFactor(0.),
305 d_factorSc(deck.d_checkScFactor),
306 d_irrevBondBreak(deck.d_irreversibleBondBreak) {
307
308 // set global fields
309 if (dimension != dim)
310 dimension = dim;
311
312 if (is_plane_strain != deck.d_isPlaneStrain)
313 is_plane_strain = deck.d_isPlaneStrain;
314
315 // create influence function
316 if (deck.d_influenceFnType == 0) {
317 if (influence_fn == nullptr)
318 influence_fn = std::make_shared<material::ConstInfluenceFn>(
319 deck.d_influenceFnParams, dim);
320 }
321 else if (deck.d_influenceFnType == 1) {
322 if (influence_fn == nullptr)
323 influence_fn = std::make_shared<material::LinearInfluenceFn>(
324 deck.d_influenceFnParams, dim);
325 }
326 else if (deck.d_influenceFnType == 2) {
327 if (influence_fn == nullptr)
328 influence_fn = std::make_shared<material::GaussianInfluenceFn>(
329 deck.d_influenceFnParams, dim);
330 }
331 else {
332 throw std::runtime_error(
334 << "Error: Influence function type = "
335 << deck.d_influenceFnType
336 << " is invalid.\n");
337 }
338
339 if (dim == 1)
340 d_invFactor = std::pow(horizon, 2) * 2.;
341 else if (dim == 2)
342 d_invFactor = std::pow(horizon, 3) * M_PI;
343 else if (dim == 3)
344 d_invFactor = std::pow(horizon, 4) * 4. * M_PI / 3.;
345
346 // check if we need to compute the material parameters
348 computeParameters(deck, dim);
349 else {
350 d_C = deck.d_bondPotentialParams[0];
352 d_rbar = std::sqrt(0.5 / d_beta);
353 }
354 };
355
357 bool isStateActive() const override { return false; };
358
387 std::pair<double, double> getBondEF(const double &r, const double &s,
388 bool &fs,
389 const bool &break_bonds) const override {
390
391 if (break_bonds && !fs && util::isGreater(std::abs(s), getBreakSc(r)))
392 fs = true;
393
394 // intact bonds follow the nonlinear potential; broken bonds keep the
395 // saturated energy and carry no force
396 if (!fs)
397 return std::make_pair(
398 getInfFn(r) * d_C *
399 (1. - std::exp(-d_beta * r * s * s)) / d_invFactor,
400 getInfFn(r) * 4. * s * d_C * d_beta *
401 std::exp(-d_beta * r * s * s) / d_invFactor);
402 else
403 return std::make_pair(getInfFn(r) * d_C / d_invFactor, 0.);
404 };
405
416 std::pair<double, double>
417 getBondEF(const double &r, const double &s, bool &fs, const double
418 &mx, const double &thetax) const override {
419
420 return this->getBondEF(r, s, fs, true);
421 };
422
431 const util::Point &du) const override {
432 return dx / dx.length();
433 };
434
441 double getS(const util::Point &dx, const util::Point &du) const override {
442 return dx.dot(du) / dx.dot(dx);
443 };
444
451 double getSc(const double &r) const override {
452 return d_rbar / std::sqrt(r);
453 };
454
464 double getBreakSc(const double &r) const override {
465 if (!d_irrevBondBreak)
466 return std::numeric_limits<double>::max();
467 return d_factorSc * getSc(r);
468 };
469
474 double getDensity() const override { return d_density; };
475
482 double getInfFn(const double &r) const override {
483 return getGlobalInfFn(r / d_horizon);
484 };
485
495 double getMoment(const size_t &i) const override {
496 return getGlobalMoment(i);
497 };
498
503 double getHorizon() const override { return d_horizon; };
504
512 inp::MatData computeMaterialProperties(const size_t &dim) const override {
513
514 auto data = inp::MatData();
515
516 // set Poisson's ratio to 1/4
517 data.d_nu = 0.25;
518
519 // get moment of influence function
520 double M = getMoment(dim);
521
522 // inverse of computeParameters
523 if (dim == 2) {
524 data.d_Gc = 4. * M * d_C / M_PI;
525 data.d_lambda = d_C * M * d_beta / 2.;
526 } else if (dim == 3) {
527 data.d_Gc = 3. * M * d_C / 2.;
528 data.d_lambda = 2. * d_C * M * d_beta / 5.;
529 }
530 data.d_mu = data.d_lambda;
531 data.d_G = data.d_lambda;
532 data.d_E = data.toELambda(data.d_lambda,
533 data.d_nu);
534 data.d_K =
535 data.toK(data.d_E, data.d_nu);
536 data.d_KIc = data.toKIc(
537 data.d_Gc, data.d_nu, data.d_E);
538
539 return data;
540 };
541
549 std::string printStr(int nt, int lvl) const override {
550
551 auto tabS = util::io::getTabS(nt);
552 std::ostringstream oss;
553 oss << tabS << "------- particle::RnpMaterial --------" << std::endl
554 << std::endl;
555 oss << tabS << "State active = " << 0 << std::endl;
556 oss << tabS << "Horizon = " << d_horizon << std::endl;
557 oss << tabS << "Influence fn address = " << influence_fn.get() << std::endl;
558 oss << tabS << "Influence fn info: " << std::endl;
559 oss << influence_fn->printStr(nt + 1, lvl);
560 oss << tabS << "Peridynamic parameters: " << std::endl;
561 oss << tabS << " C = " << d_C << std::endl;
562 oss << tabS << " beta = " << d_beta << std::endl;
563 oss << tabS << " r_bar = " << d_rbar << std::endl;
564 oss << tabS << " inv_factor = " << d_invFactor << std::endl;
565 oss << tabS << " factor_Sc = " << d_factorSc << std::endl;
566 oss << tabS << " irrev_bond_breaking = " << d_irrevBondBreak << std::endl;
567 oss << tabS << std::endl;
568
569 return oss.str();
570 }
571
578 void print(int nt, int lvl) const override {
579 std::cout << printStr(nt, lvl);
580 }
581
583 void print() const override { print(0, 0); }
584
585private:
592 void computeParameters(inp::MaterialDeck &deck, const size_t &dim) {
593 //
594 // Need following elastic and fracture properties
595 // 1. E or K
596 // 2. Gc or KIc
597 // For bond-based, Poisson's ratio is fixed to 1/4, so 2D must be plane
598 // strain (Lipton 2016; Jha 2025, sec. 7.2).
599 //
600 if (dim == 2 && !is_plane_strain) {
601 throw std::runtime_error(
603 << "Error: RNP calibration needs nu = 1/4, which in 2D means plane "
604 "strain. Set Is_Plane_Strain = true.\n");
605 }
606 if (util::isLess(deck.d_matData.d_E, 0.) &&
607 util::isLess(deck.d_matData.d_K, 0.)) {
608 throw std::runtime_error(
610 << "Error: Require either Young's modulus E or Bulk modulus K"
611 " to compute the RNP bond-based peridynamic parameters.\n");
612 }
613 if (util::isGreater(deck.d_matData.d_E, 0.) &&
614 util::isGreater(deck.d_matData.d_K, 0.)) {
615 std::cout << "Warning: Both Young's modulus E and Bulk modulus K are "
616 "provided.\n";
617 std::cout << "Warning: To compute the RNP bond-based peridynamic "
618 "parameters, we only require one of those.\n";
619 std::cout
620 << "Warning: Selecting Young's modulus to compute parameters.\n";
621 }
622
623 if (util::isLess(deck.d_matData.d_Gc, 0.) &&
624 util::isLess(deck.d_matData.d_KIc, 0.)) {
625 throw std::runtime_error(
627 << "Error: Require either critical energy release rate Gc or "
628 "critical stress intensity factor KIc to compute the RNP "
629 "bond-based peridynamic parameters.\n");
630 } else if (util::isGreater(deck.d_matData.d_Gc, 0.) &&
631 util::isGreater(deck.d_matData.d_KIc, 0.)) {
632 std::cout << "Warning: Both critical energy release rate Gc and critical "
633 "stress intensity factor KIc are provided.\n";
634 std::cout << "Warning: To compute the RNP bond-based peridynamic "
635 "parameters, we only require one of those.\n";
636 std::cout << "Warning: Selecting critical energy release rate Gc to "
637 "compute parameters.\n";
638 }
639
640 // set Poisson's ratio to 1/4
641 if (util::isGreater(deck.d_matData.d_nu, 0.) &&
642 std::abs(deck.d_matData.d_nu - 0.25) > 1.0e-12)
643 std::cout << "Warning: RNP bond-based model fixes nu = 1/4; ignoring "
644 "nu = " << deck.d_matData.d_nu << ".\n";
645 deck.d_matData.d_nu = 0.25;
646
647 // compute E if not provided or K if not provided
648 if (deck.d_matData.d_E > 0.)
649 deck.d_matData.d_K =
650 deck.d_matData.toK(deck.d_matData.d_E, deck.d_matData.d_nu);
651
652 if (deck.d_matData.d_K > 0. && deck.d_matData.d_E < 0.)
653 deck.d_matData.d_E =
654 deck.d_matData.toE(deck.d_matData.d_K, deck.d_matData.d_nu);
655
656 if (deck.d_matData.d_Gc > 0.)
657 deck.d_matData.d_KIc = deck.d_matData.toKIc(
658 deck.d_matData.d_Gc, deck.d_matData.d_nu, deck.d_matData.d_E);
659
660 if (deck.d_matData.d_KIc > 0. && deck.d_matData.d_Gc < 0.)
661 deck.d_matData.d_Gc = deck.d_matData.toGc(
662 deck.d_matData.d_KIc, deck.d_matData.d_nu, deck.d_matData.d_E);
663
664 // compute lame parameter
665 deck.d_matData.d_lambda =
667 deck.d_matData.d_G =
668 deck.d_matData.toGE(deck.d_matData.d_E, deck.d_matData.d_nu);
669 deck.d_matData.d_mu = deck.d_matData.d_G;
670
671 // get moment of influence function
672 double M = getMoment(dim);
673
674 // Small strain gives lambda = mu = C beta M / 2 (2D) and 2 C beta M / 5
675 // (3D); Gc = 4 C M / pi (2D) and 3 C M / 2 (3D). Jha 2025 eq. 83 takes
676 // Lipton's lambda, which is half the physical one (Lipton 2014, eq. 3.10).
677 if (dim == 2) {
678 d_C = M_PI * deck.d_matData.d_Gc / (4. * M);
679 d_beta = 2. * deck.d_matData.d_lambda / (d_C * M);
680 } else if (dim == 3) {
681 d_C = 2. * deck.d_matData.d_Gc / (3. * M);
682 d_beta = 5. * deck.d_matData.d_lambda / (2. * d_C * M);
683 }
684
685 d_rbar = std::sqrt(0.5 / d_beta);
686 };
687
688private:
689
691 double d_horizon;
692
694 double d_density;
695
702 double d_C;
703
705 double d_beta;
706
710 double d_rbar;
711
714
722
725};
726
731class PmbMaterial : public Material {
732
733public:
740 PmbMaterial(inp::MaterialDeck &deck, const size_t &dim, const double &horizon)
741 : Material("PMBBond"), d_horizon(horizon), d_density(deck.d_density),
742 d_c(0.), d_s0(0.), d_Jscale(1.) {
743
744 // set global fields
745 if (dimension != dim)
746 dimension = dim;
747
748 if (is_plane_strain != deck.d_isPlaneStrain)
749 is_plane_strain = deck.d_isPlaneStrain;
750
751 // create influence function
752 if (deck.d_influenceFnType == 0) {
753 if (influence_fn == nullptr)
754 influence_fn = std::make_shared<material::ConstInfluenceFn>(
755 deck.d_influenceFnParams, dim);
756 }
757 else if (deck.d_influenceFnType == 1) {
758 if (influence_fn == nullptr)
759 influence_fn = std::make_shared<material::LinearInfluenceFn>(
760 deck.d_influenceFnParams, dim);
761 }
762 else if (deck.d_influenceFnType == 2) {
763 if (influence_fn == nullptr)
764 influence_fn = std::make_shared<material::GaussianInfluenceFn>(
765 deck.d_influenceFnParams, dim);
766 }
767 else {
768 throw std::runtime_error(
770 << "Error: Influence function type = "
771 << deck.d_influenceFnType
772 << " is invalid.\n");
773 }
774
775 // check if we need to compute the material parameters
777 computeParameters(deck, dim);
778 else {
779 d_c = deck.d_bondPotentialParams[0];
780 d_s0 = deck.d_bondPotentialParams[1];
781 }
782 };
783
788 bool isStateActive() const override { return false; };
789
804 std::pair<double, double> getBondEF(const double &r, const double &s,
805 bool &fs,
806 const bool &break_bonds) const override {
807
808 if (!break_bonds)
809 return std::make_pair(getInfFn(r) * 0.25 * d_c * s *
810 s * r,
811 getInfFn(r) * d_c * s);
812
813 // Fracture: literature PMB is tension-only (s > s0). Absolute stretch is
814 // applied in pdForce when Model.Bond_Break = absolute_stretch.
815 if (!fs && util::isGreater(s, d_s0 + 1.0e-10))
816 fs = true;
817
818 // if bond is not fractured, return energy and force from nonlinear
819 // potential otherwise return energy of fractured bond, and zero force
820 if (!fs)
821 return std::make_pair(getInfFn(r) * 0.25 * d_c * s *
822 s * r,
823 getInfFn(r) * d_c * s);
824 else
825 return std::make_pair(
826 getInfFn(r) * 0.25 * d_c * d_s0 * d_s0 * r, 0.);
827 };
828
839 std::pair<double, double>
840 getBondEF(const double &r, const double &s, bool &fs, const double
841 &mx, const double &thetax) const override {
842
843 return this->getBondEF(r, s, fs, true);
844 };
845
854 const util::Point &du) const override {
855 return (dx + du) / (dx + du).length();
856 };
857
864 double getS(const util::Point &dx, const util::Point &du) const override {
865 return ((dx + du).length() - dx.length()) / dx.length();
866 };
867
874 double getSc(const double &r) const override { return d_s0; };
875
880 double getDensity() const override { return d_density; };
881
888 double getInfFn(const double &r) const override {
889 return getGlobalInfFn(r / d_horizon);
890 };
891
901 double getMoment(const size_t &i) const override {
902 return getGlobalMoment(i);
903 };
904
910 double getHorizon() const override { return d_horizon; };
911
919 inp::MatData computeMaterialProperties(const size_t &dim) const override {
920
921 auto data = inp::MatData();
922 data.d_nu = (dim == 2 && !is_plane_strain) ? 1. / 3. : 0.25;
923
924 // inverse of computeParameters, with c for J = 1
925 const double h = d_horizon;
926 const double c = d_c * d_Jscale;
927 if (dim == 2) {
928 data.d_E = is_plane_strain ? 5. * M_PI * std::pow(h, 3) * c / 48.
929 : M_PI * std::pow(h, 3) * c / 9.;
930 data.d_K = data.toK(data.d_E, data.d_nu);
931 data.d_Gc = c * d_s0 * d_s0 * std::pow(h, 4) / 4.;
932 } else if (dim == 3) {
933 data.d_K = M_PI * std::pow(h, 4) * c / 18.;
934 data.d_E = data.toE(data.d_K, data.d_nu);
935 data.d_Gc = M_PI * c * d_s0 * d_s0 * std::pow(h, 5) / 10.;
936 }
937 data.d_G = data.toGE(data.d_E, data.d_nu);
938 data.d_lambda = data.toLambdaE(data.d_E, data.d_nu);
939 data.d_mu = data.d_G;
940 data.d_KIc = data.toKIc(data.d_Gc, data.d_nu, data.d_E);
941 return data;
942 };
943
951 std::string printStr(int nt, int lvl) const override {
952
953 auto tabS = util::io::getTabS(nt);
954 std::ostringstream oss;
955 oss << tabS << "------- particle::PmbMaterial --------" << std::endl
956 << std::endl;
957 oss << tabS << "State active = " << 0 << std::endl;
958 oss << tabS << "Horizon = " << d_horizon << std::endl;
959 oss << tabS << "Influence fn address = " << influence_fn.get() << std::endl;
960 oss << tabS << "Influence fn info: " << std::endl;
961 oss << influence_fn->printStr(nt + 1, lvl);
962 oss << tabS << "Peridynamic parameters: " << std::endl;
963 oss << tabS << " c = " << d_c << std::endl;
964 oss << tabS << " s0 = " << d_s0 << std::endl;
965 oss << tabS << std::endl;
966
967 return oss.str();
968 };
969
976 void print(int nt, int lvl) const override {
977 std::cout << printStr(nt, lvl);
978 };
979
981 void print() const override { print(0, 0); };
982
983private:
990 void computeParameters(inp::MaterialDeck &deck, const size_t &dim) {
991 //
992 // Need following elastic and fracture properties
993 // 1. E or K
994 // 2. Gc or KIc
995 // Bond-based Poisson ratio is locked by dimension / plane-strain flag
996 // (Silling & Askari 2005; Madenci & Oterkus 2014; Ha & Bobaru 2010).
997 //
998 if (util::isLess(deck.d_matData.d_E, 0.) &&
999 util::isLess(deck.d_matData.d_K, 0.)) {
1000 throw std::runtime_error(
1002 << "Error: Require either Young's modulus E or Bulk modulus K"
1003 " to compute the PMB bond-based peridynamic parameters.\n");
1004 }
1005 if (util::isGreater(deck.d_matData.d_E, 0.) &&
1006 util::isGreater(deck.d_matData.d_K, 0.)) {
1007 std::cout << "Warning: Both Young's modulus E and Bulk modulus K are "
1008 "provided.\n";
1009 std::cout << "Warning: Selecting Young's modulus E for PMB calibration.\n";
1010 }
1011
1012 if (util::isLess(deck.d_matData.d_Gc, 0.) &&
1013 util::isLess(deck.d_matData.d_KIc, 0.)) {
1014 throw std::runtime_error(
1016 << "Error: Require either critical energy release rate Gc or "
1017 "critical stress intensity factor KIc to compute the PMB "
1018 "bond-based peridynamic parameters.\n");
1019 } else if (util::isGreater(deck.d_matData.d_Gc, 0.) &&
1020 util::isGreater(deck.d_matData.d_KIc, 0.)) {
1021 std::cout << "Warning: Both Gc and KIc provided; selecting Gc.\n";
1022 }
1023
1024 // Bond-based PMB fixes nu: 1/4 in 3D and plane strain, 1/3 in plane
1025 // stress. E is matched.
1026 const double nu_pmb = (dim == 2 && !is_plane_strain) ? 1. / 3. : 0.25;
1027 if (util::isGreater(deck.d_matData.d_nu, 0.) &&
1028 std::abs(deck.d_matData.d_nu - nu_pmb) > 1.0e-12)
1029 std::cout << "Warning: PMB bond-based model fixes nu = " << nu_pmb
1030 << "; ignoring nu = " << deck.d_matData.d_nu << ".\n";
1031 deck.d_matData.d_nu = nu_pmb;
1032
1033 // Prefer E; else recover E from K with the fixed nu.
1034 if (deck.d_matData.d_E < 0. && deck.d_matData.d_K > 0.)
1035 deck.d_matData.d_E =
1036 deck.d_matData.toE(deck.d_matData.d_K, deck.d_matData.d_nu);
1037 if (deck.d_matData.d_E > 0.)
1038 deck.d_matData.d_K =
1039 deck.d_matData.toK(deck.d_matData.d_E, deck.d_matData.d_nu);
1040
1041 if (deck.d_matData.d_Gc > 0.)
1042 deck.d_matData.d_KIc = deck.d_matData.toKIc(
1043 deck.d_matData.d_Gc, deck.d_matData.d_nu, deck.d_matData.d_E);
1044
1045 if (deck.d_matData.d_KIc > 0. && deck.d_matData.d_Gc < 0.)
1046 deck.d_matData.d_Gc = deck.d_matData.toGc(
1047 deck.d_matData.d_KIc, deck.d_matData.d_nu, deck.d_matData.d_E);
1048
1049 deck.d_matData.d_lambda =
1050 deck.d_matData.toLambdaE(deck.d_matData.d_E, deck.d_matData.d_nu);
1051 deck.d_matData.d_G =
1052 deck.d_matData.toGE(deck.d_matData.d_E, deck.d_matData.d_nu);
1053 deck.d_matData.d_mu = deck.d_matData.d_G;
1054
1055 // The closed forms for c and s0 hold for a constant influence function.
1056 if (deck.d_influenceFnType != 0) {
1057 throw std::runtime_error(
1059 << "Error: PMB parameters from E and Gc need a constant influence "
1060 "function. Set Influence_Function Type = 0.\n");
1061 }
1062 d_Jscale = deck.d_influenceFnParams.empty() ? double(dim + 1)
1063 : deck.d_influenceFnParams[0];
1064 if (!(d_Jscale > 0.)) {
1065 throw std::runtime_error(
1067 << "Error: PMB influence scale must be > 0.\n");
1068 }
1069
1070 // c and s0 for J = 1: Silling and Askari 2005 (3D), Ha and Bobaru 2010
1071 // (2D plane stress); plane strain uses the same energy match with
1072 // nu = 1/4. Then J = a0 is absorbed into c.
1073 const double Gc = deck.d_matData.d_Gc;
1074 const double E = deck.d_matData.d_E;
1075 const double h = d_horizon;
1076 if (dim == 2) {
1077 d_c = is_plane_strain ? 48. * E / (5. * M_PI * std::pow(h, 3))
1078 : 9. * E / (M_PI * std::pow(h, 3));
1079 d_s0 = std::sqrt(4. * Gc / (d_c * std::pow(h, 4)));
1080 } else if (dim == 3) {
1081 d_c = 18. * deck.d_matData.d_K / (M_PI * std::pow(h, 4));
1082 d_s0 = std::sqrt(10. * Gc / (M_PI * d_c * std::pow(h, 5)));
1083 } else {
1084 throw std::runtime_error(
1086 << "Error: PMB computeParameters: unsupported dim=" << dim
1087 << "\n");
1088 }
1089 d_c /= d_Jscale;
1090 };
1091
1092private:
1095
1098
1105 double d_c;
1106
1108 double d_s0;
1109
1111 double d_Jscale;
1112
1114};
1115
1120class PdElastic : public Material {
1121
1122public:
1129 PdElastic(inp::MaterialDeck &deck, const size_t &dim, const double &horizon)
1130 : Material("PDElasticBond"), d_horizon(horizon),
1131 d_density(deck.d_density), d_c(0.) {
1132
1133 // set global fields
1134 if (dimension != dim)
1135 dimension = dim;
1136
1137 if (is_plane_strain != deck.d_isPlaneStrain)
1138 is_plane_strain = deck.d_isPlaneStrain;
1139
1140 // create influence function
1141 if (deck.d_influenceFnType == 0) {
1142 if (influence_fn == nullptr)
1143 influence_fn = std::make_shared<material::ConstInfluenceFn>(
1144 deck.d_influenceFnParams, dim);
1145 }
1146 else if (deck.d_influenceFnType == 1) {
1147 if (influence_fn == nullptr)
1148 influence_fn = std::make_shared<material::LinearInfluenceFn>(
1149 deck.d_influenceFnParams, dim);
1150 }
1151 else if (deck.d_influenceFnType == 2) {
1152 if (influence_fn == nullptr)
1153 influence_fn = std::make_shared<material::GaussianInfluenceFn>(
1154 deck.d_influenceFnParams, dim);
1155 }
1156 else {
1157 throw std::runtime_error(
1159 << "Error: Influence function type = "
1160 << deck.d_influenceFnType
1161 << " is invalid.\n");
1162 }
1163
1164 // check if we need to compute the material parameters
1166 computeParameters(deck, dim);
1167 else
1168 d_c = deck.d_bondPotentialParams[0];
1169 };
1170
1175 bool isStateActive() const override { return false; };
1176
1186 std::pair<double, double> getBondEF(const double &r, const double &s,
1187 bool &fs,
1188 const bool &break_bonds) const override {
1189
1190 return std::make_pair(getInfFn(r) * 0.5 * d_c * s *
1191 s * r,
1192 getInfFn(r) * d_c * s);
1193 };
1194
1205 std::pair<double, double>
1206 getBondEF(const double &r, const double &s, bool &fs, const double
1207 &mx, const double &thetax) const override {
1208
1209 return this->getBondEF(r, s, fs, true);
1210 };
1211
1220 const util::Point &du) const override {
1221 return (dx + du) / (dx + du).length();
1222 };
1223
1230 double getS(const util::Point &dx, const util::Point &du) const override {
1231 return ((dx + du).length() - dx.length()) / dx.length();
1232 };
1233
1240 double getSc(const double &r) const override { return std::numeric_limits<double>::max(); };
1241
1246 double getDensity() const override { return d_density; };
1247
1254 double getInfFn(const double &r) const override {
1255 return getGlobalInfFn(r / d_horizon);
1256 };
1257
1267 double getMoment(const size_t &i) const override {
1268 return getGlobalMoment(i);
1269 };
1270
1276 double getHorizon() const override { return d_horizon; };
1277
1285 inp::MatData computeMaterialProperties(const size_t &dim) const override {
1286
1287 auto data = inp::MatData();
1288
1289 if (dim == 2 && !is_plane_strain)
1290 data.d_nu = 1.0 / 3.0;
1291 else
1292 data.d_nu = 0.25;
1293
1294 const double h = d_horizon;
1295 if (dim == 2 && !is_plane_strain) {
1296 data.d_E = d_c * (M_PI * std::pow(h, 3.0)) / 9.0;
1297 } else if (dim == 2 && is_plane_strain) {
1298 data.d_E = d_c * (5.0 * M_PI * std::pow(h, 3.0)) / 48.0;
1299 } else if (dim == 3) {
1300 data.d_K = d_c * (M_PI * std::pow(h, 4.0)) / 18.0;
1301 data.d_E = data.toE(data.d_K, data.d_nu);
1302 }
1303 if (dim == 2)
1304 data.d_K = data.toK(data.d_E, data.d_nu);
1305 data.d_lambda = data.toLambdaE(data.d_E, data.d_nu);
1306 data.d_mu = data.toGE(data.d_E, data.d_nu);
1307 data.d_G = data.d_mu;
1308
1309 return data;
1310 };
1311
1319 std::string printStr(int nt, int lvl) const override {
1320
1321 auto tabS = util::io::getTabS(nt);
1322 std::ostringstream oss;
1323 oss << tabS << "------- particle::PdElastic --------" << std::endl
1324 << std::endl;
1325 oss << tabS << "State active = " << 0 << std::endl;
1326 oss << tabS << "Horizon = " << d_horizon << std::endl;
1327 oss << tabS << "Influence fn address = " << influence_fn.get() << std::endl;
1328 oss << tabS << "Influence fn info: " << std::endl;
1329 oss << influence_fn->printStr(nt + 1, lvl);
1330 oss << tabS << "Peridynamic parameters: " << std::endl;
1331 oss << tabS << " c = " << d_c << std::endl;
1332 oss << tabS << std::endl;
1333
1334 return oss.str();
1335 };
1336
1343 void print(int nt, int lvl) const override {
1344 std::cout << printStr(nt, lvl);
1345 };
1346
1348 void print() const override { print(0, 0); };
1349
1350private:
1357 void computeParameters(inp::MaterialDeck &deck, const size_t &dim) {
1358 // Elastic-only bond-based micromodulus (same δ powers as PMB).
1359 if (util::isLess(deck.d_matData.d_E, 0.) &&
1360 util::isLess(deck.d_matData.d_K, 0.)) {
1361 throw std::runtime_error(
1363 << "Error: Require either Young's modulus E or Bulk modulus K"
1364 " to compute the PdElastic parameters.\n");
1365 }
1366 if (util::isGreater(deck.d_matData.d_E, 0.) &&
1367 util::isGreater(deck.d_matData.d_K, 0.)) {
1368 std::cout << "Warning: Both E and K provided; selecting E for PdElastic.\n";
1369 }
1370
1371 // Emmrich / Trask micromodulus (J≡1). Scale if ConstInfluence a0≠1.
1372 deck.d_matData.d_nu = 0.25;
1373 if (deck.d_matData.d_E < 0. && deck.d_matData.d_K > 0.)
1374 deck.d_matData.d_E =
1375 deck.d_matData.toE(deck.d_matData.d_K, deck.d_matData.d_nu);
1376 if (deck.d_matData.d_E > 0.)
1377 deck.d_matData.d_K =
1378 deck.d_matData.toK(deck.d_matData.d_E, deck.d_matData.d_nu);
1379 deck.d_matData.d_lambda =
1380 deck.d_matData.toLambdaE(deck.d_matData.d_E, deck.d_matData.d_nu);
1381 deck.d_matData.d_G =
1382 deck.d_matData.toGE(deck.d_matData.d_E, deck.d_matData.d_nu);
1383 deck.d_matData.d_mu = deck.d_matData.d_G;
1384
1385 double J_scale = 1.0;
1386 if (deck.d_influenceFnType == 0)
1387 J_scale = deck.d_influenceFnParams.empty() ? double(dim + 1)
1388 : deck.d_influenceFnParams[0];
1389 else if (deck.d_influenceFnType == 1 || deck.d_influenceFnType == 2)
1390 J_scale = std::max(getMoment(0), 1.0e-30);
1391
1392 const double h = d_horizon;
1393 const double kappa = deck.d_matData.d_K;
1394 if (dim == 2)
1395 d_c = 72.0 * kappa / (5.0 * M_PI * std::pow(h, 3.0));
1396 else if (dim == 3)
1397 d_c = 18.0 * kappa / (M_PI * std::pow(h, 4.0));
1398 else {
1399 throw std::runtime_error(
1401 << "Error: PdElastic computeParameters: unsupported dim=" << dim
1402 << "\n");
1403 }
1404 d_c /= J_scale;
1405 };
1406
1407private:
1410
1413
1420 double d_c;
1421
1423};
1424
1429class PdState : public Material {
1430
1431public:
1438 PdState(inp::MaterialDeck &deck, const size_t &dim, const double &horizon)
1439 : Material("PDState"), d_horizon(horizon), d_density(deck.d_density),
1440 d_K(0.), d_G(0.), d_kappa(0.), d_s0(0.), d_dim(double(dim)),
1441 d_alphaFactor(dim == 2 ? 8. : 15.) {
1442
1443 // set global fields
1444 if (dimension != dim)
1445 dimension = dim;
1446
1447 if (is_plane_strain != deck.d_isPlaneStrain)
1448 is_plane_strain = deck.d_isPlaneStrain;
1449
1450 // create influence function
1451 if (deck.d_influenceFnType == 0) {
1452 if (influence_fn == nullptr)
1453 influence_fn = std::make_shared<material::ConstInfluenceFn>(
1454 deck.d_influenceFnParams, dim);
1455 }
1456 else if (deck.d_influenceFnType == 1) {
1457 if (influence_fn == nullptr)
1458 influence_fn = std::make_shared<material::LinearInfluenceFn>(
1459 deck.d_influenceFnParams, dim);
1460 }
1461 else if (deck.d_influenceFnType == 2) {
1462 if (influence_fn == nullptr)
1463 influence_fn = std::make_shared<material::GaussianInfluenceFn>(
1464 deck.d_influenceFnParams, dim);
1465 }
1466 else {
1467 throw std::runtime_error(
1469 << "Error: Influence function type = "
1470 << deck.d_influenceFnType
1471 << " is invalid.\n");
1472 }
1473
1474 // check if we need to compute the material parameters
1476 computeParameters(deck, dim);
1477 else {
1478 d_K = deck.d_bondPotentialParams[0];
1479 d_G = deck.d_bondPotentialParams[1];
1480 d_s0 = deck.d_bondPotentialParams[2];
1481 d_kappa = getModelBulkModulus(dim, is_plane_strain, d_K, d_G);
1482 }
1483 };
1484
1489 bool isStateActive() const override { return true; };
1490
1500 std::pair<double, double> getBondEF(const double &r, const double &s,
1501 bool &fs,
1502 const bool &break_bonds) const override {
1503
1504 return {0., 0.};
1505 };
1506
1525 std::pair<double, double>
1526 getBondEF(const double &r, const double &s, bool &fs, const double
1527 &mx, const double &thetax) const override {
1528
1529 if (fs)
1530 return {0., 0.};
1531
1532 double J = getInfFn(r);
1533 double change_length = s * r;
1534
1535 double alpha = d_alphaFactor * d_G / mx;
1536 double factor = (d_dim * d_kappa / mx) - alpha / d_dim;
1537 double e_dev = change_length - thetax * r / d_dim;
1538
1539 return {0.5 * alpha * J * e_dev * e_dev,
1540 J * (r * thetax * factor + change_length * alpha)};
1541 };
1542
1549 double getDilatationEnergyDensity(const double &thetax) const override {
1550 return 0.5 * d_kappa * thetax * thetax;
1551 };
1552
1561 const util::Point &du) const override {
1562 return (dx + du) / (dx + du).length();
1563 };
1564
1571 double getS(const util::Point &dx, const util::Point &du) const override {
1572 return ((dx + du).length() - dx.length()) / dx.length();
1573 };
1574
1581 double getSc(const double &r) const override { return d_s0; };
1582
1587 double getDensity() const override { return d_density; };
1588
1595 double getInfFn(const double &r) const override {
1596 return getGlobalInfFn(r / d_horizon);
1597 };
1598
1608 double getMoment(const size_t &i) const override {
1609 return getGlobalMoment(i);
1610 };
1611
1617 double getHorizon() const override { return d_horizon; };
1618
1626 inp::MatData computeMaterialProperties(const size_t &dim) const override {
1627
1628 auto data = inp::MatData();
1629
1630 // we already have G and K
1631 data.d_G = d_G;
1632 data.d_K = d_K;
1633
1634 // get Poisson ratio and Young's modulus
1635 data.d_nu = (3. * d_K - 2. * d_G) / (2. * (3. * d_K + d_G));
1636 data.d_E = data.toE(d_K, data.d_nu);
1637
1638 // get lame parameters
1639 data.d_lambda = data.toLambdaE(data.d_E, data.d_nu);
1640 data.d_mu = d_G;
1641
1642 // get Gc from s0 (inverse of computeParameters)
1643 data.d_Gc = d_s0 * d_s0 * getCriticalStretchDensity(dim);
1644
1645 // KIc
1646 data.d_KIc = data.toKIc(
1647 data.d_Gc, data.d_nu, data.d_E);
1648
1649 return data;
1650 };
1651
1659 std::string printStr(int nt, int lvl) const override {
1660
1661 auto tabS = util::io::getTabS(nt);
1662 std::ostringstream oss;
1663 oss << tabS << "------- particle::PdState --------" << std::endl
1664 << std::endl;
1665 oss << tabS << "State active = " << 1 << std::endl;
1666 oss << tabS << "Horizon = " << d_horizon << std::endl;
1667 oss << tabS << "Influence fn address = " << influence_fn.get() << std::endl;
1668 oss << tabS << "Influence fn info: " << std::endl;
1669 oss << influence_fn->printStr(nt + 1, lvl);
1670 oss << tabS << "Peridynamic parameters: " << std::endl;
1671 oss << tabS << " K = " << d_K << std::endl;
1672 oss << tabS << " G = " << d_G << std::endl;
1673 oss << tabS << " s0 = " << d_s0 << std::endl;
1674 oss << tabS << std::endl;
1675
1676 return oss.str();
1677 };
1678
1685 void print(int nt, int lvl) const override {
1686 std::cout << printStr(nt, lvl);
1687 };
1688
1690 void print() const override { print(0, 0); };
1691
1692private:
1699 void computeParameters(inp::MaterialDeck &deck, const size_t &dim) {
1700 //
1701 // Need following elastic and fracture properties
1702 // 1. E or K
1703 // 2. Poisson ratio or shear modulus
1704 // 3. Gc or KIc
1705 //
1706 bool found_E = false;
1707 bool found_K = false;
1708 bool found_G = false;
1709 bool found_nu = false;
1710 size_t num_props = 0;
1711
1712 found_E = util::isGreater(deck.d_matData.d_E, 0.);
1713 if (found_E)
1714 num_props++;
1715
1716 found_K = util::isGreater(deck.d_matData.d_K, 0.);
1717 if (found_K)
1718 num_props++;
1719
1720 found_G = util::isGreater(deck.d_matData.d_G, 0.);
1721 if (found_G)
1722 num_props++;
1723
1724 found_nu = util::isGreater(deck.d_matData.d_nu, 0.);
1725 if (found_nu)
1726 num_props++;
1727
1728 if (num_props != 2) {
1729 std::ostringstream oss;
1730 oss << "Error: Require two different elastic properties for the "
1731 "PdState material. Pairs supported are (E, K), (E, G), "
1732 "(E, nu), (K, G).\n";
1733 oss << deck.printStr(0, 0) << "\n";
1734 throw std::runtime_error(
1736 << oss.str());
1737 }
1738
1739 if (util::isLess(deck.d_matData.d_Gc, 0.) &&
1740 util::isLess(deck.d_matData.d_KIc, 0.)) {
1741 throw std::runtime_error(
1743 << "Error: Require either critical energy release rate Gc or "
1744 "critical stress intensity factor KIc to compute the RNP "
1745 "bond-based peridynamic parameters.\n");
1746 } else if (util::isGreater(deck.d_matData.d_Gc, 0.) &&
1747 util::isGreater(deck.d_matData.d_KIc, 0.)) {
1748 std::cout << "Warning: Both critical energy release rate Gc and critical "
1749 "stress intensity factor KIc are provided.\n";
1750 std::cout << "Warning: To compute the RNP bond-based peridynamic "
1751 "parameters, we only require one of those.\n";
1752 std::cout << "Warning: Selecting critical energy release rate Gc to "
1753 "compute parameters.\n";
1754 }
1755
1756 // compute nu if not provided
1757 if (!found_nu) {
1758 if (found_E and found_G)
1759 deck.d_matData.d_nu =
1760 (0.5 * deck.d_matData.d_E / deck.d_matData.d_G) - 1.;
1761
1762 if (found_E and found_K)
1763 deck.d_matData.d_nu =
1764 (3. * deck.d_matData.d_K - deck.d_matData.d_E) /
1765 (6. * deck.d_matData.d_K);
1766
1767 if (found_G and found_K)
1768 deck.d_matData.d_nu =
1769 (3. * deck.d_matData.d_K - 2. * deck.d_matData.d_G) /
1770 (2. * (3. * deck.d_matData.d_K + deck.d_matData.d_G));
1771 }
1772 found_nu = true;
1773
1774 // compute E if not provided
1775 if (!found_E) {
1776 if (found_K)
1777 deck.d_matData.d_E =
1778 deck.d_matData.toE(deck.d_matData.d_K, deck.d_matData.d_nu);
1779
1780 if (found_G)
1781 deck.d_matData.d_E =
1782 2. * deck.d_matData.d_G * (1. + deck.d_matData.d_nu);
1783 }
1784 found_E = true;
1785
1786 // compute K if not provided
1787 if (!found_K)
1788 deck.d_matData.d_K =
1789 deck.d_matData.toK(deck.d_matData.d_E, deck.d_matData.d_nu);
1790
1791 found_K = true;
1792
1793
1794 // compute G if not provided
1795 if (!found_G)
1796 deck.d_matData.d_G =
1797 deck.d_matData.toGE(deck.d_matData.d_E, deck.d_matData.d_nu);
1798
1799 found_G = true;
1800
1801 // compute Gc (if not provided) and KIc (if not provided)
1802 if (deck.d_matData.d_Gc > 0.)
1803 deck.d_matData.d_KIc = deck.d_matData.toKIc(
1804 deck.d_matData.d_Gc, deck.d_matData.d_nu, deck.d_matData.d_E);
1805
1806 if (deck.d_matData.d_KIc > 0. && deck.d_matData.d_Gc < 0.)
1807 deck.d_matData.d_Gc = deck.d_matData.toGc(
1808 deck.d_matData.d_KIc, deck.d_matData.d_nu, deck.d_matData.d_E);
1809
1810 // compute lame parameter
1811 deck.d_matData.d_lambda =
1812 deck.d_matData.toLambdaE(deck.d_matData.d_E, deck.d_matData.d_nu);
1813 deck.d_matData.d_mu = deck.d_matData.d_G;
1814
1815 // compute peridynamic parameters
1816 d_K = deck.d_matData.d_K;
1817 d_G = deck.d_matData.d_G;
1818 d_kappa = getModelBulkModulus(dim, is_plane_strain, d_K, d_G);
1819
1820 // The closed form for s0 holds for a constant influence function.
1821 if (deck.d_influenceFnType != 0) {
1822 throw std::runtime_error(
1824 << "Error: PDState critical stretch from Gc needs a constant "
1825 "influence function. Set Influence_Function Type = 0.\n");
1826 }
1827 if (dim != 2 && dim != 3) {
1828 throw std::runtime_error(
1830 << "Error: PdState computeParameters: unsupported dim=" << dim
1831 << "\n");
1832 }
1833 d_s0 = std::sqrt(deck.d_matData.d_Gc / getCriticalStretchDensity(dim));
1834 };
1835
1845 double getCriticalStretchDensity(const size_t &dim) const {
1846 if (dim == 2)
1847 return (6.0 * d_G / M_PI +
1848 16.0 * (d_kappa - 2.0 * d_G) / (9.0 * M_PI * M_PI)) *
1849 d_horizon;
1850 return (3. * d_G + std::pow(3. / 4., 4) * (d_K - 5. * d_G / 3.)) *
1851 d_horizon;
1852 };
1853
1854private:
1857
1860
1867 double d_K;
1868
1870 double d_G;
1871
1873 double d_kappa;
1874
1876 double d_s0;
1877
1879 double d_dim;
1880
1883
1885};
1886
1887} // namespace material
1888
1889#endif // MATERIAL_PD_MATERIAL_H
Collection of methods and database related to peridynamic material.
Definition material.h:98
virtual void print(int nt, int lvl) const
Prints the information about the object.
Definition material.h:279
bool isPlaneStrain() const
Returns plane-strain condition.
Definition material.h:130
virtual double getDilatationEnergyDensity(const double &thetax) const
Returns the dilatational part of the strain energy density.
Definition material.h:207
virtual double getHorizon() const =0
Returns horizon.
Material(std::string name="")
Constructor.
Definition material.h:105
virtual std::pair< double, double > getBondEF(const double &r, const double &s, bool &fs, const double &mx, const double &thetax) const =0
Returns energy and force between bond due to state-based model.
virtual void print() const
Prints the information about the object.
Definition material.h:282
virtual double getMoment(const size_t &i) const =0
Returns the moment of influence function.
virtual ~Material()
Destructor.
Definition material.h:112
virtual double getDensity() const =0
Returns the density of the material.
virtual std::pair< double, double > getBondEF(const double &r, const double &s, bool &fs, const bool &break_bonds) const =0
Returns energy and force between bond due to pairwise interaction.
virtual bool isStateActive() const =0
Returns true if state-based potential is active.
virtual inp::MatData computeMaterialProperties(const size_t &dim) const =0
Computes elastic and fracture material properties and returns the data.
std::string name()
Returns name of the material.
Definition material.h:118
std::string d_name
Name of the material.
Definition material.h:286
virtual util::Point getBondForceDirection(const util::Point &dx, const util::Point &du) const =0
Returns the unit vector along which bond-force acts.
size_t getDimension() const
Returns dimension of the problem.
Definition material.h:124
virtual double getS(const util::Point &dx, const util::Point &du) const =0
Returns the bond strain.
virtual double getInfFn(const double &r) const =0
Returns the value of influence function.
virtual double getBreakSc(const double &r) const
Returns bond strain beyond which the bond is marked broken.
Definition material.h:197
virtual std::string printStr(int nt, int lvl) const
Returns the string containing printable information about the object.
Definition material.h:259
virtual double getSc(const double &r) const =0
Returns critical bond strain.
A class providing methods to compute energy density and force of peridynamic material.
Definition material.h:1120
util::Point getBondForceDirection(const util::Point &dx, const util::Point &du) const override
Returns the unit vector along which bond-force acts.
Definition material.h:1219
std::pair< double, double > getBondEF(const double &r, const double &s, bool &fs, const bool &break_bonds) const override
Returns energy and force between bond due to pairwise interaction.
Definition material.h:1186
double getMoment(const size_t &i) const override
Returns the moment of influence function.
Definition material.h:1267
double getDensity() const override
Returns the density of the material.
Definition material.h:1246
std::string printStr(int nt, int lvl) const override
Returns the string containing printable information about the object.
Definition material.h:1319
double getS(const util::Point &dx, const util::Point &du) const override
Returns the bond strain.
Definition material.h:1230
PdElastic(inp::MaterialDeck &deck, const size_t &dim, const double &horizon)
Constructor.
Definition material.h:1129
inp::MatData computeMaterialProperties(const size_t &dim) const override
Computes elastic and fracture material properties and returns the data.
Definition material.h:1285
double getSc(const double &r) const override
Returns critical bond strain.
Definition material.h:1240
double d_density
Density.
Definition material.h:1412
double getHorizon() const override
Returns horizon.
Definition material.h:1276
bool isStateActive() const override
Returns true if state-based potential is active.
Definition material.h:1175
double getInfFn(const double &r) const override
Returns the value of influence function.
Definition material.h:1254
double d_horizon
Horizon.
Definition material.h:1409
double d_c
Parameter C.
Definition material.h:1420
void print() const override
Prints the information about the object.
Definition material.h:1348
std::pair< double, double > getBondEF(const double &r, const double &s, bool &fs, const double &mx, const double &thetax) const override
Returns energy and force between bond due to state-based model.
Definition material.h:1206
void print(int nt, int lvl) const override
Prints the information about the object.
Definition material.h:1343
void computeParameters(inp::MaterialDeck &deck, const size_t &dim)
Compute material model parameters.
Definition material.h:1357
A class providing methods to compute energy density and force of peridynamic material.
Definition material.h:1429
double getS(const util::Point &dx, const util::Point &du) const override
Returns the bond strain.
Definition material.h:1571
double d_G
Shear modulus.
Definition material.h:1870
double getCriticalStretchDensity(const size_t &dim) const
Returns Gc / s0^2 for the state-based model.
Definition material.h:1845
std::string printStr(int nt, int lvl) const override
Returns the string containing printable information about the object.
Definition material.h:1659
void print(int nt, int lvl) const override
Prints the information about the object.
Definition material.h:1685
double getSc(const double &r) const override
Returns critical bond strain.
Definition material.h:1581
inp::MatData computeMaterialProperties(const size_t &dim) const override
Computes elastic and fracture material properties and returns the data.
Definition material.h:1626
double d_kappa
Bulk modulus used by the model (K in 3D, in-plane in 2D)
Definition material.h:1873
void computeParameters(inp::MaterialDeck &deck, const size_t &dim)
Compute material model parameters.
Definition material.h:1699
double d_horizon
Horizon.
Definition material.h:1856
void print() const override
Prints the information about the object.
Definition material.h:1690
double getDensity() const override
Returns the density of the material.
Definition material.h:1587
double getHorizon() const override
Returns horizon.
Definition material.h:1617
util::Point getBondForceDirection(const util::Point &dx, const util::Point &du) const override
Returns the unit vector along which bond-force acts.
Definition material.h:1560
double getMoment(const size_t &i) const override
Returns the moment of influence function.
Definition material.h:1608
double d_dim
Dimension, as a double.
Definition material.h:1879
std::pair< double, double > getBondEF(const double &r, const double &s, bool &fs, const double &mx, const double &thetax) const override
Returns energy and force between bond due to state-based model.
Definition material.h:1526
double getDilatationEnergyDensity(const double &thetax) const override
Returns the dilatational part of the strain energy density.
Definition material.h:1549
PdState(inp::MaterialDeck &deck, const size_t &dim, const double &horizon)
Constructor.
Definition material.h:1438
double getInfFn(const double &r) const override
Returns the value of influence function.
Definition material.h:1595
double d_alphaFactor
d(d+2): 15 in 3D, 8 in 2D
Definition material.h:1882
double d_K
Bulk modulus.
Definition material.h:1867
std::pair< double, double > getBondEF(const double &r, const double &s, bool &fs, const bool &break_bonds) const override
Returns energy and force between bond due to pairwise interaction.
Definition material.h:1500
double d_density
Density.
Definition material.h:1859
bool isStateActive() const override
Returns true if state-based potential is active.
Definition material.h:1489
double d_s0
Critical stretch.
Definition material.h:1876
A class providing methods to compute energy density and force of peridynamic material.
Definition material.h:731
double d_density
Density.
Definition material.h:1097
void computeParameters(inp::MaterialDeck &deck, const size_t &dim)
Compute material model parameters.
Definition material.h:990
double getMoment(const size_t &i) const override
Returns the moment of influence function.
Definition material.h:901
void print(int nt, int lvl) const override
Prints the information about the object.
Definition material.h:976
double d_s0
Critical stretch.
Definition material.h:1108
double d_horizon
Horizon.
Definition material.h:1094
double getDensity() const override
Returns the density of the material.
Definition material.h:880
double getS(const util::Point &dx, const util::Point &du) const override
Returns the bond strain.
Definition material.h:864
double getInfFn(const double &r) const override
Returns the value of influence function.
Definition material.h:888
double d_Jscale
Constant influence value a0 that c was divided by.
Definition material.h:1111
bool isStateActive() const override
Returns true if state-based potential is active.
Definition material.h:788
double getHorizon() const override
Returns horizon.
Definition material.h:910
PmbMaterial(inp::MaterialDeck &deck, const size_t &dim, const double &horizon)
Constructor.
Definition material.h:740
void print() const override
Prints the information about the object.
Definition material.h:981
util::Point getBondForceDirection(const util::Point &dx, const util::Point &du) const override
Returns the unit vector along which bond-force acts.
Definition material.h:853
double d_c
Micromodulus c (divided by the constant influence value)
Definition material.h:1105
inp::MatData computeMaterialProperties(const size_t &dim) const override
Computes elastic and fracture material properties and returns the data.
Definition material.h:919
std::pair< double, double > getBondEF(const double &r, const double &s, bool &fs, const double &mx, const double &thetax) const override
Returns energy and force between bond due to state-based model.
Definition material.h:840
std::pair< double, double > getBondEF(const double &r, const double &s, bool &fs, const bool &break_bonds) const override
Returns energy and force between bond due to pairwise interaction.
Definition material.h:804
double getSc(const double &r) const override
Returns critical bond strain.
Definition material.h:874
std::string printStr(int nt, int lvl) const override
Returns the string containing printable information about the object.
Definition material.h:951
A class providing methods to compute energy density and force of peridynamic material.
Definition material.h:293
double getHorizon() const override
Returns horizon.
Definition material.h:503
double getInfFn(const double &r) const override
Returns the value of influence function.
Definition material.h:482
double getBreakSc(const double &r) const override
Returns bond strain beyond which the bond is marked broken.
Definition material.h:464
void print(int nt, int lvl) const override
Prints the information about the object.
Definition material.h:578
util::Point getBondForceDirection(const util::Point &dx, const util::Point &du) const override
Returns the unit vector along which bond-force acts.
Definition material.h:430
std::pair< double, double > getBondEF(const double &r, const double &s, bool &fs, const bool &break_bonds) const override
Returns energy and force between bond due to pairwise interaction.
Definition material.h:387
double d_invFactor
Inverse of factor = .
Definition material.h:713
double getDensity() const override
Returns the density of the material.
Definition material.h:474
RnpMaterial(inp::MaterialDeck &deck, const size_t &dim, const double &horizon)
Constructor.
Definition material.h:302
std::pair< double, double > getBondEF(const double &r, const double &s, bool &fs, const double &mx, const double &thetax) const override
Returns energy and force between bond due to state-based model.
Definition material.h:417
double getS(const util::Point &dx, const util::Point &du) const override
Returns the bond strain.
Definition material.h:441
void computeParameters(inp::MaterialDeck &deck, const size_t &dim)
Compute material model parameters.
Definition material.h:592
void print() const override
Prints the information about the object.
Definition material.h:583
std::string printStr(int nt, int lvl) const override
Returns the string containing printable information about the object.
Definition material.h:549
double getMoment(const size_t &i) const override
Returns the moment of influence function.
Definition material.h:495
bool d_irrevBondBreak
Flag which indicates if the breaking of bond is irreversible.
Definition material.h:724
double d_rbar
Inflection point of nonlinear function = .
Definition material.h:710
bool isStateActive() const override
Returns true if state-based potential is active.
Definition material.h:357
double d_factorSc
Factor to multiply to critical strain to check if bond is fractured.
Definition material.h:721
inp::MatData computeMaterialProperties(const size_t &dim) const override
Computes elastic and fracture material properties and returns the data.
Definition material.h:512
double d_density
Density.
Definition material.h:694
double d_beta
Parameter .
Definition material.h:705
double getSc(const double &r) const override
Returns critical bond strain.
Definition material.h:451
double d_C
Parameter C.
Definition material.h:702
double d_horizon
Horizon.
Definition material.h:691
Collects a message with stream syntax for use in an exception.
Definition io.h:52
std::string str() const
The message built so far.
Definition io.h:67
bool is_plane_strain
Is plane-stress condition active.
Definition material.h:31
double getGlobalInfFn(const double &r)
Returns the value of influence function.
Definition material.h:42
double getGlobalMoment(const size_t &i)
Returns the moment of influence function.
Definition material.h:55
size_t dimension
Dimension of the domain.
Definition material.h:28
std::shared_ptr< material::BaseInfluenceFn > influence_fn
Store pointer to influence function globally.
Definition material.h:34
double getModelBulkModulus(const size_t &dim, const bool &plane_strain, const double &K, const double &G)
Returns the bulk modulus the model works with, from table K and G.
Definition material.h:70
Definition contact.h:20
std::string getTabS(int nt)
Returns tab spaces of a given size.
Definition io.h:82
bool isGreater(const double &a, const double &b)
Returns true if a > b.
Definition function.cpp:17
bool isLess(const double &a, const double &b)
Returns true if a < b.
Definition function.cpp:22
Structure for elastic properties and fracture properties.
double toGc(double KIc, double nu, double E)
Compute critical energy release rate Gc from critical stress-intensity factor KIc,...
double toLambdaE(double E, double nu)
Compute Lame first parameter lambda from Young's modulus E and Poisson's ratio nu.
double d_mu
Lame second parameter.
double toKIc(double Gc, double nu, double E)
Compute critical stress-intensity factor KIc from critical energy release rate Gc,...
double d_KIc
Critical stress intensity factor.
double toK(double E, double nu)
Compute Bulk modulus K from Young's modulus K and Poisson's ratio nu.
double d_K
Bulk modulus.
double d_lambda
Lame first parameter.
double toGE(double E, double nu)
Compute shear modulus from Young's modulus E and Poisson's ratio nu.
double d_nu
Poisson's ratio.
double d_G
Shear modulus or Lame second parameter.
double d_E
Young's elastic modulus.
double d_Gc
Critical energy release rate.
double toE(double K, double nu)
Compute Young's modulus E from Bulk modulus K and Poisson's ratio nu.
Structure to read and store material related data.
bool d_isPlaneStrain
Indicates if the 2-d simulation is of plane-strain type (thick material) or plane-stress type (thin m...
size_t d_influenceFnType
Type of influence function.
std::vector< double > d_bondPotentialParams
List of parameters for pairwise potential.
bool d_computeParamsFromElastic
Compute Peridynamic material properties from elastic properties.
inp::MatData d_matData
List of elastic and fracture properties.
std::vector< double > d_influenceFnParams
List of parameters for influence function.
std::string printStr(int nt=0, int lvl=0) const
Returns the string containing printable information about the object.
A structure to represent 3d vectors.
Definition point.h:30
double dot(const Point &b) const
Computes the dot product of this vector with another point.
Definition point.h:138
double length() const
Computes the Euclidean length of the vector.
Definition point.h:124