b2api
B2000++ API Reference Manual, VERSION 4.6
 
Loading...
Searching...
No Matches
b2composite_consistent_damage_model_mcmd_2006.H
1//------------------------------------------------------------------------
2// b2composite_consistent_damage_model_mcmd_2006.H --
3//
4//
5// written by Mathias Doreille
6//
7// Copyright (c) 2006-2012,2016
8// SMR Engineering & Development SA
9// 2502 Bienne, Switzerland
10//
11// All Rights Reserved. Proprietary source code. The contents of
12// this file may not be disclosed to third parties, copied or
13// duplicated in any form, in whole or in part, without the prior
14// written permission of SMR.
15//------------------------------------------------------------------------
16
17#ifndef __B2COMPOSITE_CONSISTENT_DAMAGE_MODEL_MCMD_2006_H__
18#define __B2COMPOSITE_CONSISTENT_DAMAGE_MODEL_MCMD_2006_H__
19
20#include <cmath>
21#include <cstdlib>
22#include <iostream>
23#include <memory>
24
25#include "utils/b2exception.H"
26#include "utils/b2type.H"
27
28namespace b2000 {
29// Implement the model described in the following NASA Technical
30// Memorandum:
31//
32// Maimí P., Camanho P.P., Mayugo J.A., Dávila C.G., 2006.
33// A thermodynamically consistent damage model for advanced composites.
34// NASA/TM-2006-214282
35//
36// Available at:
37// http://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/20060008658_2006009390.pdf
38//
39// G : G12, G13, G23
40// X : XT, XC, YT, YC, SL
41// Gf : G1+, G1-, G2+, G2-, G6
42// r : r1+, r1-, r2+, r2- ; must be set at 1 (no damage) at begening
43//
44// The viscous regularisation was applied to all the damages
45// and not only to the longitudinal direction has in the Memorandum.
46//
47class CompositeConsistentDamageModelMCMD2006 {
48public:
49 CompositeConsistentDamageModelMCMD2006() : damage_data(nullptr) {}
50
51 ~CompositeConsistentDamageModelMCMD2006() { delete damage_data; }
52
53 void get_stress(
54 const double E[2], const double P, const double G[3], const double X[5],
55 const double Gf[5], const double area, const double b, const double time,
56 const double delta_time, const double viscosity, const double strain[6],
57 const EquilibriumSolution equilibrium_solution, double stress[6],
58 double d_stress_d_strain[21], int& elasticity_domain);
59
60 const double* get_damages() const {
61 if (damage_data) {
62 return damage_data->r;
63 } else {
64 static const double undamage_r[4] = {1.0, 1.0, 1.0, 1.0};
65 return undamage_r;
66 }
67 }
68
69 const double* get_A() const {
70 if (damage_data) {
71 return damage_data->A;
72 } else {
73 static const double undamage_A[5] = {0.0, 0.0, 0.0, 0.0, 0.0};
74 return undamage_A;
75 }
76 }
77
78private:
79 struct DamageData {
80 DamageData() {
81 std::fill_n(r, 4, 1.0);
82 std::fill_n(A, 5, -1.0);
83 std::fill_n(warnings, 5, false);
84 }
85 double r[4];
86 double A[5];
87 bool warnings[5];
88 };
89 DamageData* damage_data;
90
91 template <typename T>
92 static double simpson_integration(double a, double b, int n, const T& f) {
93 n *= 2;
94 double r = (f(a) + f(b)) / 2;
95 const double h = (b - a) / n;
96 a += h;
97 for (int i = 1; i != n; ++i, a += h) { r += (1 + i % 2) * f(a); }
98 return 2 * r * h / 3;
99 }
100
101 template <typename D_M>
102 class G_M {
103 public:
104 G_M(const D_M& d_M_, double E, double P, double e_stress)
105 : d_M(d_M_), P2(P * P), s_E(e_stress * e_stress / (2 * E)), A(0) {}
106 double operator()(double r) const {
107 double tmp = (1 - P2) / (1 - (1 - d_M.value(r, A)) * P2);
108 return tmp * tmp * s_E * d_M.d_value_d_r(r, A);
109 }
110 double value(double A_) {
111 A = A_;
112 const double ln_inv_K = std::log(1 / 20.0);
113 const double s = -1 / A * ln_inv_K;
114 return simpson_integration(1, 1 + s, 100, *this);
115 }
116
117 private:
118 const D_M& d_M;
119 double P2;
120 double s_E;
121 double A;
122 };
123
124 // Method that compute the adjustment parameter by secant method
125 template <typename D_M>
126 static double compute_adjustment_parameter(
127 double E, double X, double Gf, double characteristic_length, G_M<D_M>& g_M, double tol) {
128 X *= X;
129 double lA_0;
130 double lA_1;
131 double lg_0;
132 double lg_1;
133 Gf = Gf / characteristic_length;
134 {
135 double A_1 = (2 * characteristic_length * X) / (2 * E * Gf - characteristic_length * X);
136 if (A_1 <= 0) {
137 Exception() << "The element size are too big for this material" << THROW;
138 }
139 double g_1 = g_M.value(A_1);
140 double A_0 = 0.5 * A_1;
141 double g_0 = g_M.value(A_0);
142
143 for (int nbiter = 0; nbiter != 50 && g_1 > Gf; ++nbiter) {
144 A_1 *= 10;
145 g_1 = std::max(g_M.value(A_1), 1e-200);
146 }
147 lA_1 = std::log(A_1);
148 lg_1 = std::log(g_1);
149
150 for (int nbiter = 0; nbiter != 50 && g_0 < Gf; ++nbiter) {
151 A_0 *= 0.1;
152 g_0 = g_M.value(A_0);
153 }
154 lA_0 = std::log(A_0);
155 lg_0 = std::log(g_0);
156 }
157 const double lGc = std::log(Gf);
158 for (int nbiter = 0; nbiter != 20; ++nbiter) {
159 double lA_2 = lA_1 - (lg_1 - lGc) * (lA_1 - lA_0) / (lg_1 - lg_0);
160 lg_0 = lg_1;
161 lA_2 = std::min(lA_2, 200.0);
162 double A = std::exp(lA_2);
163 double g_1;
164 for (int nbiter1 = 0; nbiter1 != 10; ++nbiter1) {
165 g_1 = g_M.value(A);
166 if (g_1 == 0) {
167 lA_2 /= 2;
168 A = std::exp(lA_2);
169 } else {
170 break;
171 }
172 }
173 if (g_1 != g_1) { Exception() << THROW; }
174 if (std::abs(g_1 - Gf) <= tol) { return A; }
175 lg_1 = std::log(g_1);
176 if (std::abs(lg_1 - lg_0) <= tol) { return A; }
177 lA_0 = lA_1;
178 lA_1 = lA_2;
179 }
180 Exception() << THROW;
181 return 0;
182 }
183
184 class D1minus {
185 public:
186 D1minus(const double Apm_, const double A1plus, const double rplus)
187 : Apm(Apm_), f(1 - Apm + Apm / rplus * std::exp(A1plus * (1 - rplus))) {}
188 double value(const double r, const double A) const {
189 return 1 - std::exp(A * (1 - r)) * f / r;
190 }
191 double d_value_d_r(const double r, const double A) const {
192 return f * std::exp(A * (1 - r)) * (1 + r * A) / (r * r);
193 }
194
195 private:
196 const double Apm;
197 const double f;
198 };
199
200 class D2plus {
201 public:
202 D2plus(const double g_) : g(g_) {}
203 double value(const double r, const double A) const {
204 const double f2plus = (g - 1 + std::sqrt((1 - g) * (1 - g) + 4 * g * r * r)) / (2 * g);
205 return 1 - std::exp(A * (1 - f2plus)) / f2plus;
206 }
207 double d_value_d_r(const double r, const double A) const {
208 const double s = std::sqrt((1 - g) * (1 - g) + 4 * g * r * r);
209 return 4 * (g * r * std::exp(A * (1 - s)) * (g * (2 + A) - A * (1 - s)))
210 / (s * (g - 1 + s));
211 }
212
213 private:
214 double g;
215 };
216
217 class D2minus {
218 public:
219 double value(const double r, const double A) const { return 1 - std::exp(A * (1 - r)) / r; }
220 double d_value_d_r(const double r, const double A) const {
221 return std::exp(A * (1 - r)) * (1 / (r * r) + A);
222 }
223 };
224};
225} // namespace b2000
226
227#endif
csda< T > exp(const csda< T > &a)
Natural exponential of a csda number.
Definition b2csda.H:360
#define THROW
Definition b2exception.H:198
Contains the base classes for implementing Finite Elements.
Definition b2boundary_condition.H:32