/trunk/SIFEL/GEFEL/matrix.cpp |
---|
3382,9 → 3382,9 |
if (j<1) continue; |
else{ |
j--; |
#ifdef INC_OPENMP |
#pragma omp atomic update |
#endif |
//#ifdef INC_OPENMP |
//#pragma omp atomic update |
//#endif |
gv[j]+=lv[i]; |
} |
} |
/trunk/SIFEL/MEFEL/SRC/Makefile |
---|
37,7 → 37,7 |
SRCS += cebfip78.cpp cebfipcontactmat.cpp chen.cpp consol.cpp contactmat.cpp cpsolver.cpp creep.cpp creep_b3.cpp creep_dpl.cpp |
SRCS += creepb.cpp creepdam.cpp creep_effym.cpp creep_rspec.cpp crsec2dbar.cpp crsec2dbeam.cpp |
SRCS += crsec3d.cpp crsec3dbeam.cpp crseclayer.cpp crsecnod.cpp crsecplstr.cpp cusatismaterial.cpp damplast.cpp damplastifacemat.cpp dkq.cpp dkt.cpp dloadcase.cpp |
SRCS += dloadn.cpp dloadel.cpp dloadpd.cpp drprag.cpp doubdp.cpp drprag2.cpp dst.cpp edgem.cpp edsolver.cpp effstress.cpp eigvalsol.cpp elastgmat2d.cpp elastgmat3d.cpp |
SRCS += dloadn.cpp dloadel.cpp dloadpd.cpp drprag.cpp doubdp.cpp drprag2.cpp dsm.cpp dst.cpp edgem.cpp edsolver.cpp effstress.cpp eigvalsol.cpp elastgmat2d.cpp elastgmat3d.cpp |
SRCS += elastisomat.cpp elastisopdmat.cpp elastortomat.cpp elasttime.cpp element.cpp elemparticle.cpp elemswitch.cpp endnodem.cpp epsolver.cpp fdsolver.cpp flsubdom.cpp fixortodam.cpp |
SRCS += generalmod.cpp |
SRCS += geoelast.cpp glasgmech.cpp glasgowdam.cpp global.cpp globmat.cpp |
/trunk/SIFEL/MEFEL/SRC/alias.h |
---|
150,7 → 150,7 |
// aliases for material models |
enum mattype {elisomat=1,elgmat3d=2,elortomat=3,elgmat2d=4, homomatm=9, |
simplas1d=10,jflow=11,mohrcoulparab=22,mohrcoul=24, |
boermaterial=25,druckerprager=26,doubledrprager=27,druckerprager2=28,modcamclaymat=30, modcamclaycoupmat=31,bbmcoupmat=33, |
boermaterial=25,druckerprager=26,doubledrprager=27,druckerprager2=28,modcamclaymat=30, modcamclaycoupmat=31,bbmcoupmat=33,doublestructuremat=34, |
shefpl=40,chenplast=42, hissplasmat=45, |
microplaneM4=50,microsimp=51,microfibro=52, |
simvisplas=70,simvisc=71,isovisc=72,lemaitr=75, |
170,7 → 170,7 |
const enumstr mattypestr[] = {{"elisomat",1}, {"elgmat3d",2}, {"elortomat",3}, {"elgmat2d",4},{"homomatm",9},{"simplas1d",10}, |
{"jflow",11}, {"mohrcoulparab",22}, |
{"mohrcoul",24}, {"boermaterial",25}, {"druckerprager",26}, {"doubledrprager",27}, {"druckerprager2",28}, |
{"modcamclaymat",30}, {"modcamclaycoupmat",31}, {"bbmcoupmat",33}, {"shefpl",40}, {"chenplast",42}, {"hissplasmat",45}, |
{"modcamclaymat",30}, {"modcamclaycoupmat",31}, {"bbmcoupmat",33}, {"doublestructuremat",34}, {"shefpl",40}, {"chenplast",42}, {"hissplasmat",45}, |
{"microplaneM4",50}, {"microsimp",51}, {"microfibro",52}, |
{"simvisc",71}, {"isovisc",72}, {"lemaitr",75}, |
{"layerplate",80}, |
/trunk/SIFEL/MEFEL/SRC/bbm.cpp |
---|
1,6 → 1,7 |
#include <math.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include "bbm.h" |
#include "global.h" |
#include "probdesc.h" |
7,12 → 8,14 |
#include "mechmat.h" |
#include "vecttens.h" |
#include "intpoints.h" |
#include "matrix.h" |
#include "vector.h" |
#include "tensor.h" |
#include "elastisomat.h" |
#include "mathem.h" |
#include "nonlinman.h" |
/** |
This constructor inializes attributes to zero values. |
*/ |
24,6 → 27,15 |
c1_tilde = 0.0; |
c2 = 0.0; |
ks = 0.0; |
//pr_suc_f = no; |
//pr_tempr_f = no; |
kappa_s0 = 0.0; |
aks1 = 0.0; |
aks2 = 0.0; |
a0 = 0.0; |
a2 = 0.0; |
} |
49,6 → 61,21 |
{ |
xfscanf (in, "%k%lf%k%lf%k%lf", "m", &m, "lambda", &lambda, "kappa", &kappa); |
xfscanf (in, "%k%lf%k%lf%k%lf", "c1_tilde", &c1_tilde, "c2", &c2, "ks", &ks); |
//preparation for the total stresses (net stress) concept and the temperature effect: |
//xfscanf (in, "%k%lf", "kappa_s0", &kappa_s0); |
//xfscanf (in, "%k%lf%k%lf", "aks1", &aks1, "aks2", &aks2); |
//xfscanf (in, "%k%lf%k%lf", "a0", &a0, "a2", &a2); |
//xfscanf(in, "%k%m", "presc_suction", &answertype_kwdset, &pr_suc_f); |
//if (pr_suc_fl == yes) |
//suc_fn.read(in); |
//xfscanf(in, "%k%m", "presc_tempr", &answertype_kwdset, &pr_tempr_f); |
//if (pr_tempr_fl == yes) |
//tempr_fn.read(in); |
sra.read (in); |
} |
57,63 → 84,121 |
with respect of consistency parameter gamma. |
@param ipp - integration point number |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
12/06/2012 TKo |
*/ |
void bbmmat::initval(long ipp, long ido) |
void bbmmat::initval(long ipp, long im, long ido) |
{ |
double v_ini, i1s, v_pc0, v_lambda1; |
double v_kappa1, p1, pc_0; |
double v_ini, v_pc0, v_lambda1; |
double i1s, j2s, s; |
double v_kappa1, p1, bar_pc_0, pc_0; |
long i, ncompstr = Mm->ip[ipp].ncompstr; |
vector epse(ASTCKVEC(ncompstr)), sig(ASTCKVEC(ncompstr)),sigt(ASTCKVEC(6)); |
matrix d(ASTCKMAT(ncompstr, ncompstr)); |
vector sig(ASTCKVEC(ncompstr)),sigt(ASTCKVEC(6)), q(ASTCKVEC(2)); |
double err=sra.give_err (); |
// variables used for the calculation of initial value of preconsolidation pressure for the fully saturated state |
double a, b, fs, ksi, sr, qq, p_atm = 101325.0; |
if (Mm->ip[ipp].eqother[ido+ncompstr+1] == 0.0) // actual value of p_c was not set |
{ |
// initial value of specific volume under small pressure p_1 |
v_kappa1 = Mm->ic[ipp][0]; |
// initial value of specific volume under small pressure p_1 on the normal consolidation line (v_lambda1 = 1+N) |
v_lambda1 = Mm->ic[ipp][0]; |
// initial reference presure |
p1 = Mm->ic[ipp][1]; |
// initial effective preconsolidation pressure |
pc_0 = Mm->ic[ipp][2]; |
p1 = Mm->ic[ipp][1]; |
// initial effective preconsolidation pressure \bar{p}_{c0}} |
bar_pc_0 = Mm->ic[ipp][2]; |
// initial value of elastic strain |
for (i=0; i<ncompstr; i++) |
epse[i] = Mm->ip[ipp].strain[i] = Mm->ic[ipp][3+i]; |
// initial effective stresses |
if ((Mp->eigstrains == 4) || (Mp->eigstrains == 5)){ |
for (i=0; i<ncompstr; i++) |
sig(i) = Mm->ip[ipp].stress[i] = Mm->eigstresses[ipp][i]; |
} |
else{ |
print_err("initial effective stresses (eigentsresses) are not defined on element %ld, ip=%ld,\n" |
" cannot determine specific volume for initial stress state", __FILE__, __LINE__, __func__, Mm->elip[ipp]+1, ipp+1); |
abort(); |
} |
// elastic stiffness matrix |
Mm->elmatstiff(d, ipp, ido); |
// initial value of stress |
mxv(d, epse, sig); |
//add initial value of effective stresses |
for (i=0; i<ncompstr; i++) |
Mm->ip[ipp].stress[i] += sig[i]; |
//vector_tensor (sig,sigt,Mm->ip[ipp].ssst,stress); |
give_full_vector (sigt, sig, Mm->ip[ipp].ssst); |
// initial value of mean stress |
i1s = first_invar(sigt)/3.0; |
q(0) = bar_pc_0; |
s = Mm->givenonmechq(suction, ipp); // suction pressure s |
sr = Mm->givenonmechq(saturation_degree, ipp); // degree of saturation S_r |
//limitation of positive suction |
if(s >=0.0) |
s=0.0; |
s = fabs(s); |
q(1) = ks*s; |
// test if the initial state is elastic, if not calculate new value of inital effective preconsolidation pressure pc_0 so the OCR=1 |
if (yieldfunction(sigt, q) > err){ |
j2s = j2_stress_invar (sigt); |
bar_pc_0 = j2s/(m*m*(i1s-q(1))) + i1s; |
} |
// specific volume for initial effective preconsolidation pressure |
v_pc0 = v_kappa1 - kappa*log(pc_0/p1); |
// |
// Calculation of inital value of preconsolidation pressure for the fully saturated state pc_0 |
// |
// suction function: |
// |
// s / p_{atm} |
// f(s) = 1 + ----------------------- |
// 10.7 + 2.4(s / p_{atm}) |
// |
fs = 1.0 + (s/p_atm) / (10.7 + 2.4*(s/p_atm)); |
if (fs < 1.0) |
fs = 1.0; |
// bonding variable: |
// |
// \ksi = f(s) (1 - S_r) |
// |
ksi = (1-sr)*fs; |
// according to Gallipoli |
qq = 1.0 - c1_tilde*(1.0 - exp(c2*ksi)); // e/e_s |
a = (qq - 1.0)/(lambda*qq - kappa)*(v_lambda1 - 1.0); |
b = (lambda - kappa)/(lambda*qq - kappa); |
pc_0 = -pow(-bar_pc_0 /exp(a), 1.0/b); |
// compute initial value of specific volume |
v_pc0 = v_lambda1 - lambda*log(pc_0/p1); |
// actual value of p_c = initial effective preconsolidtaion pressure |
Mm->ip[ipp].other[ido+ncompstr+1] = Mm->ip[ipp].eqother[ido+ncompstr+1] = pc_0; |
// original specific volume before any loading |
Mm->ip[ipp].other[ido+ncompstr+3] = Mm->ip[ipp].eqother[ido+ncompstr+3] = v_lambda1 = v_pc0 + lambda*log(pc_0/p1); |
Mm->ip[ipp].other[ido+ncompstr+1] = Mm->ip[ipp].eqother[ido+ncompstr+1] = bar_pc_0; |
Mm->ip[ipp].other[ido+ncompstr+2] = Mm->ip[ipp].eqother[ido+ncompstr+2] = q(1); |
// initial value of specific volume under small pressure p_1 on the swelling line (v_{\kappa l}) at the fully saturated state |
Mm->ip[ipp].other[ido+ncompstr+3] = Mm->ip[ipp].eqother[ido+ncompstr+3] = v_kappa1 = v_pc0 + kappa*log(pc_0/p1); |
// specific volume for intial stress state |
Mm->ip[ipp].other[ido+ncompstr+4] = Mm->ip[ipp].eqother[ido+ncompstr+4] = v_ini = v_pc0 + kappa*log(pc_0/i1s); |
// intial mean stress |
Mm->ip[ipp].other[ido+ncompstr+5] = Mm->ip[ipp].eqother[ido+ncompstr+5] = i1s; |
// saturation degree |
Mm->ip[ipp].other[ido+ncompstr+9] = Mm->ip[ipp].eqother[ido+ncompstr+9] = Mm->givenonmechq(saturation_degree, ipp); // degree of saturation S_r |
// initial depsv_dt |
Mm->ip[ipp].other[ido+ncompstr+10] = Mm->ip[ipp].eqother[ido+ncompstr+10] = 0.0; |
// porosity n for intial stress state |
Mm->ip[ipp].other[ido+ncompstr+11] = Mm->ip[ipp].eqother[ido+ncompstr+11] = (v_ini-1.0)/v_ini; // v_ini = 1.0 + e_ini |
// suction for intial stress state |
Mm->ip[ipp].other[ido+ncompstr+12] = Mm->ip[ipp].eqother[ido+ncompstr+12] = Mm->givenonmechq(suction, ipp); // suction pressure s |
// suction |
Mm->ip[ipp].other[ido+ncompstr+12] = Mm->ip[ipp].eqother[ido+ncompstr+12] = Mm->givenonmechq(suction, ipp); // suction |
} |
// set inital value of Young's modulus |
long idem = Mm->ip[ipp].gemid(); |
long ncompo = Mm->givencompeqother(ipp, im); |
double e_ini = Mm->give_initial_ym(ipp, idem, ido+ncompo); |
Mm->ip[ipp].other[ido+ncompstr+13] = Mm->ip[ipp].eqother[ido+ncompstr+13] = e_ini; |
// time step scaling factor |
Mm->ip[ipp].other[ido+ncompstr+14] = Mm->ip[ipp].eqother[ido+ncompstr+14] = 1.0; |
// set inital stiffness matrix |
matrix d; |
makerefm(d, Mm->ip[ipp].other+ido+ncompstr+15, ncompstr, ncompstr); |
Mm->elmatstiff(d, ipp, ido); |
copym(d, Mm->ip[ipp].eqother+ido+ncompstr+15); |
check_math_errel(Mm->elip[ipp]); |
check_math_errel(0); |
return; |
} |
121,7 → 206,7 |
/** |
This function computes the value of yield functions. |
@param sig - stress tensor in Voigt notation |
@param sig - full stress tensor in Voigt notation (6 components) |
@param q - %vector of hardening parameter |
@retval The function returns value of yield function for the given stress tensor |
146,9 → 231,9 |
This function computes derivatives of as-th yield function |
with respect of vector sigma. |
@param sig - stress tensor in Voigt notation |
@param sig - stress tensor in Voigt notation (6 components) |
@param q - %vector of the hardening parameter |
@param dfds - %matrix where the resulting derivatives are stored |
@param dfds - %vector where the resulting derivatives are stored (6 components) |
4.1.2002 |
189,9 → 274,10 |
ddfds[0][0] = ddfds[1][1] = ddfds[2][2] = 2.0/(3.0*m*m) + 2.0/9.0; |
ddfds[0][1] = ddfds[0][2] = ddfds[1][0] = ddfds[1][2] = -1.0/(3.0*m*m) + 2.0/9.0; |
ddfds[2][0] = ddfds[2][1] = ddfds[0][1]; |
ddfds[3][3] = 1.0/(m*m); |
ddfds[4][4] = 1.0/(m*m); |
ddfds[5][5] = 1.0/(m*m); |
// doubled shear components due to tensor-> vector transformation |
ddfds[3][3] = 2.0/(m*m); |
ddfds[4][4] = 2.0/(m*m); |
ddfds[5][5] = 2.0/(m*m); |
} |
202,11 → 288,11 |
@param sig - stress tensor |
@param q - %vector of the hardening parameters |
@param dgds - %matrix where the resulting derivatives are stored |
@param ddgds - %matrix where the resulting derivatives are stored |
*/ |
void bbmmat::derpotsigma (vector &sig, vector &q, vector &dgds) |
void bbmmat::derpotsigma (vector &sig, vector &q, vector &ddgds) |
{ |
deryieldfsigma (sig, q, dgds); |
deryieldfsigma (sig, q, ddgds); |
} |
242,17 → 328,17 |
The function computes the second derivatives of yield function |
with respect to hradening parameters. |
@param dfds - %matrix, where the resulting derivatives are stored |
@param ddfdq - %matrix, where the resulting derivatives are stored |
Created by Tomas Koudelka, 09.2012 |
*/ |
void bbmmat::deryieldfdqdq(matrix &dfq) |
void bbmmat::deryieldfdqdq(matrix &ddfdq) |
{ |
dfq[0][0] = 0.0; |
dfq[0][1] = 1.0; |
dfq[1][0] = 1.0; |
dfq[1][1] = 0.0; |
ddfdq[0][0] = 0.0; |
ddfdq[0][1] = 1.0; |
ddfdq[1][0] = 1.0; |
ddfdq[1][1] = 0.0; |
return; |
} |
284,31 → 370,51 |
@param ipp - integration point number |
@param ido - index of internal variables for given material in the ipp other array |
@param sig - stress tensor |
@param sig - full stress tensor |
@param qtr - %vector of hardening variables |
@param epsp - %vector of attained plastic strains |
@param dqdg - %vector where the resulting derivatives are stored in Voigt notation |
Created by Tomas Koudelka, 09.2012 |
*/ |
void bbmmat::der_q_gamma(long ipp, long ido, vector &sig, vector &qtr, vector &dqdg) |
void bbmmat::der_q_gamma(long ipp, long ido, vector &sig, vector &qtr, vector &epsp, vector &dqdg) |
{ |
double v_ini, v_lambda1, i1s; |
double p_atm = 101.3250; |
double v_ini, v_lambda1, v_kappa1, p1, i1s, epsvp; |
double p_atm = 101325.0; |
double s, sr, fs, b, c, c1, ksi; |
long ncompstr = Mm->ip[ipp].ncompstr; |
strastrestate ssst = Mm->ip[ipp].ssst; |
vector epst(ASTCKVEC(6)); |
// mean stress |
i1s = first_invar (sig)/3.0; |
// original specific volume before any loading |
v_lambda1 = Mm->ip[ipp].eqother[ido+ncompstr+3]; |
// initial value of specific volume under small pressure p_1 for the normal consolidation line (v_{\lambda 1} = N) |
v_lambda1 = Mm->ic[ipp][0]; |
// initial reference presure |
p1 = Mm->ic[ipp][1]; |
// initial value of specific volume under small pressure p_1 for the swelling line (v_{\kappa 1}) |
v_kappa1 = Mm->ip[ipp].eqother[ido+ncompstr+3]; |
// specific volume for intial stress state |
v_ini = Mm->ip[ipp].eqother[ido+ncompstr+4]; |
s = Mm->givenonmechq(suction, ipp); // suction pressure s |
//limitation of positive suction |
if(s >=0.0) |
s=0.0; |
s = fabs(s); |
sr = Mm->givenonmechq(saturation_degree, ipp); // degree of saturation S_r |
// actual value of preconsolidation pressure for the fully saturated state |
give_full_vector (epst, epsp, ssst); |
epsvp = first_invar(epst); |
//double pc_new = p1 * exp((v_kappa1 - v_lambda1 + v_ini*epsvp)/(kappa-lambda)); |
// specific volume for the actual preconsolidation pressure: |
// |
// v_{pc} = v_{\lambda1} - \lambda \ln(p_c/p_1) |
// double v_pc = v_lambda1 - lambda * log(pc_new/p1); |
// suction function: |
// |
// s / p_{atm} |
316,6 → 422,8 |
// 10.7 + 2.4(s / p_{atm}) |
// |
fs = 1.0 + (s/p_atm) / (10.7 + 2.4*(s/p_atm)); |
if (fs < 1.0) |
fs = 1.0; |
// bonding variable: |
// |
327,10 → 435,12 |
// c_1 = -------------------- |
// 1 |
// -------------- + 1 |
// v_{\lambda1}-1 |
c1 = c1_tilde/(1.0/(v_lambda1-1.0)+1.0); |
// v_{pc}-1 |
// c1 = c1_tilde/(1.0/(v_pc-1.0)+1.0); // according to Borja |
c1 = c1_tilde; // according to Gallipoli |
// |
// c(\ksi) = 1 - c_1 [1-\exp(c_2 \ksi)] |
// |
346,25 → 456,27 |
// q[0] = \bar{p}_c = -\exp[a(\ksi)] (-p_c)^{b(\ksi)} |
// |
// p_c = p_1 exp[(v_{\kappa} - v_{\lambda_1})/(\kappa - \lambda)] |
// p_c = p_1 exp[(v_{\kappa_1} - v_{\lambda_1} + eps_{vp} v_{ini})/(\kappa - \lambda)] |
// |
// v_{\kappa} = v_{ini} (1+\eps_v) + \kappa \ln(p/p_1) => depends on p => depends on gamma |
// p_1 = const |
// p_{c0} = const |
// \sigma_{m0} = const |
// v_{\kappa_1} = const |
// v_{p_{c0}} = v_{\kappa_1} - \kappa \ln(p_{c0}/p_1) = const |
// v_{ini} = v_{p_{c0}} + \kappa \ln(p_{c0}/\sigma_{m0}) = const |
// v_{\lambda_1} = v_{p_{c0}} - \lambda \ln(p_{c0}/p_1) = const |
// |
// v_{ini} = v_{p_{c0}} + \kappa \ln(p_{c0}/p_{ini}) = const |
// v_{\lambda_1} = v_{p_{c0}} + \lambda \ln(p_{c0}/p_1) = const |
// v_{p_{c0}} = v_{\kappa_1} - \kappa \ln(p_{c0}/p_1) = const |
// |
// d \bar{p}_c d p_c |
// ----------- = \exp[a(\ksi)] b(\ksi)(-p_c)^{b(\ksi)-1} ----------, |
// d \gamma d \gamma |
// d \bar{p}_c d p_c (-p_c)^{b(\ksi)} d p_c |
// ----------- = -\exp[a(\ksi)] b(\ksi)(-p_c)^{b(\ksi)-1} ---------- = -\exp[a(\ksi)] b(\ksi) ---------------- ---------- , |
// d \gamma d \gamma p_c d \gamma |
// |
// d p_c v_ini |
// ---------- = p_c ----------------- (2p - \bar{p}_c - p_s), |
// d \gamma \kappa - \lambda |
// |
// d \bar{p}_c b(\ksi) v_ini |
// ----------- = -\bar{p}_c ---------------- (2p - \bar{p}_c - p_s) |
// d \gamma \kappa - \lambda |
// d \bar{p}_c b(\ksi) v_ini |
// ----------- = -\bar{p}_c ---------------- (2p - \bar{p}_c - p_s) |
// d \gamma \kappa - \lambda |
// |
// |
dqdg[0] = -qtr[0] * (b*v_ini)/(kappa-lambda) * (2.0*i1s-qtr[0]-qtr[1]); |
384,6 → 496,273 |
/** |
The function computes derivatives of hardening paramters |
with respect of consistency parameter gamma. |
@param ipp - integration point number |
@param ido - index of internal variables for given material in the ipp other array |
@param sig - full stress tensor |
@param qtr - %vector of hardening variables |
@param epsp - %vector of attained plastic strains |
@param dqdgds - %matrix where the resulting derivatives are stored in Voigt notation, |
its dimensions must be qtr.n x 6 |
Created by Tomas Koudelka, 05.2022 |
*/ |
void bbmmat::dqpardgammadsigma(long ipp, long ido, vector &sig, vector &qtr, vector &epsp, matrix &dqdgds) |
{ |
double v_ini, v_lambda1, v_kappa1, p1, i1s, epsvp; |
double p_atm = 101325.0; |
double s, sr, fs, b, c, c1, ksi; |
long ncompstr = Mm->ip[ipp].ncompstr; |
strastrestate ssst = Mm->ip[ipp].ssst; |
vector epst(ASTCKVEC(6)); |
// mean stress |
i1s = first_invar (sig)/3.0; |
// initial value of specific volume under small pressure p_1 for the normal consolidation line (v_{\lambda 1} = N) |
v_lambda1 = Mm->ic[ipp][0]; |
// initial reference presure |
p1 = Mm->ic[ipp][1]; |
// initial value of specific volume under small pressure p_1 for the swelling line (v_{\kappa 1}) |
v_kappa1 = Mm->ip[ipp].eqother[ido+ncompstr+3]; |
// specific volume for intial stress state |
v_ini = Mm->ip[ipp].eqother[ido+ncompstr+4]; |
s = Mm->givenonmechq(suction, ipp); // suction pressure s |
//limitation of positive suction |
if(s >=0.0) |
s=0.0; |
s = fabs(s); |
sr = Mm->givenonmechq(saturation_degree, ipp); // degree of saturation S_r |
// actual value of preconsolidation pressure for the fully saturated state |
give_full_vector (epst, epsp, ssst); |
epsvp = first_invar(epst); |
//double pc_new = p1 * exp((v_kappa1 - v_lambda1 + v_ini*epsvp)/(kappa-lambda)); |
// specific volume for the actual preconsolidation pressure: |
// |
// v_{pc} = v_{\lambda1} - \lambda \ln(p_c/p_1) |
//double v_pc = v_lambda1 - lambda * log(pc_new/p1); |
// suction function: |
// |
// s / p_{atm} |
// f(s) = 1 + ----------------------- |
// 10.7 + 2.4(s / p_{atm}) |
// |
fs = 1.0 + (s/p_atm) / (10.7 + 2.4*(s/p_atm)); |
if (fs < 1.0) |
fs = 1.0; |
// bonding variable: |
// |
// \ksi = f(s) (1 - S_r) |
// |
ksi = (1-sr)*fs; |
// \tilde{c}_1 |
// c_1 = -------------------- |
// 1 |
// -------------- + 1 |
// v_{pc}-1 |
// c1 = c1_tilde/(1.0/(v_pc-1.0)+1.0); // according to Borja |
c1 = c1_tilde; // according to Gallipoli |
// |
// c(\ksi) = 1 - c_1 [1-\exp(c_2 \ksi)] |
// |
c = 1.0 - c1*(1.0-exp(c2*ksi)); |
// |
// \lambda - \kappa |
// b(\ksi) = -------------------------- |
// \lambda c(\ksi) - \kappa |
// |
b = (lambda - kappa)/(lambda*c - kappa); |
// q[0] = \bar{p}_c = -\exp[a(\ksi)] (-p_c)^{b(\ksi)} |
// |
// p_c = p_1 exp[(v_{\kappa_1} - v_{\lambda_1} + eps_{vp} v_{ini})/(\kappa - \lambda)] |
// |
// p_1 = const |
// p_{c0} = const |
// \sigma_{m0} = const |
// v_{\kappa_1} = const |
// v_{p_{c0}} = v_{\kappa_1} - \kappa \ln(p_{c0}/p_1) = const |
// v_{ini} = v_{p_{c0}} + \kappa \ln(p_{c0}/\sigma_{m0}) = const |
// v_{\lambda_1} = v_{p_{c0}} - \lambda \ln(p_{c0}/p_1) = const |
// |
// d \bar{p}_c d p_c (-p_c)^{b(\ksi)} d p_c |
// ----------- = -\exp[a(\ksi)] b(\ksi)(-p_c)^{b(\ksi)-1} ---------- = -\exp[a(\ksi)] b(\ksi) ---------------- ---------- , |
// d \gamma d \gamma p_c d \gamma |
// |
// d p_c v_ini |
// ---------- = p_c ----------------- (2p - \bar{p}_c - p_s), |
// d \gamma \kappa - \lambda |
// |
// d \bar{p}_c b(\ksi) v_ini |
// ----------- = -\bar{p}_c ---------------- (2p - \bar{p}_c - p_s) |
// d \gamma \kappa - \lambda |
// |
// |
// dqdg(0) = -qtr[0] * (b*v_ini)/(kappa-lambda) * (2.0*i1s-qtr[0]-qtr[1]); |
dqdgds(0,0) = dqdgds(0,1) = dqdgds(0,2) = -qtr[0] * (b*v_ini)/(kappa-lambda) * 2.0/3.0; |
// q[1] = p_s = k*s |
// |
// d p_s |
// ----------- = 0.0 because p_s is constant for the given strain level |
// d \gamma |
// |
dqdgds(1,0) = dqdgds(1,1) = dqdgds(1,2) = dqdgds(1,3) = dqdgds(1,4) = dqdgds(1,5) = 0.0; |
return; |
} |
/** |
The function computes derivatives of hardening paramters |
with respect of consistency parameter gamma. |
@param ipp - integration point number |
@param ido - index of internal variables for given material in the ipp other array |
@param sig - full stress tensor |
@param qtr - %vector of hardening variables |
@param epsp - %vector of attained plastic strains |
@param dqdgds - %matrix where the resulting derivatives are stored, its dimensions must be qtr.n x qtr.n |
Created by Tomas Koudelka, 05.2022 |
*/ |
void bbmmat::dqpardgammadqpar(long ipp, long ido, vector &sig, vector &qtr, vector &epsp, matrix &dqdgdq) |
{ |
double v_ini, v_lambda1, v_kappa1, p1, i1s, epsvp; |
double p_atm = 101325.0; |
double s, sr, fs, b, c, c1, ksi; |
long ncompstr = Mm->ip[ipp].ncompstr; |
strastrestate ssst = Mm->ip[ipp].ssst; |
vector epst(ASTCKVEC(6)); |
// mean stress |
i1s = first_invar (sig)/3.0; |
// initial value of specific volume under small pressure p_1 for the normal consolidation line (v_{\lambda 1} = N) |
v_lambda1 = Mm->ic[ipp][0]; |
// initial reference presure |
p1 = Mm->ic[ipp][1]; |
// initial value of specific volume under small pressure p_1 for the swelling line (v_{\kappa 1}) |
v_kappa1 = Mm->ip[ipp].eqother[ido+ncompstr+3]; |
// specific volume for intial stress state |
v_ini = Mm->ip[ipp].eqother[ido+ncompstr+4]; |
s = Mm->givenonmechq(suction, ipp); // suction pressure s |
//limitation of positive suction |
if(s >=0.0) |
s=0.0; |
s = fabs(s); |
sr = Mm->givenonmechq(saturation_degree, ipp); // degree of saturation S_r |
// actual value of preconsolidation pressure for the fully saturated state |
give_full_vector (epst, epsp, ssst); |
epsvp = first_invar(epst); |
//double pc_new = p1 * exp((v_kappa1 - v_lambda1 + v_ini*epsvp)/(kappa-lambda)); |
// specific volume for the actual preconsolidation pressure: |
// |
// v_{pc} = v_{\lambda1} - \lambda \ln(p_c/p_1) |
//double v_pc = v_lambda1 - lambda * log(pc_new/p1); |
// suction function: |
// |
// s / p_{atm} |
// f(s) = 1 + ----------------------- |
// 10.7 + 2.4(s / p_{atm}) |
// |
fs = 1.0 + (s/p_atm) / (10.7 + 2.4*(s/p_atm)); |
if (fs < 1.0) |
fs = 1.0; |
// bonding variable: |
// |
// \ksi = f(s) (1 - S_r) |
// |
ksi = (1-sr)*fs; |
// \tilde{c}_1 |
// c_1 = -------------------- |
// 1 |
// -------------- + 1 |
// v_{pc}-1 |
// c1 = c1_tilde/(1.0/(v_pc-1.0)+1.0); // according to Borja |
c1 = c1_tilde; // according to Gallipoli |
// |
// c(\ksi) = 1 - c_1 [1-\exp(c_2 \ksi)] |
// |
c = 1.0 - c1*(1.0-exp(c2*ksi)); |
// |
// \lambda - \kappa |
// b(\ksi) = -------------------------- |
// \lambda c(\ksi) - \kappa |
// |
b = (lambda - kappa)/(lambda*c - kappa); |
// q[0] = \bar{p}_c = -\exp[a(\ksi)] (-p_c)^{b(\ksi)} |
// |
// p_c = p_1 exp[(v_{\kappa_1} - v_{\lambda_1} + eps_{vp} v_{ini})/(\kappa - \lambda)] |
// |
// p_1 = const |
// p_{c0} = const |
// \sigma_{m0} = const |
// v_{\kappa_1} = const |
// v_{p_{c0}} = v_{\kappa_1} - \kappa \ln(p_{c0}/p_1) = const |
// v_{ini} = v_{p_{c0}} + \kappa \ln(p_{c0}/\sigma_{m0}) = const |
// v_{\lambda_1} = v_{p_{c0}} - \lambda \ln(p_{c0}/p_1) = const |
// |
// d \bar{p}_c d p_c (-p_c)^{b(\ksi)} d p_c |
// ----------- = -\exp[a(\ksi)] b(\ksi)(-p_c)^{b(\ksi)-1} ---------- = -\exp[a(\ksi)] b(\ksi) ---------------- ---------- , |
// d \gamma d \gamma p_c d \gamma |
// |
// d p_c v_ini |
// ---------- = p_c ----------------- (2p - \bar{p}_c - p_s), |
// d \gamma \kappa - \lambda |
// |
// d \bar{p}_c b(\ksi) v_ini |
// ----------- = -\bar{p}_c ---------------- (2p - \bar{p}_c - p_s) |
// d \gamma \kappa - \lambda |
// |
// |
// dqdg(0) = -qtr[0] * (b*v_ini)/(kappa-lambda) * (2.0*i1s-qtr[0]-qtr[1]); |
// wrong //dqdgdq(0,0) = 2.0*qtr[0] * (b*v_ini)/(kappa-lambda); |
dqdgdq(0,0) = -(b*v_ini)/(kappa-lambda) * (2.0*i1s-2.0*qtr[0]-qtr[1]); |
dqdgdq(0,1) = qtr[0] * (b*v_ini)/(kappa-lambda); |
// q[1] = p_s = k*s |
// |
// d p_s |
// ----------- = 0.0 because p_s is constant for the given strain level |
// d \gamma |
// |
dqdgdq(1,0) = dqdgdq(1,1) = 0.0; |
return; |
} |
/** |
This function computes plastic modulus. |
@param ipp - integration point number |
390,12 → 769,13 |
@param ido - index of internal variables for given material in the ipp other array |
@param sig - stress tensor in Voigt notation |
@param qtr - %vector of hardening parameters |
@param epsp - %vector of attained plastic strains |
@retval The function returns value of the plastic modulus. |
Created by Tomas Koudelka, 09.2012 |
*/ |
double bbmmat::plasmodscalar(long ipp, long ido, vector &sig, vector &qtr) |
double bbmmat::plasmodscalar(long ipp, long ido, vector &sig, vector &qtr, vector &epsp) |
{ |
double ret; |
vector dfq(ASTCKVEC(2)); |
402,7 → 782,7 |
vector dqg(ASTCKVEC(2)); |
deryieldfq(sig, qtr, dfq); |
der_q_gamma(ipp, ido, sig, qtr, dqg); |
der_q_gamma(ipp, ido, sig, qtr, epsp, dqg); |
scprd(dfq, dqg, ret); |
return -ret; |
428,18 → 808,18 |
vector epst(ASTCKVEC(6)); |
vector depsp(epsp.n); |
double v_kappa1, v_lambda1, p1, depsvp, v_ini, pc_new; |
double v_pc, p_atm = 101.3250; |
double v_pc, p_atm = 101325.0; |
double s, sr, fs, a, b, c, c1, ksi; |
strastrestate ssst = Mm->ip[ipp].ssst; |
long ncompstr = Mm->ip[ipp].ncompstr; |
long i; |
// initial value of specific volume under small pressure p_1 |
v_kappa1 = Mm->ic[ipp][0]; |
// initial value of specific volume under small pressure p_1 for the normal consolidation line (v_lambda1 = 1+N) |
v_lambda1 = Mm->ic[ipp][0]; |
// initial reference presure |
p1 = Mm->ic[ipp][1]; |
// original specific volume before any loading |
v_lambda1 = Mm->ip[ipp].eqother[ido+ncompstr+3]; |
v_kappa1 = Mm->ip[ipp].eqother[ido+ncompstr+3]; |
// specific volume for intial stress state |
v_ini = Mm->ip[ipp].eqother[ido+ncompstr+4]; |
452,9 → 832,11 |
// vk = v_ini*(1+epsv)+kappa*log(i1s/p1); |
for (i=0; i<ncompstr; i++) |
depsp[i] = epsp[i] + Mm->ic[ipp][3+i]; |
depsp[i] = epsp[i];// + Mm->ic[ipp][3+i]; |
give_full_vector(epst, depsp, ssst); |
depsvp = first_invar(epst); |
pc_new = p1 * exp((v_kappa1 - v_lambda1 + v_ini*depsvp)/(kappa-lambda)); |
// For the partially saturated soil, |
471,6 → 853,9 |
v_pc = v_lambda1 - lambda * log(pc_new/p1); |
s = Mm->givenonmechq(suction, ipp); // suction pressure s |
//limitation of positive suction |
if(s >=0.0) |
s=0.0; |
s = fabs(s); |
sr = Mm->givenonmechq(saturation_degree, ipp); // degree of saturation S_r |
481,6 → 866,8 |
// 10.7 + 2.4(s / p_{atm}) |
// |
fs = 1.0 + (s/p_atm) / (10.7 + 2.4*(s/p_atm)); |
if (fs < 1.0) |
fs = 1.0; |
// bonding variable: |
// |
492,8 → 879,9 |
// c_1 = -------------------- |
// 1 |
// -------------- + 1 |
// v_{\lambda1}-1 |
c1 = c1_tilde/(1.0/(v_lambda1-1.0)+1.0); |
// v_{pc}-1 |
// c1 = c1_tilde/(1.0/(v_pc-1.0)+1.0); // according to Borja |
c1 = c1_tilde; // according to Gallipoli |
// |
502,9 → 890,9 |
c = 1.0 - c1*(1.0-exp(c2*ksi)); |
// |
// a(\ksi) = v_ini v_{lambda_1} [c(\ksi)-1]/[\lambda c(\ksi) - \kappa) |
// a(\ksi) = v_{lambda_1} [c(\ksi)-1]/[\lambda c(\ksi) - \kappa) |
// |
a = v_ini*v_lambda1*(c - 1.0)/(lambda*c - kappa); |
a = (v_lambda1 - 1.0)*(c - 1.0)/(lambda*c - kappa); |
// |
// \lambda - \kappa |
554,7 → 942,149 |
case secant_stiff: |
case incr_tangent_stiff: |
case ijth_tangent_stiff:{ |
// consistent tangent stiffness matrix |
long n = Mm->ip[ipp].ncompstr; |
if (sra.give_tsra() == cp){ |
// algorithmic consistent stiffness matrix for the cutting plane algorithm is computed in the course of stress return |
if (d.m != n){ // material stiffness matrix used for element in the case of plane stress/strain states |
for(long i=0; i<d.m; i++) // copy just the first d.n(=3) components at all matrix rows |
memcpy(&d(i,0), Mm->ip[ipp].other+ido+n+15+n*i, d.n*sizeof(*Mm->ip[ipp].other)); |
} |
else{ // dimensions of material stiffness matrix matches the ones for element material stiffness matrix |
matrix auxm; |
makerefm(auxm, Mm->ip[ipp].other+ido+n+15, n, n); |
copym(auxm, d); |
} |
} |
else{ |
// compute algorithmic stiffness matrix for closest point projection stress return algorithm |
matrix de(ASTCKMAT(6, 6)), ddfdst(ASTCKMAT(6,6)); |
matrix e(ASTCKMAT(6, 6)), auxd(ASTCKMAT(6,6)), tmp(ASTCKMAT(6, 6)); |
double gamma = Mm->ip[ipp].other[ido+n]; |
identm(e); |
Mm->elmatstiff(de, ipp, spacestress); |
dderyieldfsigma(ddfdst); |
cmulm(gamma, de, auxd); |
mxm(auxd, ddfdst, tmp); |
addm(e, tmp, auxd); |
invm(auxd, tmp, zero); |
mxm(tmp, de, auxd); |
// matrix representation of the fourth order tensor |
tensor4_ematrix(d, auxd, Mm->ip[ipp].ssst); |
} |
break; |
} |
} |
} |
/** |
This function computes elasto-plastic material stiffnes matrix. |
@param d - allocated matrix structure for material stiffness %matrix in the reduced format |
@param ipp - integration point number |
@param ido - index of internal variables for given material in the ipp other array |
Created by Tomas Koudelka, 09.2012 |
*/ |
void bbmmat::depmatstiff (matrix &d, long ipp, long ido) |
{ |
switch (Mp->nlman->stmat){ |
case initial_stiff: |
// initial elastic matrix |
Mm->elmatstiff(d, ipp, ido); |
break; |
case tangent_stiff: |
case secant_stiff: |
case incr_tangent_stiff: |
case ijth_tangent_stiff:{ |
// consitent tangent stiffness matrix |
long n = Mm->ip[ipp].ncompstr; |
long ncompq = 2; |
matrix de(ASTCKMAT(n, n)), auxm; |
vector sig(ASTCKVEC(n)), q(ASTCKVEC(ncompq)), epsp(ASTCKVEC(n)); |
vector dfds(ASTCKVEC(n)), dgds(ASTCKVEC(n)); |
vector sigt(ASTCKVEC(6)), dfdst(ASTCKVEC(6)), dgdst(ASTCKVEC(6)); |
vector dedgds(ASTCKVEC(n)), dedfds(ASTCKVEC(n)); |
strastrestate ssst = Mm->ip[ipp].ssst; |
double denomh, denomd, denom, gamma, f, err=sra.give_err(); |
// prepare actual values of needed quantities |
copyv(Mm->ip[ipp].stress, sig); // stresses |
copyv(Mm->ip[ipp].other+ido, epsp); // plastic strains |
gamma = Mm->ip[ipp].other[ido+n+0]; // cumulated plastic multiplier |
q(0) = Mm->ip[ipp].other[ido+n+1]; // hardening parameter \bar{p}_c |
q(1) = Mm->ip[ipp].other[ido+n+2]; // hardening parameter k_s |
give_full_vector(sigt, sig, ssst); // 6 component vector of stresses |
// check actual stress state: f <= 0.0 |
f = yieldfunction(sigt, q); |
if ((f < -err) || (gamma == 0.0 && (f < err))){ |
// stress state is in the elastic domain, |
// i.e. material has been subjected by elastic loading/unloading -> |
// -> return actual elastic stiffness matrix |
Mm->elmatstiff(d, ipp, ssst); |
return; |
} |
// stress state is on/close to the yield surface |
// material has been subjected by plastic loading -> |
// compute elasto-plastic matrix |
// D_e \frac{dg}{d\sigma} (\frac{df}{d\sigma})^T D_e |
// D_{ep} = D_e - --------------------------------------------------- |
// (\frac{df}{d\sigma})^T D_e \frac{dg}{d\sigma} + H |
// |
// H = -\frac{df}{dq} \frac{dq}{d\lambda} |
Mm->elmatstiff(de, ipp, ssst); |
deryieldfsigma(sigt, q, dfdst); |
derpotsigma(sigt, q, dgdst); |
// conversion of full tensor notation to vector notation |
give_red_vector(dfdst, dfds, ssst); |
// conversion of full tensor notation to vector notation |
give_red_vector(dgdst, dgds, ssst); |
mxv(de,dgds,dedgds); |
mxv(de,dfds,dedfds); |
denomh = plasmodscalar(ipp, ido, sig, q, epsp); |
scprd(dfds, dedgds, denomd); |
// preserve minimum stiffness for perfect plastic material, i.e. if the hardening modulus is 'close' to zero (H->0) |
// if (fabs(denomh/denomd) < 1.0e-3) |
// denomh = sgn(denomh)*1.0e-3*denomd; |
denom = denomd+denomh; |
if (n == d.m){ |
// material stiffness matrix has identical dimensions with the ones of stiffness matrix used in |
// assembling of element stiffness matrix on finite element -> auxm will be reference on matrix d |
makerefm(auxm, d.a, d.m, d.n); |
nullm(auxm); |
} |
else{ |
// material stiffness matrix has different dimensions than the stiffness matrix used in |
// assembling of element stiffness matrix on finite element -> auxm will be reference on matrix d |
reallocm(RSTCKMAT(n, n, auxm)); |
} |
// calculate matrix in the nominator |
vxv(dedgds, dedfds, auxm); |
// scaling by the denominator |
cmulm(1.0/denom, auxm); |
// resulting material stiffness matrix |
subm(de, auxm, auxm); |
// resulting material stiffness matrix with dimensions adjusted for finite element computation |
if (n != d.m){ |
// resulting material stiffness matrix dimensions must be adjusted for finite element computation |
extractblock(auxm, d, 0, 0); |
} |
else{ |
// nothing is needed, matrix auxm is direct reference to the matrix in argument d |
// hence d contains resulting material stiffness matrix with appropriate dimensions for |
// the stiffness matrix on the finite element |
} |
/* |
double zero=1.0e-20; |
matrix de(ASTCKMAT(6, 6)), ddfdst(ASTCKMAT(6,6)); |
matrix e(ASTCKMAT(6, 6)), auxd(ASTCKMAT(6,6)), tmp(ASTCKMAT(6, 6)); |
long n = Mm->ip[ipp].ncompstr; |
568,15 → 1098,129 |
invm(auxd, tmp, zero); |
mxm(tmp, de, auxd); |
// matrix representation of the fourth order tensor |
tensor4_ematrix(d, auxd, Mm->ip[ipp].ssst); |
tensor4_ematrix(d, auxd, Mm->ip[ipp].ssst);*/ |
break; |
} |
} |
} |
/** |
The function computes stress increments due to suction and temperature changes in the integration point and stores |
them into eqother array. |
@param ipp - integration point pointer |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
@return The function does not return anything but stores the resulting values in the eqother array. |
Created by Tomas krejci, 02/2023 |
*/ |
void bbmmat::nlstressesincr (long ipp, long im, long ido) |
// |
{ |
double n,v,depss=0.0,depst=0.0,ds,s,kappa_s,lambda_s,p_atm = 101325.0,p,pc_ref; |
// double temp=0.0,temp0=0.0,dtemp=0.0; |
long i,ncomp; |
// stress/strain state |
strastrestate ss = Mm->ip[ipp].ssst; |
ncomp=Mm->ip[ipp].ncompstr; |
matrix d(ASTCKMAT(ncomp,ncomp)); |
vector depsv(ASTCKVEC(ncomp)),dsigma(ASTCKVEC(ncomp)); |
if (Mm->ip[ipp].tm[im-1] == effective_stress){ |
// In case of effective stresses concept, stress increments due to suction changes are included in eff_stress material |
for (i=0;i<ncomp;i++) |
Mm->ip[ipp].eqother[ido+ncomp+15+ncomp*ncomp+i] = 0.0; |
} |
else{ |
//stress increments are computed in case of total stresses concept (net stress) - not completed!!! |
// suction change |
//if (pr_suc_f == no){ |
// actual porosity n |
n = Mm->ip[ipp].other[ido+ncomp+11]; |
// specific volume |
v = 1/(1-n); |
// suction increment |
ds = Mm->givenonmechq(suction, ipp) - Mm->ip[ipp].eqother[ido+ncomp+12]; |
s = Mm->givenonmechq(suction, ipp); |
//positive notation of suction |
s = fabs(s); |
// volume strain caused by a suction change |
// calculate negative increment of stresses due to change in suction (-du = -ds*chi) |
// which will be used in calculation of nodal forces and added to the right hand side vector |
// K*dr = df_e - \int B^T*du dV |
if(ds >= 0.0){//swelling |
p = Mm->ip[ipp].eqother[ido+ncomp+5];//effective mean stress |
pc_ref = Mm->ip[ipp].eqother[ido+ncomp+1]; //effective preconsolidation pressure |
kappa_s = kappa_s0*(1+aks1*log(p/pc_ref))*exp(aks2*s); |
depss = -kappa_s*ds/(3*v*(s+p_atm));//swelling |
} |
else{//shrinkage - not finished!!?? |
lambda_s = kappa_s0;//provisionally |
depss = -lambda_s*ds/(3*v*(s+p_atm));//shrinkage |
} |
//} |
// temperature change - not completed |
//if (pr_tempr_f == no){ |
//temp = ??? |
//temp0 = ??? |
//dtemp = ??? |
//depst = (a0 + a2*(temp - temp0))*dtemp/3.0; |
//} |
//only uniaxial |
if(ss==bar){ |
depsv[0]=depss+depst; |
} |
else{ |
depsv[0]=depss+depst; |
depsv[1]=depss+depst; |
} |
if(ss==planestrain) depsv[3]=depss+depst; |
if(ss==planestress) depsv[3]=depss+depst; |
if(ss==axisymm) depsv[2]=depss+depst; |
if(ss==spacestress) depsv[2]=depss+depst; |
fillm(0.0,d); |
matstiff (d, ipp, ido); |
mxv (d,depsv,dsigma); |
for (i=0;i<ncomp;i++) |
Mm->ip[ipp].eqother[ido+ncomp+15+ncomp*ncomp+i] = dsigma(i); |
} |
} |
/** |
The function computes stress increment due to pore pressure change in the integration point and stores |
them into ip stress array. |
@param lcid - load case id |
@param ipp - integration point number |
@param im - index of the material in the tm and idm arrays on integration point |
@param ido - index of internal variables in the ip's ipp eqother array |
@param fi - first index of the required stress increment component |
@param sig - %vector containing stress increment components (output) |
@return The function returns %vector of stress increments in the parameter sig. |
Created by Tomas Krejci, 02/2023 |
*/ |
void bbmmat::givestressincr (long lcid, long ipp, long im, long ido, long fi, vector &sig) |
{ |
nullv(sig); |
long i, j, ncomp = Mm->ip[ipp].ncompstr; |
for (i=fi,j=0; j<sig.n; i++, j++) |
sig(j) = Mm->ip[ipp].eqother[ido+ncomp+15+ncomp*ncomp+i]; |
} |
/** |
This function computes stresses at given integration point ipp, |
depending on the reached strains. |
The cutting plane algorithm is used. The stress and the other attribute of |
583,6 → 1227,7 |
given integration point is actualized. |
@param ipp - integration point number in the mechmat ip array. |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
Created by Tomas Koudelka, 09.2012 |
591,19 → 1236,19 |
// |
{ |
int errr; |
long i,ni,ncomp=Mm->ip[ipp].ncompstr; |
double gamma,err; |
long i,ni,ncomp=Mm->ip[ipp].ncompstr, matcomp=0, ret; |
double gamma, err, pnewdt = 1.0; |
vector epsn(ASTCKVEC(ncomp)), epsp(ASTCKVEC(ncomp)), q(ASTCKVEC(2)); |
vector epsa(ASTCKVEC(ncomp)), sig(ASTCKVEC(ncomp)), dfds(ASTCKVEC(ncomp)), dgds(ASTCKVEC(ncomp)); |
matrix d(ASTCKMAT(ncomp,ncomp)); |
matrix d; |
vector dfdst(ASTCKVEC(6)), dgdst(ASTCKVEC(6)); |
vector epst(ASTCKVEC(6)), epsnt(ASTCKVEC(6)), epspt(ASTCKVEC(6)), sigt(ASTCKVEC(6)); |
//vector dev(ASTCKVEC(6)); |
double i1s, j2s, epsv, epsvp; |
double dtime = Mp->timecon.actualforwtimeincr(); |
// double p_atm = 101.3250,s,ds; |
vector epss(ASTCKVEC(ncomp)); |
matrix epsvs(ASTCKMAT(3,3)); |
// stress/strain state |
//strastrestate ssst = Mm->ip[ipp].ssst; |
//double nu; |
// initial values |
for (i=0; i<ncomp; i++) |
610,30 → 1255,11 |
{ |
epsn[i] = Mm->ip[ipp].strain[i]; |
epsp[i] = Mm->ip[ipp].eqother[ido+i]; |
// epsp[i] += Mm->ic[ipp][3+i]; |
// It is necessary to substract initial strains in order to invoke initial nonzero stress |
// state for zero displacements (i.e. zero strains) |
// sig = E*(eps - eps_p), sig_0 = E*eps_0. For eps = 0: sig = sig_0 => eps_p = -eps_0 |
epsp[i] -= Mm->ic[ipp][3+i]; |
// epsp[i] -= Mm->ic[ipp][3+i]; |
} |
//zde vlozeno??!! |
//elastic swelling strains: |
/////////////////////////////////////////////////// |
//s = Mm->givenonmechq(suction, ipp); // suction pressure s |
//ds = s - Mm->ip[ipp].eqother[ido+ncomp+12]; |
//for (i=0;i<3;i++) |
//epsvs[i][i] = -0.022/(1+0.6)*ds/(s+p_atm); |
// convert total stress tensor back to vector form - epss |
//tensor_vector(epss, epsvs, Mm->ip[ipp].ssst,stress); |
//for (i=0; i<ncomp; i++) |
//Mm->ip[ipp].strain[i] += epss[i]; |
/////////////////////////////////////////////////// |
gamma=Mm->ip[ipp].eqother[ido+ncomp]; |
q[0] = Mm->ip[ipp].eqother[ido+ncomp+1]; // effective preconsolidation pressure \bar{p}_c |
q[1] = Mm->ip[ipp].eqother[ido+ncomp+2]; // apparent adhesion p_s = k * s |
640,11 → 1266,18 |
// stress return algorithm |
switch(sra.give_tsra ()) |
{ |
{ |
case cp: |
ni=sra.give_ni (); |
err=sra.give_err (); |
Mm->cutting_plane (ipp, im, ido, gamma, epsn, epsp, q, ni, err); |
matcomp = actualize_stiffmat(*Mp->nlman, Mp->istep, Mp->jstep); |
if (Mp->istep >= 265){ |
matcomp = 0; |
} |
if (matcomp) reallocm(RSTCKMAT(ncomp, ncomp, d)); |
ret = Mm->cutting_plane (ipp, im, ido, gamma, epsn, epsp, q, ni, err, matcomp, d); |
if (ret) |
pnewdt = 0.5; |
break; |
case gsra: |
ni=sra.give_ni (); |
654,15 → 1287,43 |
default: |
print_err("wrong type of stress return algorithm is required", __FILE__, __LINE__, __func__); |
abort (); |
} |
/* |
//////////////////////////////// |
// elastic material for debug!!?? |
// initial values |
for (i=0;i<ncomp;i++){ |
epsn[i]=epsp[i]=Mm->ip[ipp].strain[i]; |
} |
reallocm(RSTCKMAT(ncomp, ncomp, d)); |
Mm->elmatstiff (d,ipp,ssst); |
nu = 0.3; |
mxv (d,epsn,sig); |
if (Mm->ip[ipp].ssst == planestress) |
Mm->ip[ipp].strain[3] = -nu / (1.0 - nu) * (epsn[0]+epsn[1]); |
if ((Mp->eigstrains == 4) || (Mp->eigstrains == 5)) |
{ |
for (i=0;i<ncomp;i++) |
sig(i) += Mm->eigstresses[ipp][i]; |
} |
for (i=0;i<ncomp;i++){ |
Mm->ip[ipp].stress[i]=sig(i); |
} |
//////////////////////////////// |
*/ |
// new data storage |
for (i=0; i<ncomp; i++){ |
epsp[i] += Mm->ic[ipp][3+i]; |
//epsp[i] += Mm->ic[ipp][3+i]; |
Mm->ip[ipp].other[ido+i]=epsp[i]; |
} |
Mm->ip[ipp].other[ido+ncomp]=gamma; |
Mm->ip[ipp].other[ido+ncomp+1]=q[0]; // the first hardening parameter \bar{p}_c |
Mm->ip[ipp].other[ido+ncomp+2]=q[1]; // the second hardening parameter p_s |
// other[ido+ncomp+3] = v_lambda1; it is the initial value and therefore it does not require actualization |
// other[ido+ncomp+4] = v_ini; it is the initial value and therefore it does not require actualization |
Mm->givestress(0, ipp, sig); |
670,14 → 1331,13 |
give_full_vector(epsnt,epsn,Mm->ip[ipp].ssst); |
give_full_vector(epspt,epsp,Mm->ip[ipp].ssst); |
//vector_tensor (sig,sigt,Mm->ip[ipp].ssst,strain); |
//vector_tensor (epsn,epst,Mm->ip[ipp].ssst,strain);//tady??!! |
//vector_tensor (epsp,epspt,Mm->ip[ipp].ssst,strain); |
//deviator (sigt,dev); |
i1s = first_invar (sigt)/3.0; |
// the second invariant of deviator |
// it is expressed with the help of the stress components |
// components of the deviator are not needed |
j2s = sqrt(j2_stress_invar (sigt)); |
epsv = first_invar (epsnt);//tady??!! |
epsv = first_invar (epsnt); |
epsvp = first_invar (epspt); |
Mm->ip[ipp].other[ido+ncomp+5] = i1s; |
Mm->ip[ipp].other[ido+ncomp+6] = j2s; |
684,11 → 1344,15 |
Mm->ip[ipp].other[ido+ncomp+7] = epsv; |
Mm->ip[ipp].other[ido+ncomp+8] = epsvp; |
Mm->ip[ipp].other[ido+ncomp+9] = Mm->givenonmechq(saturation_degree, ipp); |
Mm->ip[ipp].other[ido+ncomp+10] = (epsv - Mm->ip[ipp].eqother[ido+ncomp+7])/dtime; |
// volumetric strain rate |
//Mm->ip[ipp].other[ido+ncomp+10] = (epsv - Mm->ip[ipp].eqother[ido+ncomp+7])/dtime; |
// the volumetric strain rate is computed via generalized trapesoidal rule |
Mm->ip[ipp].other[ido+ncomp+10] = 0.5*((epsv - Mm->ip[ipp].eqother[ido+ncomp+7])/dtime + Mm->ip[ipp].eqother[ido+ncomp+10]); |
// reference presure = p1 |
double p1 = Mm->ic[ipp][1]; |
// specific volume at the reference pressure p_1 = v_lambda1 |
double v_lambda1 = Mm->ip[ipp].eqother[ido+ncomp+3]; |
double v_lambda1 = Mm->ic[ipp][0]; |
// specific volume for the actual preconsolidation pressure = v_pc |
double v_pc = v_lambda1 - lambda * log(q[0]/p1); |
// specific volume for the actual pressure p |
699,25 → 1363,79 |
v = v_pc + kappa*log(-q[0]); |
// actual porosity n |
Mm->ip[ipp].other[ido+ncomp+11] = (v-1.0)/v; |
// suction |
Mm->ip[ipp].other[ido+ncomp+12] = Mm->givenonmechq(suction, ipp); |
// Young modulus |
Mm->ip[ipp].other[ido+ncomp+13] = give_actual_ym(ipp, im, ido); |
// time step scaling factor |
Mm->ip[ipp].other[ido+ncomp+14] = pnewdt; |
if (matcomp) |
copym(d, Mm->ip[ipp].other+ido+ncomp+15); |
errr = check_math_errel(Mm->elip[ipp]); |
} |
/** |
Function returns flag whether actualize the stiffness matrix according to the setup of the nonlinear solver and |
attained number of steps. |
@param[in] smt - type of the stiffness matrix modification in NR method |
@param[in] istep - number of load increment step in NR method |
@param[in] jstep - number of inner iteration step in NR method |
@retval 0 - in the case that actualization of the stiffness matrix is NOT required |
@retval 1 - in the case that actualization of the stiffness matrix is required |
*/ |
long bbmmat::actualize_stiffmat(const nonlinman &nlman, long istep, long jstep) |
{ |
long ret = 0; |
switch (nlman.stmat){ |
case initial_stiff: |
break; |
case tangent_stiff: |
ret = 1; |
break; |
case secant_stiff: |
case incr_tangent_stiff:{ |
if (jstep <= 0) |
ret = 1; |
break; |
} |
case ijth_tangent_stiff:{ |
if (((jstep <= 0) && (istep % nlman.ithstiffchange == 0)) || |
((jstep+1) % nlman.jthstiffchange == 0)) |
ret = 1; |
break; |
} |
default:{ |
print_err("unknown type of stiffness matrix is required",__FILE__,__LINE__,__func__); |
} |
} |
return ret; |
} |
/** |
This function updates values in the other array reached in the previous equlibrium state to |
values reached in the new actual equilibrium state. |
@param ipp - integration point number in the mechmat ip array. |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
Created by Tomas Koudelka, 09.2012 |
*/ |
void bbmmat::updateval (long ipp,long ido) |
void bbmmat::updateval (long ipp, long im, long ido) |
{ |
long i,n = Mm->ip[ipp].ncompstr; |
double e = comp_actual_ym(ipp, im, ido); |
for (i=0;i<n;i++){ |
Mm->ip[ipp].eqother[ido+i]=Mm->ip[ipp].other[ido+i]; |
} |
736,18 → 1454,174 |
Mm->ip[ipp].eqother[ido+n+7] = Mm->ip[ipp].other[ido+n+7]; // epsv; |
Mm->ip[ipp].eqother[ido+n+8] = Mm->ip[ipp].other[ido+n+8]; // epsvp; |
// saturation degree |
Mm->ip[ipp].eqother[ido+n+9] = Mm->ip[ipp].other[ido+n+9]; // Sr |
Mm->ip[ipp].eqother[ido+n+9] = Mm->ip[ipp].other[ido+n+9]; // Sr |
// volumteric strain rate |
Mm->ip[ipp].eqother[ido+n+10] = Mm->ip[ipp].other[ido+n+10]; // depsv/dt |
Mm->ip[ipp].eqother[ido+n+10] = Mm->ip[ipp].other[ido+n+10]; // depsv/dt |
// actual porosity n |
Mm->ip[ipp].eqother[ido+n+11] = Mm->ip[ipp].other[ido+n+11]; |
// actual suction |
Mm->ip[ipp].eqother[ido+n+12] = Mm->ip[ipp].other[ido+n+12]; |
// suction |
Mm->ip[ipp].eqother[ido+n+12] = Mm->ip[ipp].other[ido+n+12]; //s |
// Young modulus |
Mm->ip[ipp].eqother[ido+n+13] = Mm->ip[ipp].other[ido+n+13] = e; |
// time step scaling factor |
Mm->ip[ipp].eqother[ido+n+14] = Mm->ip[ipp].other[ido+n+14]; |
// stiffness matrix |
for (i=0;i<n*n;i++){ |
Mm->ip[ipp].eqother[ido+n+15+i] = Mm->ip[ipp].other[ido+n+15+i]; |
} |
// stress increments - it is not needed |
//for (i=0;i<n;i++){ |
//Mm->ip[ipp].eqother[ido+n+15+n*n+i]=Mm->ip[ipp].other[ido+n+15+n*n+i]; |
//} |
} |
/** |
The function returns actual Young modulus value. |
@param ipp - integration point number |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
*/ |
double bbmmat::give_actual_ym(long ipp, long im, long ido) |
{ |
long ncomp=Mm->ip[ipp].ncompstr; |
double e = Mm->ip[ipp].other[ido+ncomp+13]; |
return e; |
} |
/** |
The function computes actual Young modulus value. |
@param ipp - integration point number |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
*/ |
double bbmmat::comp_actual_ym(long ipp, long im, long ido) |
{ |
long idem = Mm->ip[ipp].gemid(); |
long ncompo = Mm->givencompeqother(ipp, im); |
double e; |
// initial Young modulus |
double e_ini = Mm->give_initial_ym(ipp, idem, ido+ncompo); |
// actual Poisson's ratio |
double nu = give_actual_nu(ipp, im, ido); |
// actual values of strains |
long ncomp=Mm->ip[ipp].ncompstr; |
strastrestate ssst = Mm->ip[ipp].ssst; |
//vector epsp(ASTCKVEC(ncomp)); |
vector epst(ASTCKVEC(6)); |
vector eps(ASTCKVEC(ncomp)); |
vector epsp(ASTCKVEC(ncomp)); |
vector sig(ASTCKVEC(ncomp)); |
vector q(ASTCKVEC(1)); |
// actual total volumetric strain |
Mm->givestrain(0, ipp, eps); |
give_full_vector(epst, eps, ssst); |
double epsv = first_invar(epst); |
// actual plastic volumteric strain |
//Mm->giveother(ipp, ido, ncomp, epsp); |
// total volumetric strain from the last converged step |
double epsvo = Mm->ip[ipp].eqother[ido+ncomp+7]; |
// total volumetric plastic strain from the last converged step |
double epsvpo = Mm->ip[ipp].eqother[ido+ncomp+8]; |
// actual plastic strain |
for(long i=0; i<ncomp; i++) |
epsp(i) = Mm->ip[ipp].other[ido]; |
give_full_vector(epst, epsp, ssst); |
double epsvp = first_invar(epst); |
// actual value of p_c |
//updateq(ipp, ido, eps, epsp, sig, q); |
//double pc = q(0); |
double pc = Mm->ip[ipp].other[ido+ncomp+1]; |
/* |
// initial value of elastic strain |
for (long i=0; i<ncomp; i++) |
eps(i) = Mm->ic[ipp][3+i]; |
give_full_vector(auxt, eps, ssst); |
double epsv_ini = first_invar(auxt); |
if (epsv >= epsv_ini) |
return e_ini;*/ |
// actual value of of specific volume |
double v_ini = Mm->ip[ipp].eqother[ido+ncomp+4]; |
//double v = v_ini*(1.0+epsv); |
//double p = pc/exp((v-v_pc)/kappa); |
double po = Mm->ip[ipp].eqother[ido+ncomp+5]; |
if ((po == 0.0) || (epsv == 0.0)) |
return e_ini; |
if (po > pc){ |
// for the unloading: \Delta eps^{el}_V = \Delta eps_V |
// actual p according actual swelling line |
double epsve = (epsv-epsvo) - (epsvp - epsvpo); |
double p = po*exp(-(epsve)*v_ini/kappa); |
if (epsve == 0.0) |
e = 3.0*(1.0-2.0*nu)*v_ini*(-p)/kappa; |
else |
e = 3.0*(1.0-2.0*nu)*(p-po)/(epsve); |
} |
else{ |
e = e_ini; |
} |
//e = 3.0*(1.0-2.0*nu)*v*(-p)/kappa; |
return e; |
} |
/** |
The function returns actual Poisson's ratio. |
@param ipp - integration point number |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
*/ |
double bbmmat::give_actual_nu(long ipp, long im, long ido) |
{ |
long idem = Mm->ip[ipp].gemid(); |
long ncompo = Mm->givencompeqother(ipp, im); |
double nu = Mm->give_initial_nu(ipp, idem, ido+ncompo); |
return nu; |
} |
/** |
The function returns time step scaling factor required by the model. It is represented by ratio |
of required time step size to the actual one or 1.0 for no change in time step size. |
@param ipp - integration point number in the mechmat ip array. |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
@return The function returns required time step scaling factor provided by the bbmmat model |
Created by Tomas Koudelka, 5.2022 |
*/ |
double bbmmat::dstep_red(long ipp, long im, long ido) |
{ |
long ncomp = Mm->ip[ipp].ncompstr; |
return (Mm->ip[ipp].other[ido+ncomp+14]); |
} |
/** |
Function returns irreversible plastic strains. |
@param ipp - integration point number in the mechmat ip array. |
939,8 → 1813,12 |
*/ |
void bbmmat::give_reqnmq(long *anmq) |
{ |
//if (pr_suc_f == no){ |
anmq[saturation_degree-1] = 1; |
anmq[suction-1] = 1; |
//} |
//if (pr_tempr_f == no) |
//anmq[temperature-1] = 1; |
} |
/trunk/SIFEL/MEFEL/SRC/bbm.h |
---|
1,12 → 1,17 |
#ifndef BBMMAT_H |
#define BBMMAT_H |
#include "iotools.h" |
#include "galias.h" |
#include "gfunct.h" |
#include "xfile.h" |
#include "alias.h" |
#include "strretalg.h" |
#include "matrix.h" |
#include "vector.h" |
struct matrix; |
struct vector; |
struct atsel; |
class nonlinman; |
/** |
This class defines modified cam-clay material model |
for coupling with moisture transfer. The material is defined by |
17,7 → 22,7 |
Additionally, there are three parameters which controls |
evolution of hardening with respect to degree of saturation and suction |
c1_tilde, c2 - controls the ration of specific volumes v/v_sat (partially sturated/fully saturated) |
c1_tilde, c2 - controls the ratio of specific volumes v/v_sat (partially saturated/fully saturated) |
ks - controls apparent adhesion (intersection of yield surface with p axis) |
In addition to these material constants, several initial values |
26,11 → 31,11 |
unloading from initial consolidation pressure p_c0 (v_kappa0) |
p1 - reference pressure (p_1), it must be negative |
p_c0 - initial consolidation pressure, it must be negative |
iepsp_1 - |
sig0_1 - |
. \ |
. \ components of initial plastic strains |
. \ components of eigenstresses |
. / |
iepsp_ncomp - |
sig0_ncomp - |
Order of the eqother array components |
id | description |
59,7 → 64,7 |
bbmmat (void); |
~bbmmat (void); |
void read (XFILE *in); |
void initval(long ipp, long ido); |
void initval(long ipp, long im, long ido); |
double cohesion(vector &qtr); |
double yieldfunction (vector &sig, vector &q); |
void deryieldfsigma (vector &sig, vector &q, vector &dfds); |
66,15 → 71,25 |
void dderyieldfsigma (matrix &ddfds); |
void derpotsigma (vector &sig, vector &q, vector &dgds); |
void deryieldfq(vector &sig, vector &q, vector &dq); |
void deryieldfdqdq(matrix &dfq); |
void deryieldfdqdq(matrix &ddfdq); |
void deryieldfdsdq(matrix &dfdsdqt); |
void der_q_gamma(long ipp, long ido, vector &sig, vector &qtr, vector &dqdg); |
double plasmodscalar(long ipp, long ido, vector &sig, vector &qtr); |
void der_q_gamma(long ipp, long ido, vector &sig, vector &qtr, vector &epsp, vector &dqdg); |
void dqpardgammadsigma(long ipp, long ido, vector &sig, vector &qtr, vector &epsp, matrix &dqdgds); |
void dqpardgammadqpar(long ipp, long ido, vector &sig, vector &qtr, vector &epsp, matrix &dqdgdq); |
double plasmodscalar(long ipp, long ido, vector &sig, vector &qtr, vector &epsp); |
void updateq(long ipp, long ido, vector &eps, vector &epsp, vector &sig, vector &q); |
// void updateq(vector &epsp, strastrestate ssst, vector &q); |
void matstiff (matrix &d, long ipp,long ido); |
void depmatstiff (matrix &d, long ipp, long ido); |
void nlstressesincr (long ipp,long im,long ido); |
void givestressincr (long lcid, long ipp, long im, long ido, long fi, vector &sig); |
void nlstresses (long ipp,long im,long ido); |
void updateval (long ipp,long ido); |
long actualize_stiffmat(const nonlinman &nlman, long istep, long jstep); |
void updateval (long ipp, long im, long ido); |
double comp_actual_ym(long ipp, long im, long ido); |
double give_actual_ym(long ipp, long im, long ido); |
double give_actual_nu(long ipp, long im, long ido); |
double dstep_red(long ipp, long im, long ido); |
void giveirrstrains (long ipp, long ido, vector &epsp); |
double give_consparam (long ipp, long ido); |
double give_preconspress(long ipp, long ido); |
104,6 → 119,23 |
/// coefficent of apparent adhesion due to suction pressure |
double ks; |
/// soil swelling index reference value |
double kappa_s0; |
/// parameters for the strain rate caculation caused by the suction change |
double aks1,aks2; |
/// parameters for the thermal strain rate caculation |
double a0,a2; |
/// flag for suction definition (yes=suction evolution is prescribed by suc_fn, no=suction is taken from TRFEL) |
//answertype pr_suc_f; |
/// function of prescribed suction evolution |
//gfunct suc_fn; |
/// flag for temperature definition (yes=temperature is prescribed by tempr_fn, no=temperature is taken from TRFEL) |
//answertype pr_tempr_f; |
/// function of prescribed temperature evolution |
//gfunct tempr_fn; |
/// stress return algorithm |
strretalg sra; |
}; |
/trunk/SIFEL/MEFEL/SRC/creep.cpp |
---|
27,6 → 27,7 |
*/ |
void creep_matstiff (matrix &d, long ipp, long im, long ido) |
{ |
long i,j; |
double q; |
q = 1.0; |
// asymptotic elastic stiffness matrix |
36,6 → 37,17 |
// actual stiffness matrix |
cmulm(q, d); |
// this printing below is only for debug: |
//fprintf(Out,"\n q = %lf\n",q); |
//fprintf(Out,"\n\n vysledna matice pro creep D^M\n"); |
//for (i=0;i<6;i++){ |
//for (j=0;j<6;j++) |
// fprintf(Out,"%e \n",d[i][j]); |
//fprintf(Out,"\n"); |
//} |
//fflush(Out); |
} |
/trunk/SIFEL/MEFEL/SRC/creep_b3.cpp |
---|
445,9 → 445,9 |
/** |
function stores E_mu stifnesses of Kelvin chain units into eqother |
function stores E_mu stiffnesses of Kelvin chain units into eqother |
@param e_mu - %vector of stifnesses |
@param e_mu - %vector of stiffnesses |
@param n_ret_times - number of ret. times |
@param ipp - number of integration point |
@param ido - index of internal variables for given material in the ipp other array |
473,9 → 473,9 |
/** |
function returns E_mu stifnesses of Kelvin chains |
function returns E_mu stiffnesses of Kelvin chains |
@param e_mu - %vector of stifnesses |
@param e_mu - %vector of stiffnesses |
@param n_ret_times - number of ret. times |
@param ipp - number of integration point |
@param ido - index of internal variables for given material in the ipp other array |
/trunk/SIFEL/MEFEL/SRC/creep_dpl.cpp |
---|
286,9 → 286,9 |
/** |
function stores E_mu stifnesses of Kelvin chain units into eqother |
function stores E_mu stiffnesses of Kelvin chain units into eqother |
@param e_mu - %vector of stifnesses |
@param e_mu - %vector of stiffnesses |
@param n_ret_times - number of ret. times |
@param ipp - number of integration point |
@param ido - index of internal variables for given material in the ipp other array |
314,9 → 314,9 |
/** |
function returns E_mu stifnesses of Kelvin chains |
function returns E_mu stiffnesses of Kelvin chains |
@param e_mu - %vector of stifnesses |
@param e_mu - %vector of stiffnesses |
@param n_ret_times - number of ret. times |
@param ipp - number of integration point |
@param ido - index of internal variables for given material in the ipp other array |
/trunk/SIFEL/MEFEL/SRC/creep_rspec.cpp |
---|
746,7 → 746,7 |
/** |
function stores E_mu stiffnesses of Kelvin chain units into eqother |
@param e_mu - %vector of stifnesses |
@param e_mu - %vector of stiffnesses |
@param n_ret_times - number of ret. times |
@param ipp - number of integration point |
@param ido - index of internal variables for given material in the ipp other array |
772,9 → 772,9 |
/** |
function returns E_mu stifnesses of Kelvin chains |
function returns E_mu stiffnesses of Kelvin chains |
@param e_mu - %vector of stifnesses |
@param e_mu - %vector of stiffnesses |
@param n_ret_times - number of ret. times |
@param ipp - number of integration point |
@param ido - index of internal variables for given material in the ipp other array |
/trunk/SIFEL/MEFEL/SRC/dloadcase.cpp |
---|
764,7 → 764,8 |
@return The function returns prescribed displacement. |
Created by Tomas Koudelka, 14.11.2007 |
Modified by Tomas Koudelka, 07.2016 |
Modified by Tomas Koudelka, 07.2016, |
Corrected by TKr, 20/04/2023 |
*/ |
double dloadcase::get_pd(double time, long dof) |
{ |
789,7 → 790,8 |
} |
case timedepload:{ |
if (npd) |
ret = pd[0-dof-1].getval(Mp->time); |
//ret = pd[0-dof-1].getval(Mp->time); |
ret = pd[0-dof-1].getval(time); // corrcted for values for the given time |
if (tnpid && (-dof > max_npd)) // initial prescribed displacements at gradual construction problem have been defined |
ret = pid[-(dof+max_npd+1)]; // dof number of prescribed initial displacement is negative and it is less than all dof numbers |
// for prescribed displacements defined in particular subloadcases |
/trunk/SIFEL/MEFEL/SRC/dsm.cpp |
---|
0,0 → 1,1855 |
#include <math.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include "dsm.h" |
#include "global.h" |
#include "probdesc.h" |
#include "mechmat.h" |
#include "vecttens.h" |
#include "intpoints.h" |
#include "matrix.h" |
#include "vector.h" |
#include "tensor.h" |
#include "elastisomat.h" |
#include "mathem.h" |
#include "nonlinman.h" |
/** |
This constructor inializes attributes to zero values. |
*/ |
dsmmat::dsmmat (void) |
{ |
m = 0.0; |
lambda = 0.0; |
kappa = 0.0; |
c1_tilde = 0.0; |
c2 = 0.0; |
ks = 0.0; |
//pr_suc_f = no; |
//pr_tempr_f = no; |
kappa_s0 = 0.0; |
aks1 = 0.0; |
aks2 = 0.0; |
a0 = 0.0; |
a2 = 0.0; |
} |
/** |
This destructor is only for the formal purposes. |
*/ |
dsmmat::~dsmmat (void) |
{ |
} |
/** |
This function reads material parameters from the opened text file given |
by the parameter in. |
@param in - pointer to the opned text file |
*/ |
void dsmmat::read (XFILE *in) |
{ |
xfscanf (in, "%k%lf%k%lf%k%lf", "m", &m, "lambda", &lambda, "kappa", &kappa); |
xfscanf (in, "%k%lf%k%lf%k%lf", "c1_tilde", &c1_tilde, "c2", &c2, "ks", &ks); |
sra.read (in); |
} |
/** |
This function initializes material model data |
with respect of consistency parameter gamma. |
@param ipp - integration point number |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
12/06/2012 TKo |
*/ |
void dsmmat::initval(long ipp, long im, long ido) |
{ |
double v_ini, v_pc0, v_lambda1; |
double i1s, j2s, s; |
double v_kappa1, p1, bar_pc_0, pc_0; |
long i, ncompstr = Mm->ip[ipp].ncompstr; |
vector sig(ASTCKVEC(ncompstr)),sigt(ASTCKVEC(6)), q(ASTCKVEC(2)); |
double err=sra.give_err (); |
// variables used for the calculation of initial value of preconsolidation pressure for the fully saturated state |
double a, b, fs, ksi, sr, qq, p_atm = 101325.0; |
if (Mm->ip[ipp].eqother[ido+ncompstr+1] == 0.0) // actual value of p_c was not set |
{ |
// initial value of specific volume under small pressure p_1 on the normal consolidation line (v_lambda1 = 1+N) |
v_lambda1 = Mm->ic[ipp][0]; |
// initial reference presure |
p1 = Mm->ic[ipp][1]; |
// initial effective preconsolidation pressure \bar{p}_{c0}} |
bar_pc_0 = Mm->ic[ipp][2]; |
// initial effective stresses |
if ((Mp->eigstrains == 4) || (Mp->eigstrains == 5)){ |
for (i=0; i<ncompstr; i++) |
sig(i) = Mm->ip[ipp].stress[i] = Mm->eigstresses[ipp][i]; |
} |
else{ |
print_err("initial effective stresses (eigentsresses) are not defined on element %ld, ip=%ld,\n" |
" cannot determine specific volume for initial stress state", __FILE__, __LINE__, __func__, Mm->elip[ipp]+1, ipp+1); |
abort(); |
} |
//vector_tensor (sig,sigt,Mm->ip[ipp].ssst,stress); |
give_full_vector (sigt, sig, Mm->ip[ipp].ssst); |
// initial value of mean stress |
i1s = first_invar(sigt)/3.0; |
q(0) = bar_pc_0; |
s = Mm->givenonmechq(suction, ipp); // suction pressure s |
sr = Mm->givenonmechq(saturation_degree, ipp); // degree of saturation S_r |
//limitation of positive suction |
if(s >=0.0) |
s=0.0; |
s = fabs(s); |
q(1) = ks*s; |
// test if the initial state is elastic, if not calculate new value of inital effective preconsolidation pressure pc_0 so the OCR=1 |
if (yieldfunction(sigt, q) > err){ |
j2s = j2_stress_invar (sigt); |
bar_pc_0 = j2s/(m*m*(i1s-q(1))) + i1s; |
} |
// |
// Calculation of inital value of preconsolidation pressure for the fully saturated state pc_0 |
// |
// suction function: |
// |
// s / p_{atm} |
// f(s) = 1 + ----------------------- |
// 10.7 + 2.4(s / p_{atm}) |
// |
fs = 1.0 + (s/p_atm) / (10.7 + 2.4*(s/p_atm)); |
if (fs < 1.0) |
fs = 1.0; |
// bonding variable: |
// |
// \ksi = f(s) (1 - S_r) |
// |
ksi = (1-sr)*fs; |
// according to Gallipoli |
qq = 1.0 - c1_tilde*(1.0 - exp(c2*ksi)); // e/e_s |
a = (qq - 1.0)/(lambda*qq - kappa)*(v_lambda1 - 1.0); |
b = (lambda - kappa)/(lambda*qq - kappa); |
pc_0 = -pow(-bar_pc_0 /exp(a), 1.0/b); |
// compute initial value of specific volume |
v_pc0 = v_lambda1 - lambda*log(pc_0/p1); |
// actual value of p_c = initial effective preconsolidtaion pressure |
Mm->ip[ipp].other[ido+ncompstr+1] = Mm->ip[ipp].eqother[ido+ncompstr+1] = bar_pc_0; |
Mm->ip[ipp].other[ido+ncompstr+2] = Mm->ip[ipp].eqother[ido+ncompstr+2] = q(1); |
// initial value of specific volume under small pressure p_1 on the swelling line (v_{\kappa l}) at the fully saturated state |
Mm->ip[ipp].other[ido+ncompstr+3] = Mm->ip[ipp].eqother[ido+ncompstr+3] = v_kappa1 = v_pc0 + kappa*log(pc_0/p1); |
// specific volume for intial stress state |
Mm->ip[ipp].other[ido+ncompstr+4] = Mm->ip[ipp].eqother[ido+ncompstr+4] = v_ini = v_pc0 + kappa*log(pc_0/i1s); |
// intial mean stress |
Mm->ip[ipp].other[ido+ncompstr+5] = Mm->ip[ipp].eqother[ido+ncompstr+5] = i1s; |
// saturation degree |
Mm->ip[ipp].other[ido+ncompstr+9] = Mm->ip[ipp].eqother[ido+ncompstr+9] = Mm->givenonmechq(saturation_degree, ipp); // degree of saturation S_r |
// initial depsv_dt |
Mm->ip[ipp].other[ido+ncompstr+10] = Mm->ip[ipp].eqother[ido+ncompstr+10] = 0.0; |
// porosity n for intial stress state |
Mm->ip[ipp].other[ido+ncompstr+11] = Mm->ip[ipp].eqother[ido+ncompstr+11] = (v_ini-1.0)/v_ini; // v_ini = 1.0 + e_ini |
// suction |
Mm->ip[ipp].other[ido+ncompstr+12] = Mm->ip[ipp].eqother[ido+ncompstr+12] = Mm->givenonmechq(suction, ipp); // suction |
} |
// set inital value of Young's modulus |
long idem = Mm->ip[ipp].gemid(); |
long ncompo = Mm->givencompeqother(ipp, im); |
double e_ini = Mm->give_initial_ym(ipp, idem, ido+ncompo); |
Mm->ip[ipp].other[ido+ncompstr+13] = Mm->ip[ipp].eqother[ido+ncompstr+13] = e_ini; |
// time step scaling factor |
Mm->ip[ipp].other[ido+ncompstr+14] = Mm->ip[ipp].eqother[ido+ncompstr+14] = 1.0; |
// set inital stiffness matrix |
matrix d; |
makerefm(d, Mm->ip[ipp].other+ido+ncompstr+15, ncompstr, ncompstr); |
Mm->elmatstiff(d, ipp, ido); |
copym(d, Mm->ip[ipp].eqother+ido+ncompstr+15); |
check_math_errel(Mm->elip[ipp]); |
//set of effective mean stress of previous time step |
Mm->ip[ipp].other[ido+ncompstr+15+ncompstr*ncompstr] = Mm->ip[ipp].eqother[ido+ncompstr+15+ncompstr*ncompstr] = i1s; |
return; |
} |
/** |
This function computes the value of yield functions. |
@param sig - full stress tensor in Voigt notation (6 components) |
@param q - %vector of hardening parameter |
@retval The function returns value of yield function for the given stress tensor |
25.3.2002 |
*/ |
double dsmmat::yieldfunction (vector &sig, vector &q) |
{ |
double i1s,j2s,f; |
i1s = first_invar (sig)/3.0; |
j2s = j2_stress_invar (sig); |
f = j2s/(m*m) + (i1s - q[1]) * (i1s - q[0]); |
return f; |
} |
/** |
This function computes derivatives of as-th yield function |
with respect of vector sigma. |
@param sig - stress tensor in Voigt notation (6 components) |
@param q - %vector of the hardening parameter |
@param dfds - %vector where the resulting derivatives are stored (6 components) |
4.1.2002 |
*/ |
void dsmmat::deryieldfsigma (vector &sig, vector &q, vector &dfds) |
{ |
double volume,i1s; |
i1s = first_invar (sig)/3.0; |
deviator (sig,dfds); |
// q[0] = \bar{p}_c |
// q[1] = p_s = k * s |
cmulv(1.0/(m*m), dfds); |
volume=1.0/3.0*(2.0*i1s - q[0] - q[1]); |
dfds(0) += volume; |
dfds(1) += volume; |
dfds(2) += volume; |
dfds(3) *= 2.0; |
dfds(4) *= 2.0; |
dfds(5) *= 2.0; |
} |
/** |
The function computes the second derivatives of yield function |
with respect of stress tensor sigma. |
@param ddfds - tensor of the 4-th order where the are derivatives stored |
19.12.2002 |
*/ |
void dsmmat::dderyieldfsigma (matrix &ddfds) |
{ |
fillm(0.0, ddfds); |
ddfds[0][0] = ddfds[1][1] = ddfds[2][2] = 2.0/(3.0*m*m) + 2.0/9.0; |
ddfds[0][1] = ddfds[0][2] = ddfds[1][0] = ddfds[1][2] = -1.0/(3.0*m*m) + 2.0/9.0; |
ddfds[2][0] = ddfds[2][1] = ddfds[0][1]; |
// doubled shear components due to tensor-> vector transformation |
ddfds[3][3] = 2.0/(m*m); |
ddfds[4][4] = 2.0/(m*m); |
ddfds[5][5] = 2.0/(m*m); |
} |
/** |
The function computes derivatives of plastic potential function |
with respect of vector sigma. |
@param sig - stress tensor |
@param q - %vector of the hardening parameters |
@param ddgds - %matrix where the resulting derivatives are stored |
*/ |
void dsmmat::derpotsigma (vector &sig, vector &q, vector &ddgds) |
{ |
deryieldfsigma (sig, q, ddgds); |
} |
/** |
This function computes derivatives of as-th yield function |
with respect of vector of hradening parameters. |
@param sig - stress tensor |
@param q - %vector of the hardening parameters |
@param dfds - %vector where the resulting derivatives are stored |
4.1.2002 |
*/ |
void dsmmat::deryieldfq(vector &sig, vector &q, vector &dfq) |
{ |
// df |
// ---------- = dfq[0] |
// d\bar{p}_c |
dfq[0] = -first_invar (sig)/3.0 + q[1]; |
// df |
// --- = dfq[1] |
// p_s |
dfq[1] = -first_invar (sig)/3.0 + q[0]; |
return; |
} |
/** |
The function computes the second derivatives of yield function |
with respect to hradening parameters. |
@param ddfdq - %matrix, where the resulting derivatives are stored |
Created by Tomas Koudelka, 09.2012 |
*/ |
void dsmmat::deryieldfdqdq(matrix &ddfdq) |
{ |
ddfdq[0][0] = 0.0; |
ddfdq[0][1] = 1.0; |
ddfdq[1][0] = 1.0; |
ddfdq[1][1] = 0.0; |
return; |
} |
/** |
The function computes the second derivatives of yield function |
with respect to stresses. |
@param dfds - tensor, where the resulting derivatives are stored. |
size of dfds = (6,number_of_hardening_param) |
Created by Tomas Koudelka, 09.2012 |
*/ |
void dsmmat::deryieldfdsdq(matrix &dfdsdqt) |
{ |
dfdsdqt[0][0] = dfdsdqt[1][0] = dfdsdqt[2][0] = -1.0/3.0; |
dfdsdqt[0][1] = dfdsdqt[1][1] = dfdsdqt[2][1] = -1.0/3.0; |
return; |
} |
/** |
The function computes derivatives of hardening paramters |
with respect of consistency parameter gamma. |
@param ipp - integration point number |
@param ido - index of internal variables for given material in the ipp other array |
@param sig - full stress tensor |
@param qtr - %vector of hardening variables |
@param epsp - %vector of attained plastic strains |
@param dqdg - %vector where the resulting derivatives are stored in Voigt notation |
Created by Tomas Koudelka, 09.2012 |
*/ |
void dsmmat::der_q_gamma(long ipp, long ido, vector &sig, vector &qtr, vector &epsp, vector &dqdg) |
{ |
double v_ini, v_lambda1, v_kappa1, p1, i1s, epsvp; |
double p_atm = 101325.0; |
double s, sr, fs, b, c, c1, ksi; |
long ncompstr = Mm->ip[ipp].ncompstr; |
strastrestate ssst = Mm->ip[ipp].ssst; |
vector epst(ASTCKVEC(6)); |
// mean stress |
i1s = first_invar (sig)/3.0; |
// initial value of specific volume under small pressure p_1 for the normal consolidation line (v_{\lambda 1} = N) |
v_lambda1 = Mm->ic[ipp][0]; |
// initial reference presure |
p1 = Mm->ic[ipp][1]; |
// initial value of specific volume under small pressure p_1 for the swelling line (v_{\kappa 1}) |
v_kappa1 = Mm->ip[ipp].eqother[ido+ncompstr+3]; |
// specific volume for intial stress state |
v_ini = Mm->ip[ipp].eqother[ido+ncompstr+4]; |
s = Mm->givenonmechq(suction, ipp); // suction pressure s |
//limitation of positive suction |
if(s >=0.0) |
s=0.0; |
s = fabs(s); |
sr = Mm->givenonmechq(saturation_degree, ipp); // degree of saturation S_r |
// actual value of preconsolidation pressure for the fully saturated state |
give_full_vector (epst, epsp, ssst); |
epsvp = first_invar(epst); |
//double pc_new = p1 * exp((v_kappa1 - v_lambda1 + v_ini*epsvp)/(kappa-lambda)); |
// specific volume for the actual preconsolidation pressure: |
// |
// v_{pc} = v_{\lambda1} - \lambda \ln(p_c/p_1) |
// double v_pc = v_lambda1 - lambda * log(pc_new/p1); |
// suction function: |
// |
// s / p_{atm} |
// f(s) = 1 + ----------------------- |
// 10.7 + 2.4(s / p_{atm}) |
// |
fs = 1.0 + (s/p_atm) / (10.7 + 2.4*(s/p_atm)); |
if (fs < 1.0) |
fs = 1.0; |
// bonding variable: |
// |
// \ksi = f(s) (1 - S_r) |
// |
ksi = (1-sr)*fs; |
// \tilde{c}_1 |
// c_1 = -------------------- |
// 1 |
// -------------- + 1 |
// v_{pc}-1 |
// c1 = c1_tilde/(1.0/(v_pc-1.0)+1.0); // according to Borja |
c1 = c1_tilde; // according to Gallipoli |
// |
// c(\ksi) = 1 - c_1 [1-\exp(c_2 \ksi)] |
// |
c = 1.0 - c1*(1.0-exp(c2*ksi)); |
// |
// \lambda - \kappa |
// b(\ksi) = -------------------------- |
// \lambda c(\ksi) - \kappa |
// |
b = (lambda - kappa)/(lambda*c - kappa); |
// q[0] = \bar{p}_c = -\exp[a(\ksi)] (-p_c)^{b(\ksi)} |
// |
// p_c = p_1 exp[(v_{\kappa_1} - v_{\lambda_1} + eps_{vp} v_{ini})/(\kappa - \lambda)] |
// |
// p_1 = const |
// p_{c0} = const |
// \sigma_{m0} = const |
// v_{\kappa_1} = const |
// v_{p_{c0}} = v_{\kappa_1} - \kappa \ln(p_{c0}/p_1) = const |
// v_{ini} = v_{p_{c0}} + \kappa \ln(p_{c0}/\sigma_{m0}) = const |
// v_{\lambda_1} = v_{p_{c0}} - \lambda \ln(p_{c0}/p_1) = const |
// |
// d \bar{p}_c d p_c (-p_c)^{b(\ksi)} d p_c |
// ----------- = -\exp[a(\ksi)] b(\ksi)(-p_c)^{b(\ksi)-1} ---------- = -\exp[a(\ksi)] b(\ksi) ---------------- ---------- , |
// d \gamma d \gamma p_c d \gamma |
// |
// d p_c v_ini |
// ---------- = p_c ----------------- (2p - \bar{p}_c - p_s), |
// d \gamma \kappa - \lambda |
// |
// d \bar{p}_c b(\ksi) v_ini |
// ----------- = -\bar{p}_c ---------------- (2p - \bar{p}_c - p_s) |
// d \gamma \kappa - \lambda |
// |
// |
dqdg[0] = -qtr[0] * (b*v_ini)/(kappa-lambda) * (2.0*i1s-qtr[0]-qtr[1]); |
// q[1] = p_s = k*s |
// |
// d p_s |
// ----------- = 0.0 because p_s is constant for the given strain level |
// d \gamma |
// |
dqdg[1] = 0.0; |
return; |
} |
/** |
The function computes derivatives of hardening paramters |
with respect of consistency parameter gamma. |
@param ipp - integration point number |
@param ido - index of internal variables for given material in the ipp other array |
@param sig - full stress tensor |
@param qtr - %vector of hardening variables |
@param epsp - %vector of attained plastic strains |
@param dqdgds - %matrix where the resulting derivatives are stored in Voigt notation, |
its dimensions must be qtr.n x 6 |
Created by Tomas Koudelka, 05.2022 |
*/ |
void dsmmat::dqpardgammadsigma(long ipp, long ido, vector &sig, vector &qtr, vector &epsp, matrix &dqdgds) |
{ |
double v_ini, v_lambda1, v_kappa1, p1, i1s, epsvp; |
double p_atm = 101325.0; |
double s, sr, fs, b, c, c1, ksi; |
long ncompstr = Mm->ip[ipp].ncompstr; |
strastrestate ssst = Mm->ip[ipp].ssst; |
vector epst(ASTCKVEC(6)); |
// mean stress |
i1s = first_invar (sig)/3.0; |
// initial value of specific volume under small pressure p_1 for the normal consolidation line (v_{\lambda 1} = N) |
v_lambda1 = Mm->ic[ipp][0]; |
// initial reference presure |
p1 = Mm->ic[ipp][1]; |
// initial value of specific volume under small pressure p_1 for the swelling line (v_{\kappa 1}) |
v_kappa1 = Mm->ip[ipp].eqother[ido+ncompstr+3]; |
// specific volume for intial stress state |
v_ini = Mm->ip[ipp].eqother[ido+ncompstr+4]; |
s = Mm->givenonmechq(suction, ipp); // suction pressure s |
//limitation of positive suction |
if(s >=0.0) |
s=0.0; |
s = fabs(s); |
sr = Mm->givenonmechq(saturation_degree, ipp); // degree of saturation S_r |
// actual value of preconsolidation pressure for the fully saturated state |
give_full_vector (epst, epsp, ssst); |
epsvp = first_invar(epst); |
//double pc_new = p1 * exp((v_kappa1 - v_lambda1 + v_ini*epsvp)/(kappa-lambda)); |
// specific volume for the actual preconsolidation pressure: |
// |
// v_{pc} = v_{\lambda1} - \lambda \ln(p_c/p_1) |
//double v_pc = v_lambda1 - lambda * log(pc_new/p1); |
// suction function: |
// |
// s / p_{atm} |
// f(s) = 1 + ----------------------- |
// 10.7 + 2.4(s / p_{atm}) |
// |
fs = 1.0 + (s/p_atm) / (10.7 + 2.4*(s/p_atm)); |
if (fs < 1.0) |
fs = 1.0; |
// bonding variable: |
// |
// \ksi = f(s) (1 - S_r) |
// |
ksi = (1-sr)*fs; |
// \tilde{c}_1 |
// c_1 = -------------------- |
// 1 |
// -------------- + 1 |
// v_{pc}-1 |
// c1 = c1_tilde/(1.0/(v_pc-1.0)+1.0); // according to Borja |
c1 = c1_tilde; // according to Gallipoli |
// |
// c(\ksi) = 1 - c_1 [1-\exp(c_2 \ksi)] |
// |
c = 1.0 - c1*(1.0-exp(c2*ksi)); |
// |
// \lambda - \kappa |
// b(\ksi) = -------------------------- |
// \lambda c(\ksi) - \kappa |
// |
b = (lambda - kappa)/(lambda*c - kappa); |
// q[0] = \bar{p}_c = -\exp[a(\ksi)] (-p_c)^{b(\ksi)} |
// |
// p_c = p_1 exp[(v_{\kappa_1} - v_{\lambda_1} + eps_{vp} v_{ini})/(\kappa - \lambda)] |
// |
// p_1 = const |
// p_{c0} = const |
// \sigma_{m0} = const |
// v_{\kappa_1} = const |
// v_{p_{c0}} = v_{\kappa_1} - \kappa \ln(p_{c0}/p_1) = const |
// v_{ini} = v_{p_{c0}} + \kappa \ln(p_{c0}/\sigma_{m0}) = const |
// v_{\lambda_1} = v_{p_{c0}} - \lambda \ln(p_{c0}/p_1) = const |
// |
// d \bar{p}_c d p_c (-p_c)^{b(\ksi)} d p_c |
// ----------- = -\exp[a(\ksi)] b(\ksi)(-p_c)^{b(\ksi)-1} ---------- = -\exp[a(\ksi)] b(\ksi) ---------------- ---------- , |
// d \gamma d \gamma p_c d \gamma |
// |
// d p_c v_ini |
// ---------- = p_c ----------------- (2p - \bar{p}_c - p_s), |
// d \gamma \kappa - \lambda |
// |
// d \bar{p}_c b(\ksi) v_ini |
// ----------- = -\bar{p}_c ---------------- (2p - \bar{p}_c - p_s) |
// d \gamma \kappa - \lambda |
// |
// |
// dqdg(0) = -qtr[0] * (b*v_ini)/(kappa-lambda) * (2.0*i1s-qtr[0]-qtr[1]); |
dqdgds(0,0) = dqdgds(0,1) = dqdgds(0,2) = -qtr[0] * (b*v_ini)/(kappa-lambda) * 2.0/3.0; |
// q[1] = p_s = k*s |
// |
// d p_s |
// ----------- = 0.0 because p_s is constant for the given strain level |
// d \gamma |
// |
dqdgds(1,0) = dqdgds(1,1) = dqdgds(1,2) = dqdgds(1,3) = dqdgds(1,4) = dqdgds(1,5) = 0.0; |
return; |
} |
/** |
The function computes derivatives of hardening paramters |
with respect of consistency parameter gamma. |
@param ipp - integration point number |
@param ido - index of internal variables for given material in the ipp other array |
@param sig - full stress tensor |
@param qtr - %vector of hardening variables |
@param epsp - %vector of attained plastic strains |
@param dqdgds - %matrix where the resulting derivatives are stored, its dimensions must be qtr.n x qtr.n |
Created by Tomas Koudelka, 05.2022 |
*/ |
void dsmmat::dqpardgammadqpar(long ipp, long ido, vector &sig, vector &qtr, vector &epsp, matrix &dqdgdq) |
{ |
double v_ini, v_lambda1, v_kappa1, p1, i1s, epsvp; |
double p_atm = 101325.0; |
double s, sr, fs, b, c, c1, ksi; |
long ncompstr = Mm->ip[ipp].ncompstr; |
strastrestate ssst = Mm->ip[ipp].ssst; |
vector epst(ASTCKVEC(6)); |
// mean stress |
i1s = first_invar (sig)/3.0; |
// initial value of specific volume under small pressure p_1 for the normal consolidation line (v_{\lambda 1} = N) |
v_lambda1 = Mm->ic[ipp][0]; |
// initial reference presure |
p1 = Mm->ic[ipp][1]; |
// initial value of specific volume under small pressure p_1 for the swelling line (v_{\kappa 1}) |
v_kappa1 = Mm->ip[ipp].eqother[ido+ncompstr+3]; |
// specific volume for intial stress state |
v_ini = Mm->ip[ipp].eqother[ido+ncompstr+4]; |
s = Mm->givenonmechq(suction, ipp); // suction pressure s |
//limitation of positive suction |
if(s >=0.0) |
s=0.0; |
s = fabs(s); |
sr = Mm->givenonmechq(saturation_degree, ipp); // degree of saturation S_r |
// actual value of preconsolidation pressure for the fully saturated state |
give_full_vector (epst, epsp, ssst); |
epsvp = first_invar(epst); |
//double pc_new = p1 * exp((v_kappa1 - v_lambda1 + v_ini*epsvp)/(kappa-lambda)); |
// specific volume for the actual preconsolidation pressure: |
// |
// v_{pc} = v_{\lambda1} - \lambda \ln(p_c/p_1) |
//double v_pc = v_lambda1 - lambda * log(pc_new/p1); |
// suction function: |
// |
// s / p_{atm} |
// f(s) = 1 + ----------------------- |
// 10.7 + 2.4(s / p_{atm}) |
// |
fs = 1.0 + (s/p_atm) / (10.7 + 2.4*(s/p_atm)); |
if (fs < 1.0) |
fs = 1.0; |
// bonding variable: |
// |
// \ksi = f(s) (1 - S_r) |
// |
ksi = (1-sr)*fs; |
// \tilde{c}_1 |
// c_1 = -------------------- |
// 1 |
// -------------- + 1 |
// v_{pc}-1 |
// c1 = c1_tilde/(1.0/(v_pc-1.0)+1.0); // according to Borja |
c1 = c1_tilde; // according to Gallipoli |
// |
// c(\ksi) = 1 - c_1 [1-\exp(c_2 \ksi)] |
// |
c = 1.0 - c1*(1.0-exp(c2*ksi)); |
// |
// \lambda - \kappa |
// b(\ksi) = -------------------------- |
// \lambda c(\ksi) - \kappa |
// |
b = (lambda - kappa)/(lambda*c - kappa); |
// q[0] = \bar{p}_c = -\exp[a(\ksi)] (-p_c)^{b(\ksi)} |
// |
// p_c = p_1 exp[(v_{\kappa_1} - v_{\lambda_1} + eps_{vp} v_{ini})/(\kappa - \lambda)] |
// |
// p_1 = const |
// p_{c0} = const |
// \sigma_{m0} = const |
// v_{\kappa_1} = const |
// v_{p_{c0}} = v_{\kappa_1} - \kappa \ln(p_{c0}/p_1) = const |
// v_{ini} = v_{p_{c0}} + \kappa \ln(p_{c0}/\sigma_{m0}) = const |
// v_{\lambda_1} = v_{p_{c0}} - \lambda \ln(p_{c0}/p_1) = const |
// |
// d \bar{p}_c d p_c (-p_c)^{b(\ksi)} d p_c |
// ----------- = -\exp[a(\ksi)] b(\ksi)(-p_c)^{b(\ksi)-1} ---------- = -\exp[a(\ksi)] b(\ksi) ---------------- ---------- , |
// d \gamma d \gamma p_c d \gamma |
// |
// d p_c v_ini |
// ---------- = p_c ----------------- (2p - \bar{p}_c - p_s), |
// d \gamma \kappa - \lambda |
// |
// d \bar{p}_c b(\ksi) v_ini |
// ----------- = -\bar{p}_c ---------------- (2p - \bar{p}_c - p_s) |
// d \gamma \kappa - \lambda |
// |
// |
// dqdg(0) = -qtr[0] * (b*v_ini)/(kappa-lambda) * (2.0*i1s-qtr[0]-qtr[1]); |
// wrong //dqdgdq(0,0) = 2.0*qtr[0] * (b*v_ini)/(kappa-lambda); |
dqdgdq(0,0) = -(b*v_ini)/(kappa-lambda) * (2.0*i1s-2.0*qtr[0]-qtr[1]); |
dqdgdq(0,1) = qtr[0] * (b*v_ini)/(kappa-lambda); |
// q[1] = p_s = k*s |
// |
// d p_s |
// ----------- = 0.0 because p_s is constant for the given strain level |
// d \gamma |
// |
dqdgdq(1,0) = dqdgdq(1,1) = 0.0; |
return; |
} |
/** |
This function computes plastic modulus. |
@param ipp - integration point number |
@param ido - index of internal variables for given material in the ipp other array |
@param sig - stress tensor in Voigt notation |
@param qtr - %vector of hardening parameters |
@param epsp - %vector of attained plastic strains |
@retval The function returns value of the plastic modulus. |
Created by Tomas Koudelka, 09.2012 |
*/ |
double dsmmat::plasmodscalar(long ipp, long ido, vector &sig, vector &qtr, vector &epsp) |
{ |
double ret; |
vector dfq(ASTCKVEC(2)); |
vector dqg(ASTCKVEC(2)); |
deryieldfq(sig, qtr, dfq); |
der_q_gamma(ipp, ido, sig, qtr, epsp, dqg); |
scprd(dfq, dqg, ret); |
return -ret; |
} |
/** |
This function computes new value of the hardening parameter q. |
@param ipp - integration point pointer |
@param ido - index of internal variables for given material in the ipp other array |
@param eps - %vector of the attained strains in Voigt notation |
@param epsp - %vector of the attained plastic strains in Voigt notation |
@param sig - attained stress tensor in Voigt notation |
@param ssst - stress/strain state parameter (for the used vector_tensor function) |
@param q - %vector of the hardening parameters |
Created by Tomas Koudelka, 09.2012 |
*/ |
void dsmmat::updateq(long ipp, long ido, vector &eps, vector &epsp, vector &sig, vector &q) |
{ |
vector epst(ASTCKVEC(6)); |
vector depsp(epsp.n); |
double v_kappa1, v_lambda1, p1, depsvp, v_ini, pc_new; |
double v_pc, p_atm = 101325.0; |
double s, sr, fs, a, b, c, c1, ksi; |
strastrestate ssst = Mm->ip[ipp].ssst; |
long ncompstr = Mm->ip[ipp].ncompstr; |
long i; |
// initial value of specific volume under small pressure p_1 for the normal consolidation line (v_lambda1 = 1+N) |
v_lambda1 = Mm->ic[ipp][0]; |
// initial reference presure |
p1 = Mm->ic[ipp][1]; |
// original specific volume before any loading |
v_kappa1 = Mm->ip[ipp].eqother[ido+ncompstr+3]; |
// specific volume for intial stress state |
v_ini = Mm->ip[ipp].eqother[ido+ncompstr+4]; |
// Original version of pc calculation - problems with tension |
// vk = v_ini*(1+epsv)+kappa*log(i1s/p1); |
// pc_new = p1 * exp((vk-v_lambda1)/(kappa-lambda)); |
// |
// Alternative version of pc calculation - 'less' accurate in benchmarks |
// pc_new = p1 * exp((v_kappa1 - v_lambda1 + v_ini*epsv)/(kappa-lambda)); |
// vk = v_ini*(1+epsv)+kappa*log(i1s/p1); |
for (i=0; i<ncompstr; i++) |
depsp[i] = epsp[i];// + Mm->ic[ipp][3+i]; |
give_full_vector(epst, depsp, ssst); |
depsvp = first_invar(epst); |
pc_new = p1 * exp((v_kappa1 - v_lambda1 + v_ini*depsvp)/(kappa-lambda)); |
// For the partially saturated soil, |
// the effective preconsolidation pressure \bar{p}_c is related to the saturated |
// preconsolidation pressure p_c according to bonding variable \ksi |
// |
// \bar{p}_c = -exp[a(\ksi)] (-p_c)^{b(\ksi)} |
// |
// |
// specific volume for the actual preconsolidation pressure: |
// |
// v_{pc} = v_{\lambda1} - \lambda \ln(p_c/p_1) |
v_pc = v_lambda1 - lambda * log(pc_new/p1); |
s = Mm->givenonmechq(suction, ipp); // suction pressure s |
//limitation of positive suction |
if(s >=0.0) |
s=0.0; |
s = fabs(s); |
sr = Mm->givenonmechq(saturation_degree, ipp); // degree of saturation S_r |
// suction function: |
// |
// s / p_{atm} |
// f(s) = 1 + ----------------------- |
// 10.7 + 2.4(s / p_{atm}) |
// |
fs = 1.0 + (s/p_atm) / (10.7 + 2.4*(s/p_atm)); |
if (fs < 1.0) |
fs = 1.0; |
// bonding variable: |
// |
// \ksi = f(s) (1 - S_r) |
// |
ksi = (1-sr)*fs; |
// \tilde{c}_1 |
// c_1 = -------------------- |
// 1 |
// -------------- + 1 |
// v_{pc}-1 |
// c1 = c1_tilde/(1.0/(v_pc-1.0)+1.0); // according to Borja |
c1 = c1_tilde; // according to Gallipoli |
// |
// c(\ksi) = 1 - c_1 [1-\exp(c_2 \ksi)] |
// |
c = 1.0 - c1*(1.0-exp(c2*ksi)); |
// |
// a(\ksi) = v_{lambda_1} [c(\ksi)-1]/[\lambda c(\ksi) - \kappa) |
// |
a = (v_lambda1 - 1.0)*(c - 1.0)/(lambda*c - kappa); |
// |
// \lambda - \kappa |
// b(\ksi) = -------------------------- |
// \lambda c(\ksi) - \kappa |
// |
b = (lambda - kappa)/(lambda*c - kappa); |
// |
// effective preconsolidation pressure: |
// |
// q[0] = \bar{p}_c = -exp[a(\ksi)] (-p_c)^{b(\ksi)} |
// |
q[0] = -exp(a)*pow(-pc_new, b); |
// apparent adhesion due to suction |
// (right intersection of the yield surface with p axis): |
// |
// q[1] = p_s = k s |
// |
q[1] = ks * s; |
return; |
} |
/** |
This function computes material stiffnes matrix. |
@param d - allocated matrix structure for material stiffness %matrix in the reduced format |
@param ipp - integration point number |
@param ido - index of internal variables for given material in the ipp other array |
Created by Tomas Koudelka, 09.2012 |
*/ |
void dsmmat::matstiff (matrix &d, long ipp, long ido) |
{ |
double zero=1.0e-20; |
switch (Mp->nlman->stmat){ |
case initial_stiff: |
// initial elastic matrix |
Mm->elmatstiff(d, ipp, ido); |
break; |
case tangent_stiff: |
case secant_stiff: |
case incr_tangent_stiff: |
case ijth_tangent_stiff:{ |
// consistent tangent stiffness matrix |
long n = Mm->ip[ipp].ncompstr; |
if (sra.give_tsra() == cp){ |
// algorithmic consistent stiffness matrix for the cutting plane algorithm is computed in the course of stress return |
if (d.m != n){ // material stiffness matrix used for element in the case of plane stress/strain states |
for(long i=0; i<d.m; i++) // copy just the first d.n(=3) components at all matrix rows |
memcpy(&d(i,0), Mm->ip[ipp].other+ido+n+15+n*i, d.n*sizeof(*Mm->ip[ipp].other)); |
} |
else{ // dimensions of material stiffness matrix matches the ones for element material stiffness matrix |
matrix auxm; |
makerefm(auxm, Mm->ip[ipp].other+ido+n+15, n, n); |
copym(auxm, d); |
} |
} |
else{ |
// compute algorithmic stiffness matrix for closest point projection stress return algorithm |
matrix de(ASTCKMAT(6, 6)), ddfdst(ASTCKMAT(6,6)); |
matrix e(ASTCKMAT(6, 6)), auxd(ASTCKMAT(6,6)), tmp(ASTCKMAT(6, 6)); |
double gamma = Mm->ip[ipp].other[ido+n]; |
identm(e); |
Mm->elmatstiff(de, ipp, spacestress); |
dderyieldfsigma(ddfdst); |
cmulm(gamma, de, auxd); |
mxm(auxd, ddfdst, tmp); |
addm(e, tmp, auxd); |
invm(auxd, tmp, zero); |
mxm(tmp, de, auxd); |
// matrix representation of the fourth order tensor |
tensor4_ematrix(d, auxd, Mm->ip[ipp].ssst); |
} |
break; |
} |
} |
} |
/** |
This function computes elasto-plastic material stiffnes matrix. |
@param d - allocated matrix structure for material stiffness %matrix in the reduced format |
@param ipp - integration point number |
@param ido - index of internal variables for given material in the ipp other array |
Created by Tomas Koudelka, 09.2012 |
*/ |
void dsmmat::depmatstiff (matrix &d, long ipp, long ido) |
{ |
switch (Mp->nlman->stmat){ |
case initial_stiff: |
// initial elastic matrix |
Mm->elmatstiff(d, ipp, ido); |
break; |
case tangent_stiff: |
case secant_stiff: |
case incr_tangent_stiff: |
case ijth_tangent_stiff:{ |
// consitent tangent stiffness matrix |
long n = Mm->ip[ipp].ncompstr; |
long ncompq = 2; |
matrix de(ASTCKMAT(n, n)), auxm; |
vector sig(ASTCKVEC(n)), q(ASTCKVEC(ncompq)), epsp(ASTCKVEC(n)); |
vector dfds(ASTCKVEC(n)), dgds(ASTCKVEC(n)); |
vector sigt(ASTCKVEC(6)), dfdst(ASTCKVEC(6)), dgdst(ASTCKVEC(6)); |
vector dedgds(ASTCKVEC(n)), dedfds(ASTCKVEC(n)); |
strastrestate ssst = Mm->ip[ipp].ssst; |
double denomh, denomd, denom, gamma, f, err=sra.give_err(); |
// prepare actual values of needed quantities |
copyv(Mm->ip[ipp].stress, sig); // stresses |
copyv(Mm->ip[ipp].other+ido, epsp); // plastic strains |
gamma = Mm->ip[ipp].other[ido+n+0]; // cumulated plastic multiplier |
q(0) = Mm->ip[ipp].other[ido+n+1]; // hardening parameter \bar{p}_c |
q(1) = Mm->ip[ipp].other[ido+n+2]; // hardening parameter k_s |
give_full_vector(sigt, sig, ssst); // 6 component vector of stresses |
// check actual stress state: f <= 0.0 |
f = yieldfunction(sigt, q); |
if ((f < -err) || (gamma == 0.0 && (f < err))){ |
// stress state is in the elastic domain, |
// i.e. material has been subjected by elastic loading/unloading -> |
// -> return actual elastic stiffness matrix |
Mm->elmatstiff(d, ipp, ssst); |
return; |
} |
// stress state is on/close to the yield surface |
// material has been subjected by plastic loading -> |
// compute elasto-plastic matrix |
// D_e \frac{dg}{d\sigma} (\frac{df}{d\sigma})^T D_e |
// D_{ep} = D_e - --------------------------------------------------- |
// (\frac{df}{d\sigma})^T D_e \frac{dg}{d\sigma} + H |
// |
// H = -\frac{df}{dq} \frac{dq}{d\lambda} |
Mm->elmatstiff(de, ipp, ssst); |
deryieldfsigma(sigt, q, dfdst); |
derpotsigma(sigt, q, dgdst); |
// conversion of full tensor notation to vector notation |
give_red_vector(dfdst, dfds, ssst); |
// conversion of full tensor notation to vector notation |
give_red_vector(dgdst, dgds, ssst); |
mxv(de,dgds,dedgds); |
mxv(de,dfds,dedfds); |
denomh = plasmodscalar(ipp, ido, sig, q, epsp); |
scprd(dfds, dedgds, denomd); |
// preserve minimum stiffness for perfect plastic material, i.e. if the hardening modulus is 'close' to zero (H->0) |
// if (fabs(denomh/denomd) < 1.0e-3) |
// denomh = sgn(denomh)*1.0e-3*denomd; |
denom = denomd+denomh; |
if (n == d.m){ |
// material stiffness matrix has identical dimensions with the ones of stiffness matrix used in |
// assembling of element stiffness matrix on finite element -> auxm will be reference on matrix d |
makerefm(auxm, d.a, d.m, d.n); |
nullm(auxm); |
} |
else{ |
// material stiffness matrix has different dimensions than the stiffness matrix used in |
// assembling of element stiffness matrix on finite element -> auxm will be reference on matrix d |
reallocm(RSTCKMAT(n, n, auxm)); |
} |
// calculate matrix in the nominator |
vxv(dedgds, dedfds, auxm); |
// scaling by the denominator |
cmulm(1.0/denom, auxm); |
// resulting material stiffness matrix |
subm(de, auxm, auxm); |
// resulting material stiffness matrix with dimensions adjusted for finite element computation |
if (n != d.m){ |
// resulting material stiffness matrix dimensions must be adjusted for finite element computation |
extractblock(auxm, d, 0, 0); |
} |
else{ |
// nothing is needed, matrix auxm is direct reference to the matrix in argument d |
// hence d contains resulting material stiffness matrix with appropriate dimensions for |
// the stiffness matrix on the finite element |
} |
/* |
double zero=1.0e-20; |
matrix de(ASTCKMAT(6, 6)), ddfdst(ASTCKMAT(6,6)); |
matrix e(ASTCKMAT(6, 6)), auxd(ASTCKMAT(6,6)), tmp(ASTCKMAT(6, 6)); |
long n = Mm->ip[ipp].ncompstr; |
double gamma = Mm->ip[ipp].other[ido+n]; |
identm(e); |
Mm->elmatstiff(de, ipp, spacestress); |
dderyieldfsigma(ddfdst); |
cmulm(gamma, de, auxd); |
mxm(auxd, ddfdst, tmp); |
addm(e, tmp, auxd); |
invm(auxd, tmp, zero); |
mxm(tmp, de, auxd); |
// matrix representation of the fourth order tensor |
tensor4_ematrix(d, auxd, Mm->ip[ipp].ssst);*/ |
break; |
} |
} |
} |
/** |
The function computes stress increments due to suction and temperature changes in the integration point and stores |
them into eqother array. |
@param ipp - integration point pointer |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
@return The function does not return anything but stores the resulting values in the eqother array. |
Created by Tomas krejci, 03/2023 |
*/ |
void dsmmat::nlstressesincr (long ipp, long im, long ido) |
// |
{ |
double sigm_eff_prev,sigm_eff,dsigm_eff,em,km,depsvm,p0,f_beta,depss; |
long i,ncomp; |
// stress/strain state |
strastrestate ss = Mm->ip[ipp].ssst; |
ncomp=Mm->ip[ipp].ncompstr; |
matrix d(ASTCKMAT(ncomp,ncomp)); |
vector depsv(ASTCKVEC(ncomp)),sig(ASTCKVEC(ncomp)),dsigma(ASTCKVEC(ncomp)),sigt(ASTCKVEC(6)); |
for (i=0;i<ncomp;i++) |
Mm->ip[ipp].eqother[ido+ncomp+15+ncomp*ncomp+1+i] = 0.0; |
//trial addition of microstructure effect - not completed!!! |
/* |
if (Mm->ip[ipp].tm[im-1] == effective_stress){ |
sigm_eff_prev = Mm->ip[ipp].eqother[ido+ncomp+15+ncomp*ncomp];//effective mean stress from previous time step |
sigm_eff = Mm->ip[ipp].eqother[ido+ncomp+5];//effective mean stress |
Mm->ip[ipp].other[ido+ncomp+15+ncomp*ncomp] = sigm_eff;//storing effective mean stress from previos time step |
dsigm_eff = sigm_eff - sigm_eff_prev; |
//km = exp(-am*sigm_eff)/betam; |
em = 0.35; |
km = 0.21; |
km = (1 + em)/km*fabs(sigm_eff); |
depsvm = dsigm_eff/km; |
p0 = Mm->ip[ipp].eqother[ido+ncomp+1]; // p_c (hardening parameter - effective preconsolidation pressure) |
//interaction function: |
f_beta = 0.0; |
if(dsigm_eff > 0.0){//microstructural swelling |
f_beta = 0.1 - 1.1*pow((1.0-sigm_eff/p0),2.0); |
} |
if(dsigm_eff < 0.0){//microstructural constraction |
f_beta = -0.1 + 1.1*pow((sigm_eff/p0),0.5); |
} |
depss = f_beta*depsvm; |
//only uniaxial |
if(ss==bar){ |
depsv[0]=depss; |
} |
else{ |
depsv[0]=depss; |
depsv[1]=depss; |
} |
if(ss==planestrain) depsv[3]=depss; |
if(ss==planestress) depsv[3]=depss; |
if(ss==axisymm) depsv[2]=depss; |
if(ss==spacestress) depsv[2]=depss; |
fillm(0.0,d); |
matstiff (d, ipp, ido); |
mxv (d,depsv,dsigma); |
for (i=0;i<ncomp;i++) |
Mm->ip[ipp].eqother[ido+ncomp+15+ncomp*ncomp+1+i] = dsigma(i); |
} |
*/ |
} |
/** |
The function computes stress increment due to pore pressure change in the integration point and stores |
them into ip stress array. |
@param lcid - load case id |
@param ipp - integration point number |
@param im - index of the material in the tm and idm arrays on integration point |
@param ido - index of internal variables in the ip's ipp eqother array |
@param fi - first index of the required stress increment component |
@param sig - %vector containing stress increment components (output) |
@return The function returns %vector of stress increments in the parameter sig. |
Created by Tomas Krejci, 03/2023 |
*/ |
void dsmmat::givestressincr (long lcid, long ipp, long im, long ido, long fi, vector &sig) |
{ |
nullv(sig); |
long i, j, ncomp = Mm->ip[ipp].ncompstr; |
for (i=fi,j=0; j<sig.n; i++, j++) |
sig(j) = Mm->ip[ipp].eqother[ido+ncomp+15+ncomp*ncomp+1+i]; |
} |
/** |
This function computes stresses at given integration point ipp, |
depending on the reached strains. |
The cutting plane algorithm is used. The stress and the other attribute of |
given integration point is actualized. |
@param ipp - integration point number in the mechmat ip array. |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
Created by Tomas Koudelka, 09.2012 |
*/ |
void dsmmat::nlstresses (long ipp, long im, long ido) |
// |
{ |
int errr; |
long i,ni,ncomp=Mm->ip[ipp].ncompstr, matcomp=0, ret; |
double gamma, err, pnewdt = 1.0; |
vector epsn(ASTCKVEC(ncomp)), epsp(ASTCKVEC(ncomp)), q(ASTCKVEC(2)); |
vector epsa(ASTCKVEC(ncomp)), sig(ASTCKVEC(ncomp)), dfds(ASTCKVEC(ncomp)), dgds(ASTCKVEC(ncomp)); |
matrix d; |
vector dfdst(ASTCKVEC(6)), dgdst(ASTCKVEC(6)); |
vector epst(ASTCKVEC(6)), epsnt(ASTCKVEC(6)), epspt(ASTCKVEC(6)), sigt(ASTCKVEC(6)); |
//vector dev(ASTCKVEC(6)); |
double i1s, j2s, epsv, epsvp; |
double dtime = Mp->timecon.actualforwtimeincr(); |
// stress/strain state |
//strastrestate ssst = Mm->ip[ipp].ssst; |
//double nu; |
// initial values |
for (i=0; i<ncomp; i++) |
{ |
epsn[i] = Mm->ip[ipp].strain[i]; |
epsp[i] = Mm->ip[ipp].eqother[ido+i]; |
// It is necessary to substract initial strains in order to invoke initial nonzero stress |
// state for zero displacements (i.e. zero strains) |
// sig = E*(eps - eps_p), sig_0 = E*eps_0. For eps = 0: sig = sig_0 => eps_p = -eps_0 |
// epsp[i] -= Mm->ic[ipp][3+i]; |
} |
gamma=Mm->ip[ipp].eqother[ido+ncomp]; |
q[0] = Mm->ip[ipp].eqother[ido+ncomp+1]; // effective preconsolidation pressure \bar{p}_c |
q[1] = Mm->ip[ipp].eqother[ido+ncomp+2]; // apparent adhesion p_s = k * s |
// stress return algorithm |
switch(sra.give_tsra ()) |
{ |
case cp: |
ni=sra.give_ni (); |
err=sra.give_err (); |
matcomp = actualize_stiffmat(*Mp->nlman, Mp->istep, Mp->jstep); |
if (Mp->istep >= 265){ |
matcomp = 0; |
} |
if (matcomp) reallocm(RSTCKMAT(ncomp, ncomp, d)); |
ret = Mm->cutting_plane (ipp, im, ido, gamma, epsn, epsp, q, ni, err, matcomp, d); |
if (ret) |
pnewdt = 0.5; |
break; |
case gsra: |
ni=sra.give_ni (); |
err=sra.give_err (); |
Mm->newton_stress_return (ipp, im, ido, gamma, epsn, epsp, q, ni, err); |
break; |
default: |
print_err("wrong type of stress return algorithm is required", __FILE__, __LINE__, __func__); |
abort (); |
} |
/* |
//////////////////////////////// |
// elastic material for debug?? |
// initial values |
for (i=0;i<ncomp;i++){ |
epsn[i]=epsp[i]=Mm->ip[ipp].strain[i]; |
} |
reallocm(RSTCKMAT(ncomp, ncomp, d)); |
Mm->elmatstiff (d,ipp,ssst); |
nu = 0.3; |
mxv (d,epsn,sig); |
if (Mm->ip[ipp].ssst == planestress) |
Mm->ip[ipp].strain[3] = -nu / (1.0 - nu) * (epsn[0]+epsn[1]); |
if ((Mp->eigstrains == 4) || (Mp->eigstrains == 5)) |
{ |
for (i=0;i<ncomp;i++) |
sig(i) += Mm->eigstresses[ipp][i]; |
} |
for (i=0;i<ncomp;i++){ |
Mm->ip[ipp].stress[i]=sig(i); |
} |
//////////////////////////////// |
*/ |
// new data storage |
for (i=0; i<ncomp; i++){ |
//epsp[i] += Mm->ic[ipp][3+i]; |
Mm->ip[ipp].other[ido+i]=epsp[i]; |
} |
Mm->ip[ipp].other[ido+ncomp]=gamma; |
Mm->ip[ipp].other[ido+ncomp+1]=q[0]; // the first hardening parameter \bar{p}_c |
Mm->ip[ipp].other[ido+ncomp+2]=q[1]; // the second hardening parameter p_s |
// other[ido+ncomp+3] = v_lambda1; it is the initial value and therefore it does not require actualization |
// other[ido+ncomp+4] = v_ini; it is the initial value and therefore it does not require actualization |
Mm->givestress(0, ipp, sig); |
give_full_vector(sigt,sig,Mm->ip[ipp].ssst); |
give_full_vector(epsnt,epsn,Mm->ip[ipp].ssst); |
give_full_vector(epspt,epsp,Mm->ip[ipp].ssst); |
i1s = first_invar (sigt)/3.0; |
// the second invariant of deviator |
// it is expressed with the help of the stress components |
// components of the deviator are not needed |
j2s = sqrt(j2_stress_invar (sigt)); |
epsv = first_invar (epsnt); |
epsvp = first_invar (epspt); |
Mm->ip[ipp].other[ido+ncomp+5] = i1s; |
Mm->ip[ipp].other[ido+ncomp+6] = j2s; |
Mm->ip[ipp].other[ido+ncomp+7] = epsv; |
Mm->ip[ipp].other[ido+ncomp+8] = epsvp; |
Mm->ip[ipp].other[ido+ncomp+9] = Mm->givenonmechq(saturation_degree, ipp); |
// volumetric strain rate |
//Mm->ip[ipp].other[ido+ncomp+10] = (epsv - Mm->ip[ipp].eqother[ido+ncomp+7])/dtime; |
// the volumetric strain rate is computed via generalized trapesoidal rule |
Mm->ip[ipp].other[ido+ncomp+10] = 0.5*((epsv - Mm->ip[ipp].eqother[ido+ncomp+7])/dtime + Mm->ip[ipp].eqother[ido+ncomp+10]); |
// reference presure = p1 |
double p1 = Mm->ic[ipp][1]; |
// specific volume at the reference pressure p_1 = v_lambda1 |
double v_lambda1 = Mm->ic[ipp][0]; |
// specific volume for the actual preconsolidation pressure = v_pc |
double v_pc = v_lambda1 - lambda * log(q[0]/p1); |
// specific volume for the actual pressure p |
double v; |
if (i1s < 0.0) |
v = v_pc + kappa*log(q[0]/i1s); |
else |
v = v_pc + kappa*log(-q[0]); |
// actual porosity n |
Mm->ip[ipp].other[ido+ncomp+11] = (v-1.0)/v; |
// suction |
Mm->ip[ipp].other[ido+ncomp+12] = Mm->givenonmechq(suction, ipp); |
// Young modulus |
Mm->ip[ipp].other[ido+ncomp+13] = give_actual_ym(ipp, im, ido); |
// time step scaling factor |
Mm->ip[ipp].other[ido+ncomp+14] = pnewdt; |
if (matcomp) |
copym(d, Mm->ip[ipp].other+ido+ncomp+15); |
errr = check_math_errel(Mm->elip[ipp]); |
} |
/** |
Function returns flag whether actualize the stiffness matrix according to the setup of the nonlinear solver and |
attained number of steps. |
@param[in] smt - type of the stiffness matrix modification in NR method |
@param[in] istep - number of load increment step in NR method |
@param[in] jstep - number of inner iteration step in NR method |
@retval 0 - in the case that actualization of the stiffness matrix is NOT required |
@retval 1 - in the case that actualization of the stiffness matrix is required |
*/ |
long dsmmat::actualize_stiffmat(const nonlinman &nlman, long istep, long jstep) |
{ |
long ret = 0; |
switch (nlman.stmat){ |
case initial_stiff: |
break; |
case tangent_stiff: |
ret = 1; |
break; |
case secant_stiff: |
case incr_tangent_stiff:{ |
if (jstep <= 0) |
ret = 1; |
break; |
} |
case ijth_tangent_stiff:{ |
if (((jstep <= 0) && (istep % nlman.ithstiffchange == 0)) || |
((jstep+1) % nlman.jthstiffchange == 0)) |
ret = 1; |
break; |
} |
default:{ |
print_err("unknown type of stiffness matrix is required",__FILE__,__LINE__,__func__); |
} |
} |
return ret; |
} |
/** |
This function updates values in the other array reached in the previous equlibrium state to |
values reached in the new actual equilibrium state. |
@param ipp - integration point number in the mechmat ip array. |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
Created by Tomas Koudelka, 09.2012 |
*/ |
void dsmmat::updateval (long ipp, long im, long ido) |
{ |
long i,n = Mm->ip[ipp].ncompstr; |
double e = comp_actual_ym(ipp, im, ido); |
for (i=0;i<n;i++){ |
Mm->ip[ipp].eqother[ido+i]=Mm->ip[ipp].other[ido+i]; |
} |
Mm->ip[ipp].eqother[ido+n] = Mm->ip[ipp].other[ido+n]; // gamma |
Mm->ip[ipp].eqother[ido+n+1] = Mm->ip[ipp].other[ido+n+1]; // p_c (hardening parameter - effective preconsolidation pressure) |
Mm->ip[ipp].eqother[ido+n+2] = Mm->ip[ipp].other[ido+n+2]; // p_s (hardening parameter - apparent adhesion) |
// |
// Following three values of the specific volume are constant and they |
// are stored directly in the eqother array during the intial step |
// |
// Mm->ip[ipp].eqother[ido+n+3] = Mm->ip[ipp].other[ido+n+3]; // v_lambda1 |
// Mm->ip[ipp].eqother[ido+n+4] = Mm->ip[ipp].other[ido+n+4]; // v_ini |
// |
Mm->ip[ipp].eqother[ido+n+5] = Mm->ip[ipp].other[ido+n+5]; // i1s; |
Mm->ip[ipp].eqother[ido+n+6] = Mm->ip[ipp].other[ido+n+6]; // j2s; |
Mm->ip[ipp].eqother[ido+n+7] = Mm->ip[ipp].other[ido+n+7]; // epsv; |
Mm->ip[ipp].eqother[ido+n+8] = Mm->ip[ipp].other[ido+n+8]; // epsvp; |
// saturation degree |
Mm->ip[ipp].eqother[ido+n+9] = Mm->ip[ipp].other[ido+n+9]; // Sr |
// volumteric strain rate |
Mm->ip[ipp].eqother[ido+n+10] = Mm->ip[ipp].other[ido+n+10]; // depsv/dt |
// actual porosity n |
Mm->ip[ipp].eqother[ido+n+11] = Mm->ip[ipp].other[ido+n+11]; |
// suction |
Mm->ip[ipp].eqother[ido+n+12] = Mm->ip[ipp].other[ido+n+12]; //s |
// Young modulus |
Mm->ip[ipp].eqother[ido+n+13] = Mm->ip[ipp].other[ido+n+13] = e; |
// time step scaling factor |
Mm->ip[ipp].eqother[ido+n+14] = Mm->ip[ipp].other[ido+n+14]; |
// stiffness matrix |
for (i=0;i<n*n;i++){ |
Mm->ip[ipp].eqother[ido+n+15+i] = Mm->ip[ipp].other[ido+n+15+i]; |
} |
//effective mean stress from previous time step |
Mm->ip[ipp].eqother[ido+n+15+n*n+1]=Mm->ip[ipp].other[ido+n+15+n*n]; |
// stress increments - it is not needed |
//for (i=0;i<n;i++){ |
//Mm->ip[ipp].eqother[ido+n+15+n*n+i]=Mm->ip[ipp].other[ido+n+15+n*n+1+i]; |
//} |
} |
/** |
The function returns actual Young modulus value. |
@param ipp - integration point number |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
*/ |
double dsmmat::give_actual_ym(long ipp, long im, long ido) |
{ |
long ncomp=Mm->ip[ipp].ncompstr; |
double e = Mm->ip[ipp].other[ido+ncomp+13]; |
return e; |
} |
/** |
The function computes actual Young modulus value. |
@param ipp - integration point number |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
*/ |
double dsmmat::comp_actual_ym(long ipp, long im, long ido) |
{ |
long idem = Mm->ip[ipp].gemid(); |
long ncompo = Mm->givencompeqother(ipp, im); |
double e; |
// initial Young modulus |
double e_ini = Mm->give_initial_ym(ipp, idem, ido+ncompo); |
// actual Poisson's ratio |
double nu = give_actual_nu(ipp, im, ido); |
// actual values of strains |
long ncomp=Mm->ip[ipp].ncompstr; |
strastrestate ssst = Mm->ip[ipp].ssst; |
//vector epsp(ASTCKVEC(ncomp)); |
vector epst(ASTCKVEC(6)); |
vector eps(ASTCKVEC(ncomp)); |
vector epsp(ASTCKVEC(ncomp)); |
vector sig(ASTCKVEC(ncomp)); |
vector q(ASTCKVEC(1)); |
// actual total volumetric strain |
Mm->givestrain(0, ipp, eps); |
give_full_vector(epst, eps, ssst); |
double epsv = first_invar(epst); |
// actual plastic volumteric strain |
//Mm->giveother(ipp, ido, ncomp, epsp); |
// total volumetric strain from the last converged step |
double epsvo = Mm->ip[ipp].eqother[ido+ncomp+7]; |
// total volumetric plastic strain from the last converged step |
double epsvpo = Mm->ip[ipp].eqother[ido+ncomp+8]; |
// actual plastic strain |
for(long i=0; i<ncomp; i++) |
epsp(i) = Mm->ip[ipp].other[ido]; |
give_full_vector(epst, epsp, ssst); |
double epsvp = first_invar(epst); |
// actual value of p_c |
//updateq(ipp, ido, eps, epsp, sig, q); |
//double pc = q(0); |
double pc = Mm->ip[ipp].other[ido+ncomp+1]; |
/* |
// initial value of elastic strain |
for (long i=0; i<ncomp; i++) |
eps(i) = Mm->ic[ipp][3+i]; |
give_full_vector(auxt, eps, ssst); |
double epsv_ini = first_invar(auxt); |
if (epsv >= epsv_ini) |
return e_ini;*/ |
// actual value of of specific volume |
double v_ini = Mm->ip[ipp].eqother[ido+ncomp+4]; |
//double v = v_ini*(1.0+epsv); |
//double p = pc/exp((v-v_pc)/kappa); |
double po = Mm->ip[ipp].eqother[ido+ncomp+5]; |
if ((po == 0.0) || (epsv == 0.0)) |
return e_ini; |
if (po > pc){ |
// for the unloading: \Delta eps^{el}_V = \Delta eps_V |
// actual p according actual swelling line |
double epsve = (epsv-epsvo) - (epsvp - epsvpo); |
double p = po*exp(-(epsve)*v_ini/kappa); |
if (epsve == 0.0) |
e = 3.0*(1.0-2.0*nu)*v_ini*(-p)/kappa; |
else |
e = 3.0*(1.0-2.0*nu)*(p-po)/(epsve); |
} |
else{ |
e = e_ini; |
} |
//e = 3.0*(1.0-2.0*nu)*v*(-p)/kappa; |
return e; |
} |
/** |
The function returns actual Poisson's ratio. |
@param ipp - integration point number |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
*/ |
double dsmmat::give_actual_nu(long ipp, long im, long ido) |
{ |
long idem = Mm->ip[ipp].gemid(); |
long ncompo = Mm->givencompeqother(ipp, im); |
double nu = Mm->give_initial_nu(ipp, idem, ido+ncompo); |
return nu; |
} |
/** |
The function returns time step scaling factor required by the model. It is represented by ratio |
of required time step size to the actual one or 1.0 for no change in time step size. |
@param ipp - integration point number in the mechmat ip array. |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
@return The function returns required time step scaling factor provided by the dsmmat model |
Created by Tomas Koudelka, 5.2022 |
*/ |
double dsmmat::dstep_red(long ipp, long im, long ido) |
{ |
long ncomp = Mm->ip[ipp].ncompstr; |
return (Mm->ip[ipp].other[ido+ncomp+14]); |
} |
/** |
Function returns irreversible plastic strains. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of the first internal variable for given material in the ipp other array |
@param epsp - %vector of irreversible strains |
Returns vector of irreversible strains via parameter epsp |
Created by Tomas Koudelka, 09.2012 |
*/ |
void dsmmat::giveirrstrains (long ipp, long ido, vector &epsp) |
{ |
long i; |
for (i=0;i<epsp.n;i++) |
epsp[i] = Mm->ip[ipp].eqother[ido+i]; |
} |
/** |
This function extracts consistency parametr gamma for the reached equilibrium state |
from the integration point other array. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
@retval The function returns value of consistency parameter. |
Created by Tomas Koudelka, 09.2012 |
*/ |
double dsmmat::give_consparam (long ipp,long ido) |
{ |
long ncompstr; |
double gamma; |
ncompstr=Mm->ip[ipp].ncompstr; |
gamma = Mm->ip[ipp].eqother[ido+ncompstr]; |
return gamma; |
} |
/** |
The function extracts saturation degree s from the integration point eqother array. |
This value remains constant from initialization of the model. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
@retval The function returns value of saturation degree. |
Created by Tomas Krejci, 14/12/2014 |
*/ |
double dsmmat::give_saturation_degree(long ipp, long ido) |
{ |
long ncompstr; |
double s; |
ncompstr=Mm->ip[ipp].ncompstr; |
s = Mm->ip[ipp].other[ido+ncompstr+9]; |
return s; |
} |
/** |
The function extracts preconsolidation pressure p_c for the attained state |
from the integration point other array. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
@retval The function returns value of preconsolidation pressure. |
Created by Tomas Koudelka, 8.10.2013 |
*/ |
double dsmmat::give_preconspress(long ipp, long ido) |
{ |
long ncompstr; |
double pc; |
ncompstr=Mm->ip[ipp].ncompstr; |
pc = Mm->ip[ipp].other[ido+ncompstr+1]; |
return pc; |
} |
/** |
The function extracts virgin void ratio e_lambda1 for the attained state (it is constant initial value) |
from the integration point eqother array. This value remains constant from initialization of the model. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
@retval The function returns value of virgin porosity e_lambda1. |
Created by Tomas Koudelka, 8.10.2013 |
*/ |
double dsmmat::give_virgporosity(long ipp, long ido) |
{ |
long ncompstr; |
double e_lambda1; |
ncompstr=Mm->ip[ipp].ncompstr; |
e_lambda1 = Mm->ip[ipp].eqother[ido+ncompstr+3]-1.0; |
return e_lambda1; |
} |
/** |
The function extracts initial porosity n_ini for the attained state (it is constant initial value) |
from the integration point eqother array. This value remains constant from initialization of the model. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
@retval The function returns value of initial porosity e_ini. |
Created by Tomas Koudelka, 8.10.2013 |
*/ |
double dsmmat::give_iniporosity(long ipp, long ido) |
{ |
long ncompstr; |
double v_ini, n_ini; |
ncompstr=Mm->ip[ipp].ncompstr; |
v_ini = Mm->ip[ipp].eqother[ido+ncompstr+4]; // v_ini = 1.0 + e_ini |
n_ini = (v_ini-1.0)/v_ini; |
return n_ini; |
} |
/** |
The function extracts porosity for the actual state from the integration point other array. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
@retval The function returns value of actual porosity e. |
Created by Tomas Koudelka, 06.2020 |
*/ |
double dsmmat::give_porosity(long ipp, long ido) |
{ |
long ncompstr; |
double n; |
ncompstr=Mm->ip[ipp].ncompstr; |
n = Mm->ip[ipp].other[ido+ncompstr+11]; |
return (n); |
} |
/** |
The function returns rate of the volumetric strain at the given integration point. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
@return The function returns rate of the volumetric strain. |
Created by Tomas Koudelka 06.2020 |
*/ |
double dsmmat::give_strain_vol_rate(long ipp, long ido) |
{ |
long ncomp = Mm->ip[ipp].ncompstr; |
return Mm->ip[ipp].other[ido+ncomp+10]; |
} |
/** |
The funtion marks required non-mechanical quantities in the array anmq. |
@param anmq - array with flags for used material types |
anmq[i] = 1 => qunatity type nonmechquant(i+1) is required |
anmq[i] = 0 => qunatity type nonmechquant(i+1) is not required |
@return The function does not return anything, but it may change content of anmq array. |
*/ |
void dsmmat::give_reqnmq(long *anmq) |
{ |
//if (pr_suc_f == no){ |
anmq[saturation_degree-1] = 1; |
anmq[suction-1] = 1; |
//} |
//if (pr_tempr_f == no) |
//anmq[temperature-1] = 1; |
} |
/** |
The function changes material parameters for stochastic analysis. |
@param atm - selected material parameters (parameters which are changed) |
@param val - array containing new values of parameters |
@return The function does not return anything. |
Created by Tomas Koudelka, 09.2012 |
*/ |
void dsmmat::changeparam (atsel &atm,vector &val) |
{ |
long i; |
for (i=0;i<atm.num;i++) |
{ |
switch (atm.atrib[i]) |
{ |
case 0: |
m=val[i]; |
break; |
case 1: |
lambda=val[i]; |
break; |
case 2: |
kappa=val[i]; |
break; |
case 3: |
c1_tilde=val[i]; |
break; |
case 4: |
c2=val[i]; |
break; |
case 5: |
ks=val[i]; |
break; |
default: |
print_err("wrong number of atribute", __FILE__, __LINE__, __func__); |
} |
} |
} |
/trunk/SIFEL/MEFEL/SRC/dsm.h |
---|
0,0 → 1,157 |
#ifndef DSMMAT_H |
#define DSMMAT_H |
#include "galias.h" |
#include "gfunct.h" |
#include "xfile.h" |
#include "alias.h" |
#include "strretalg.h" |
struct matrix; |
struct vector; |
struct atsel; |
class nonlinman; |
/** |
This class defines double structure plasticity model for expansive clays based on cam-clay material model coupled with moisture transfer |
and on a double structure concept according to: |
Sanchez, M., Gens, A., Do Nascimento Guimares, L., and Olivella, S., A double structure generalized plasticity model for expansive materials, |
International Journal for Numerical and Analytical Methods in Geomechanics, vol. 29, no. 8, pp. 751-787, 2005. doi:10.1002/nag.434. |
- this concept is not working for the curent MEFEL version, which assumes total values (not their rates) of strains and stresses |
- it must be reformulated and derived |
- not completed!! - not working!! |
Plasticity model - modified cam-clay material model: |
The material is defined by |
three usual camclay material constants : |
m - is frictional constant and it depends on the frictional angle phi |
lambda - slope of the normal consolidationa line |
kappa - slope of the swelling line |
Additionally, there are three parameters which controls |
evolution of hardening with respect to degree of saturation and suction |
c1_tilde, c2 - controls the ratio of specific volumes v/v_sat (partially saturated/fully saturated) |
ks - controls apparent adhesion (intersection of yield surface with p axis) |
In addition to these material constants, several initial values |
have to be specified at each integration point in the following order : |
v_kappa1 - initial specific volume at the reference pressure p1 after |
unloading from initial consolidation pressure p_c0 (v_kappa0) |
p1 - reference pressure (p_1), it must be negative |
p_c0 - initial consolidation pressure, it must be negative |
sig0_1 - |
. \ |
. \ components of eigenstresses |
. / |
sig0_ncomp - |
Order of the eqother array components |
id | description |
------------------+------------------------------------------------ |
<0; ncompstr-1> | plastic strains |
ncompstr | gamma - consistency parameter |
ncompstr+1 | hardening parameter p_c - consolidation pressure |
ncompstr+2 | hardening parameter p_s - apparent adhesion |
ncompstr+3 | v_lambda1 - initial value of specific volume on the NCL at reference pressure p1 |
. | v_ini - initial specific volume |
. | i1s - mean stress |
. | j2s - the second invariant of stress deviator |
. | epsv - total volume strain |
ncompstr+8 | epsvp - plastic volume strain |
ncompstr+9 | degree of saturation |
ncompstr+10 | depsv/dt - volumtric strain rate |
ncompstr+11 | actual porosity e |
10.2012 |
TKo |
*/ |
class dsmmat |
{ |
public: |
dsmmat (void); |
~dsmmat (void); |
void read (XFILE *in); |
void initval(long ipp, long im, long ido); |
double cohesion(vector &qtr); |
double yieldfunction (vector &sig, vector &q); |
void deryieldfsigma (vector &sig, vector &q, vector &dfds); |
void dderyieldfsigma (matrix &ddfds); |
void derpotsigma (vector &sig, vector &q, vector &dgds); |
void deryieldfq(vector &sig, vector &q, vector &dq); |
void deryieldfdqdq(matrix &ddfdq); |
void deryieldfdsdq(matrix &dfdsdqt); |
void der_q_gamma(long ipp, long ido, vector &sig, vector &qtr, vector &epsp, vector &dqdg); |
void dqpardgammadsigma(long ipp, long ido, vector &sig, vector &qtr, vector &epsp, matrix &dqdgds); |
void dqpardgammadqpar(long ipp, long ido, vector &sig, vector &qtr, vector &epsp, matrix &dqdgdq); |
double plasmodscalar(long ipp, long ido, vector &sig, vector &qtr, vector &epsp); |
void updateq(long ipp, long ido, vector &eps, vector &epsp, vector &sig, vector &q); |
// void updateq(vector &epsp, strastrestate ssst, vector &q); |
void matstiff (matrix &d, long ipp,long ido); |
void depmatstiff (matrix &d, long ipp, long ido); |
void nlstressesincr (long ipp,long im,long ido); |
void givestressincr (long lcid, long ipp, long im, long ido, long fi, vector &sig); |
void nlstresses (long ipp,long im,long ido); |
long actualize_stiffmat(const nonlinman &nlman, long istep, long jstep); |
void updateval (long ipp, long im, long ido); |
double comp_actual_ym(long ipp, long im, long ido); |
double give_actual_ym(long ipp, long im, long ido); |
double give_actual_nu(long ipp, long im, long ido); |
double dstep_red(long ipp, long im, long ido); |
void giveirrstrains (long ipp, long ido, vector &epsp); |
double give_consparam (long ipp, long ido); |
double give_preconspress(long ipp, long ido); |
double give_saturation_degree(long ipp, long ido); |
double give_virgporosity(long ipp, long ido); |
double give_iniporosity(long ipp, long ido); |
double give_porosity(long ipp, long ido); |
double give_strain_vol_rate(long ipp, long ido); |
void give_reqnmq(long *anmq); |
void changeparam (atsel &atm, vector &val); |
/// frictional constant |
double m; |
/// slope of normal consolidation line |
double lambda; |
/// slope of swelling line |
double kappa; |
/// first parameter for control of the v/v_sat ratio evolution |
double c1_tilde; |
/// second parameter for control of the v/v_sat ratio evolution |
double c2; |
/// coefficent of apparent adhesion due to suction pressure |
double ks; |
/// soil swelling index reference value |
double kappa_s0; |
/// parameters for the strain rate caculation caused by the suction change |
double aks1,aks2; |
/// parameters for the thermal strain rate caculation |
double a0,a2; |
/// flag for suction definition (yes=suction evolution is prescribed by suc_fn, no=suction is taken from TRFEL) |
//answertype pr_suc_f; |
/// function of prescribed suction evolution |
//gfunct suc_fn; |
/// flag for temperature definition (yes=temperature is prescribed by tempr_fn, no=temperature is taken from TRFEL) |
//answertype pr_tempr_f; |
/// function of prescribed temperature evolution |
//gfunct tempr_fn; |
/// stress return algorithm |
strretalg sra; |
}; |
#endif |
/trunk/SIFEL/MEFEL/SRC/effstress.cpp |
---|
143,7 → 143,7 |
{ |
pp = varppv->getval(Mp->time); |
sr = varsrv->getval(Mp->time); |
// set effective_pore_pressure_component of nonmechq array to constant value |
// set effective_pore_pressure_component of nonmechq array to constant value, saturation degree is assued as the effective stress factor chi |
Mm->storenonmechq(eff_pore_pressure, ipp, pp*sr); |
} |
/trunk/SIFEL/MEFEL/SRC/elastisomat.cpp |
---|
405,18 → 405,17 |
d[0][0]=s*(1-nu); d[0][1]=s*nu; d[0][2]=s*nu; |
d[1][0]=d[0][1]; d[1][1]=d[0][0]; d[1][2]=d[0][1]; |
d[2][0]=d[0][1]; d[2][1]=d[0][1]; d[2][2]=d[0][0]; |
d[3][3]=g; d[4][4]=g; d[5][5]=g; |
//////////////////////////////////////////////////////////// |
// this printing below is only for debug: |
fprintf(Out,"\n\n vysledna matice D^M\n"); |
for (i=0;i<6;i++){ |
for (j=0;j<6;j++) |
fprintf(Out,"%e \n",d[i][j]); |
fprintf(Out,"\n"); |
} |
//fprintf(Out,"\n\n vysledna matice D^M\n"); |
//for (i=0;i<6;i++){ |
//for (j=0;j<6;j++) |
// fprintf(Out,"%e \n",d[i][j]); |
//fprintf(Out,"\n"); |
//} |
} |
/trunk/SIFEL/MEFEL/SRC/elemswitch.cpp |
---|
3957,8 → 3957,13 |
*/ |
void stiffmat (long lcid,long eid,matrix &sm) |
{ |
long i,j; |
elemtype te; |
//debug??!! |
//fprintf(Out,"\n stifness matrix eid=%ld\n",eid+1); |
//fflush(Out); |
te = Mt->give_elem_type (eid); |
switch (te){ |
4170,6 → 4175,13 |
default: |
print_err("unknown element type is required", __FILE__, __LINE__, __func__); |
} |
//debug??!! |
//fprintf(Out,"\n stiffness matrix eid=%ld\n",eid+1); |
//for (i=0;i<sm.m;i++) |
//for (j=0;j<sm.n;j++) |
// fprintf(Out,"%lf ",sm[i][j]); |
//fflush(Out); |
} |
5615,10 → 5627,10 |
Mm->eigstresses = Mm->aip_eigstresses; |
Mm->tempstrains = Mm->aip_tempstrains; |
#ifdef INC_OPENMP |
#pragma omp parallel num_threads(4) |
#pragma omp for nowait |
#endif |
//#ifdef INC_OPENMP |
// #pragma omp parallel num_threads(4) |
// #pragma omp for |
//#endif |
// just call computenlstresses procedure on all auxiliary integration points |
// and check for math errors |
/trunk/SIFEL/MEFEL/SRC/generalmod.cpp |
---|
51,7 → 51,7 |
qstatev[6] = SrM |
qstatev[7] = a_scan (required on input) |
qstatev[8] = re |
Order of parameters in the array rkf_parms |
rkf_parms[0] = err_sig |
rkf_parms[1] = h_min |
91,88 → 91,47 |
garray_move(stress_gen, stress_gen_init, ngstress); |
garray_move(strain_gen, strain_gen_init, ngstrain); |
garray_move(qstatev, qstatev_init, nstatev); |
initialise_parameters(parms); |
if (parms) initialise_parameters(parms); |
//Initialises state variables and parameters (flag 0) |
if (flag == 0) { |
initialise_variables(strain_gen, stress_gen, qstatev, dstrain_gen, 1.0, parms, kinc); |
} |
//direct stiffness matrix (approximate, but can be calculated with zero strain increment provided) |
else if (flag == 3) { |
double dstrain_gen_zero[max_ngstrain]; |
garray_set(dstrain_gen_zero, 0, max_ngstrain); |
errormath += correct_statev_values(strain_gen, stress_gen, qstatev, dstrain_gen_zero, 1); |
direct_stiffness_matrix(strain_gen, stress_gen, qstatev, dstrain_gen, 1.0, DDtan_gen, parms, kinc); |
direct_stiffness_matrix(strain_gen, stress_gen, qstatev, dstrain_gen, 1.0, DDtan_gen, parms, kinc, flag); |
} |
//Updates variables, if flag == 1 also stiffness matrix by perturbation |
else if (flag == 1 || flag == 2) { |
errormath += correct_statev_values(strain_gen, stress_gen, qstatev, dstrain_gen, 1); |
//Update variables |
errorrkf += calc_rkf(strain_gen, stress_gen, qstatev, dstrain_gen, dtime, parms, rkf_statev, rkf_parms, kinc); |
errormath += correct_statev_values(strain_gen, stress_gen, qstatev, dstrain_gen, 2); |
//Calculate stiffness matrix by perturbation of current strain increment |
if(flag == 1) { |
long error_statev_perturbate = 0; |
bool perturbate=false; |
if(kinc<20 && rkf_parms[4]<10) perturbate=true; |
if(perturbate) { |
double stress_gen_pert[max_ngstress]; |
double strain_gen_pert[max_ngstrain]; |
double dstrain_gen_pert[max_ngstrain]; |
double qstatev_pert[max_nstatev]; |
garray_set(stress_gen_pert, 0.0, max_ngstress); |
garray_set(strain_gen_pert, 0.0, max_ngstrain); |
garray_set(dstrain_gen_pert, 0.0, max_ngstrain); |
garray_set(qstatev_pert, 0.0, max_nstatev); |
double pertinc_all[c_ngstrain]; |
for(int i=0; i<6; i++) pertinc_all[i]=1.e-6; |
pertinc_all[6]=-sairentry0*1.e-6; //ds |
pertinc_all[7]=1.e-3; //dT |
for(int i=0; i<ngstrain; i++) {//stiffness matrix as dDsig/dDepsiolon |
garray_move(dstrain_gen, dstrain_gen_pert, ngstrain); |
dstrain_gen_pert[i]+=pertinc_all[i]; |
garray_move(stress_gen_init, stress_gen_pert, ngstress); |
garray_move(strain_gen_init, strain_gen_pert, ngstrain); |
garray_move(qstatev_init, qstatev_pert, nstatev); |
errorrkf += calc_rkf(strain_gen_pert, stress_gen_pert, qstatev_pert, dstrain_gen_pert, dtime, parms, rkf_statev, rkf_parms, kinc); |
error_statev_perturbate += correct_statev_values(strain_gen_pert, stress_gen_pert, qstatev_pert, dstrain_gen_pert, 3); |
for(int j=0; j<ngstress; j++) { |
DDtan_gen[j*ngstrain+i]=(stress_gen_pert[j]-stress_gen[j])/pertinc_all[i]; |
} |
} |
} |
if (!perturbate || errorrkf || errormath || error_statev_perturbate) { |
direct_stiffness_matrix(strain_gen_init, stress_gen_init, qstatev_init, dstrain_gen, dtime, DDtan_gen, parms, kinc); |
} |
errormath += correct_DDtan_gen(strain_gen, stress_gen, DDtan_gen); |
direct_stiffness_matrix(strain_gen_init, stress_gen_init, qstatev_init, dstrain_gen, dtime, DDtan_gen, parms, kinc, flag); |
} |
//cout<<-strain_gen[6]<<" "<<DDtan_gen[6]<<" "<<-stress_gen[0]<<endl;//debug print |
} |
else { |
cout<<"Generalmod called with wrong flag"<<endl; |
cout<<"Generalmod called with wrong flag"<<endl; |
} |
if(check_math_error() || errormath) { |
cout<<"Generalmodel ended up with math error"<<endl; |
long matherror_here=check_math_error(); |
if(matherror_here || errormath) { |
cout<<"Generalmodel ended up with math error, errormath = "<<errormath<<", matherror_here = "<<matherror_here<<", errorrkf = "<<errorrkf<<", flag = "<<flag<<endl; |
return(1); |
} |
if(errorrkf) { |
garray_move(stress_gen_init, stress_gen, ngstress); |
garray_move(strain_gen_init, strain_gen, ngstrain); |
205,7 → 164,7 |
double dsignet[9], double &Sr_new, double dqstatev[], int kinc) { |
long errorfsigq = 0; |
//BEGIN convert increments to rates |
dsuction/=dtime; |
dTemper/=dtime; |
225,17 → 184,20 |
garray_set(&H_unsat[0][0],0,9); |
garray_set(&HT_unsat[0][0],0,9); // initialises tensors |
double fm=0.5; // initially sets fm double-structure coupling factor to 0.5 |
double fm_lambda_act=0.5; |
double fu=0; // initially sets fu factor (to Hs and HT) to zero |
double SrM=qstatev[6]; // takes the macrostructural Sr from the state variables vector |
double Sr=qstatev[2]; |
double Sr=qstatev[2]; |
bool swelling=false; |
give_LNH(signet, suction, Temper, qstatev, hypo_L, hypo_N, H_unsat, HT_unsat, fm, fu); // calculates tangent operators |
double eM=qstatev[5]; // takes the macrostructural void ratio from the state variables vector |
//double SrM=qstatev[6]; // does NOT take Sr again |
double a_scan=qstatev[7]; // takes scanning curve |
double re=qstatev[8]; // takes re (relative void ratio) |
double sewM=aer*sairentry0*eM0/eM*(aTparam+bTparam*Temper)/(aTparam+bTparam*Trparam); |
give_LNH(signet, suction, Temper, qstatev, hypo_L, hypo_N, H_unsat, HT_unsat, swelling, fu); // calculates tangent operators |
if(re<0) { |
if(debug) cout<<"re<0 for some reason, correcting it, just for fm calculation. re="<<re<<" eM="<<eM<<" em="<<qstatev[4]<<" e="<<qstatev[0]<<" ascan="<<a_scan<<endl; |
re=0; |
272,41 → 234,33 |
//Trial trace of dep_m for the given iteration |
double trdepm=0; // here trdepm is initialised to zero, and this value is used in the first iteration |
double sewM=aer*sairentry0*eM0/eM*(aTparam+bTparam*Temper)/(aTparam+bTparam*Trparam); |
double rlambda_for_ascan=0; |
double rlambda_for_se=0; |
double rlambda=give_rlambda(suction, a_scan, dsuction, sewM, SrM, rlambda_for_ascan, rlambda_for_se); |
bool swelling=true; |
double iterfactor=0; |
while(1) { |
//calculation of the double structure coupling factor |
swelling=true; |
bool notbytrdepm=false; |
if(fabs(dsuction)>1.e-4) notbytrdepm=true; |
if(!notbytrdepm && trdepm<0) swelling=false; |
else if (notbytrdepm && dsuction<0) swelling=false; |
double fm_swelling=1-gscalar_power(re,mmparam); //swelling |
fm=(csh*(suction/sewM)); |
if(swelling) fm=fm_swelling; |
else if(fm>(1-fm_swelling)) fm=1-fm_swelling; |
if(fm<0) fm=0; |
else if (fm>1) fm=1; |
if(num_iter == 0 || num_iter == 1 || num_iter == 5 || num_iter % 50 == 0) |
give_LNH(signet, suction, Temper, qstatev, hypo_L, hypo_N, H_unsat, HT_unsat, fm, fu); |
give_LNH(signet, suction, Temper, qstatev, hypo_L, hypo_N, H_unsat, HT_unsat, swelling, fu); |
depM[0]=deps[0]-fm*trdepm/3; |
depM[4]=deps[4]-fm*trdepm/3; |
depM[8]=deps[8]-fm*trdepm/3; |
give_fm(fm, fm_lambda_act, suction, sewM, re, swelling); |
double depm[9]; |
garray_set(depm,0,9); |
for(int i=0; i<3; i++) depM[3*i+i]=deps[3*i+i]-fm*trdepm/3; |
double DM[3][3]; |
garray_set(&DM[0][0], 0, 3*3); |
garray_move(depM, &DM[0][0], 3*3); |
340,26 → 294,25 |
dsignet_iter[3*i+j]=dsigMef[3*i+j]-kron_delta[i][j]*chi*(corr_s+corr_eM+corr_T); |
} |
} |
double em=qstatev[4]; |
if(num_iter>1000) {//for zero eM all the deformation is due to microstructure |
fu=0; |
garray_set(depM,0,9); |
fm=1; |
trdepm=(deps[0]+deps[4]+deps[8]); |
double pefsat=(signet[0]+signet[4]+signet[8])/3+suction; |
double dpefsat=-(trdepm-alpha_s*dTemper)*pefsat/kappam; |
double demdpm=give_demdpm(pefsat, em); |
double dpefsat=(trdepm-alpha_s*dTemper)*(1+em)/demdpm; |
dsignet_iter[0]=dsignet_iter[4]=dsignet_iter[8]=(dpefsat-dsuction); |
} |
//Calculate microstructural strain corresponding to the obtained dsignet in the current iteration. |
double depm_iter[9]; |
garray_set(depm_iter,0,9); |
calc_depm(signet, suction, Temper, dsuction, dTemper, dsignet_iter, depm_iter, fu); |
double trdepm_iter = calc_trdepm(signet, suction, Temper, em, dsuction, dTemper, dsignet_iter, fu); |
//Calculate the difference between microstructural strain obtained in the current iteration and the trial strain trdepm |
double old_error_measure=error_measure; |
error_measure=trdepm-3*depm_iter[0]; |
error_measure=trdepm-trdepm_iter; |
//Solution found |
if(gscalar_dabs(error_measure)<mexerror) |
386,26 → 339,26 |
trdepm+=step_depm; |
*/ |
if((old_error_measure>0 && error_measure<0) || (old_error_measure<0 && error_measure>0)) iterfactor+=1; |
trdepm=(3*depm_iter[0]+iterfactor*trdepm)/(iterfactor+1); // after the first iteration trdepm is updated from zero to 1/4 of 3*depm_iter[0] (+3/4 of trdepm later when trdepm is not zero) |
trdepm=(trdepm_iter+iterfactor*trdepm)/(iterfactor+1); // after the first iteration trdepm is updated from zero to 1/4 of 3*depm_iter[0] (+3/4 of trdepm later when trdepm is not zero) |
if(num_iter>1000) { |
errorfsigq = true; |
if(debug) { |
cout<<endl<<"-----------------------------------------------------"<<endl; |
cout<<"Error in microstructural iterations."<<endl; |
cout<<"Error in microstructural iterations."<<endl; |
for(int i=0; i<6; i++) cout<<"signet["<<i<<"] "<<signet[i]<<endl; |
cout<<"suction "<<suction<<endl; |
for(int i=0; i<nstatev; i++) cout<<"qstatev["<<i<<"] "<<qstatev[i]<<endl; |
cout<<"-----------------------------------------------------"<<endl; |
} |
exit(0); |
exit(1); |
} |
num_iter++; |
} |
garray_move(dsignet_iter, dsignet, 9); |
//BEGIN rates back to increments |
dsuction*=dtime; |
dTemper*=dtime; |
416,10 → 369,61 |
//this calculates dqstatev, it is not updating the original values |
int flag=2; |
update_hisv(signet, suction, Temper, qstatev, deps, dsuction, dTemper, dsignet, Sr_new, dqstatev, flag, fu, kinc); |
return(errorfsigq); |
} |
void Hypoplasti_unsat_expansive_thermal_2017::give_fm(double& fm, double& fm_lambda_act, double suction, double sewM, double re, bool swelling) { |
double fm_swelling=1-gscalar_power(re,mmparam); //swelling |
fm=(csh*(suction/sewM)); |
if(swelling) fm=fm_swelling; |
else if(fm>(1-fm_swelling)) fm=1-fm_swelling; |
if(fm<0) fm=0; |
else if (fm>1) fm=1; |
fm_lambda_act = -fm; //in the paper 2017, sign fm was wrong in lambda_act calculation |
} |
void Hypoplasti_unsat_expansive_thermal_2022::give_fm(double& fm, double& fm_lambda_act, double suction, double sewM, double re, bool swelling) { |
double fm_swelling=1-gscalar_power(re,mmparam); //swelling |
fm=(csh*(suction/sewM)); |
if(swelling) fm=fm_swelling; |
else if(fm>(1-fm_swelling)) fm=1-fm_swelling; |
if(fm<0) fm=0; |
else if (fm>1) fm=1; |
fm_lambda_act = -fm; //in the paper 2017, sign fm was wrong in lambda_act calculation |
} |
void Hypoplasti_unsat_expansive_thermal::give_fm(double& fm, double& fm_lambda_act, double suction, double sewM, double re, bool swelling) { |
double fm_swelling=1-gscalar_power(re,mmparam); |
double fm_shrinkage=csh*(suction/sewM); |
if(suction>sewM) fm_shrinkage=csh; |
if (fm_shrinkage > (1-fm_swelling)) fm_shrinkage=1-fm_swelling; |
if(fm_swelling<0) fm_swelling=0; |
else if (fm_swelling>1) fm_swelling=1; |
if(fm_shrinkage<0) fm_shrinkage=0; |
else if (fm_shrinkage>1) fm_shrinkage=1; |
if(swelling) fm=fm_swelling; |
else fm=fm_shrinkage; |
fm_lambda_act=fm_shrinkage; |
} |
/*void Hypoplasti_unsat_expansive_thermal_2022::give_fm(double& fm, double& fm_lambda_act, double suction, double sewM, double re, double swelling) { |
}*/ |
/** |
The function calculates state variable increment vector dqstatev[]. The old values of qstatev[0] (void ratio) and qstatev[6] (a_scan) must be provided by the FEM (even for the initialisation stage). The order of state variables is as follows: |
[0]e (required on input) |
464,28 → 468,31 |
//calculating state variable increments/new values |
double delta_e=(1+evoid)*gtrace(D); |
double evoid_new=evoid+delta_e; |
if(evoid_new<0) evoid_new=0; |
double Temper_new=Temper+dTemper; |
double signet_new[9]; |
garray_add(signet, dsignet, signet_new, 9); |
double suction_new=suction+dsuction; |
double emstarT=exp(alpha_s*(Temper-Trparam)+log(1+emstar))-1.0; |
double emstarT_new=exp(alpha_s*(Temper_new-Trparam)+log(1+emstar))-1.0; |
double pefsat_new=(signet_new[0]+signet_new[4]+signet_new[8])/3+suction_new; |
double pefsat=(signet[0]+signet[4]+signet[8])/3.0+suction; |
double em=qstatev[4]; |
if(fu>1) fu=1; |
double d_em=(1.0+em)*(alpha_s*dTemper-kappam/pefsat*(pefsat_new-pefsat)); |
double em_new=em; |
if(d_em>0) d_em*=(1.0-fu); |
double em_new=em+d_em; |
if(flag==0) { |
em_new=exp(kappam*log(smstar/pefsat_new)+log(1+emstarT_new))-1.0; |
em=exp(kappam*log(smstar/pefsat)+log(1+emstarT))-1.0; |
double pefsat_new=(signet_new[0]+signet_new[4]+signet_new[8])/3+suction_new; |
double pefsat=(signet[0]+signet[4]+signet[8])/3.0+suction; |
double emstarT=exp(alpha_s*(Temper-Trparam))-1.0; |
double emstarT_new=exp(alpha_s*(Temper_new-Trparam))-1.0; |
double em_pefsat_new=init_em_pefsat(pefsat_new); |
double em_pefsat=init_em_pefsat(pefsat); |
em_new=exp(log(1+em_pefsat_new)+log(1+emstarT_new))-1.0; |
em=exp(log(1+em_pefsat)+log(1+emstarT))-1.0; |
} |
double trdepm = calc_trdepm(signet, suction, Temper, em, dsuction, dTemper, dsignet, fu); |
double d_em=(1+em)*trdepm; |
em_new=em+d_em; |
double min_void=0.0001; |
if(em_new<min_void) em_new=min_void; |
if(em<min_void) em=min_void; |
531,17 → 538,18 |
double se=sedM*(aer+a_scan-aer*a_scan); |
double a_scan_new=0.0; |
double sD=0.0; |
double SrM=qstatev[6]; |
if (suction<sewM) { |
// suction at the main drying curve - equation (39) of Masin[2] |
sD=sedM/se*suction; |
double sD=sedM/se*suction; |
double sWM=sewM/(gscalar_power(SrM,(1/lambdap0))); |
double sDM=sWM/aer; |
double d_a_scan=0.0; |
double rlambda_for_ascan=0; |
double rlambda_for_se=0; |
double rlambda=give_rlambda(suction, a_scan, dsuction, sewM, SrM, rlambda_for_ascan, rlambda_for_se); |
if(aer<1) d_a_scan = (1.0-rlambda_for_ascan)/(sD*(1.0-aer))*(suction_new-suction); |
if(aer<1 && suction<sWM && suction>sDM ) d_a_scan = (1.0-rlambda_for_ascan)/(sD*(1.0-aer))*(suction_new-suction); |
a_scan_new=a_scan+d_a_scan; |
if (a_scan_new>1.0 ) |
a_scan_new=1.0; |
575,7 → 583,7 |
dqstatev[6]=SrM_new-SrM; |
dqstatev[7]=a_scan_new-qstatev[7]; |
dqstatev[8]=0; //re: to be filled later |
//calculate new state variables, needed just for re |
double qstatev_new[c_nstatev]; |
garray_add(qstatev, dqstatev, qstatev_new, c_nstatev); |
585,11 → 593,11 |
double sigef_new[9]; |
make_sig_unsat(signet_new, suction_new, SrM_new, sigef_new, suction_new); |
double pmeanef_new=-(sigef_new[0]+sigef_new[4]+sigef_new[8])/3.0; |
double emaxisot_new=min_void; |
if(pmeanef_new<1.0) emaxisot_new=exp(Nuse_new)-1.0; |
else if(Nuse_new > lambda_use_new*log(pmeanef_new)) emaxisot_new=exp(Nuse_new-lambda_use_new*log(pmeanef_new))-1.0; // maximum void ratio for the state corresponding to NCL - equation (88) of Masin[2] |
if ( /*((evoid_new>emaxisot_new) && (evoid_new>evoid)) ||*/ ((evoid_new<min_void) && (evoid_new<evoid)) ) { |
dqstatev[0]=0.0; // rate of total void ratio |
dqstatev[4]=0.0; // rate of void ratio on microlevel |
597,7 → 605,7 |
} |
double re_new=min_void; |
if(emaxisot_new>em_new) re_new=(evoid_new-em_new)/(emaxisot_new-em_new); |
if(re_new<min_void) re_new=min_void; |
else if(re_new>1) re_new=1; |
606,6 → 614,12 |
dqstatev[8]=dre; |
} |
double Hypoplasti_unsat_expansive_thermal::init_em_pefsat(double pefsat) { |
double em_pefsat = exp(kappam*log(smstar/pefsat)+log(1+emstar))-1; |
return em_pefsat; |
} |
/** |
The function calculates the macrostructural effective stress. |
619,7 → 633,7 |
Created by D. Masin 13.7.2015 |
*/ |
void Hypoplasti_unsat_expansive_thermal::make_sig_unsat(double sig[3*3], double suction, double SrM, |
void Hypoplasti_unsat_expansive_thermal::make_sig_unsat(double sig[3*3], double suction, double SrM, |
double tensor_unsat[3*3], double &scalar_unsat) { |
garray_set(tensor_unsat, 0, 3*3); |
648,22 → 662,25 |
Created by D. Masin 13.7.2015 |
*/ |
void Hypoplasti_unsat_expansive_thermal::calc_depm(double signet[9], double suction, double Temper, double dsuction, |
double dTemper, double dsignet[9], double depm[9], double fu) { |
double Hypoplasti_unsat_expansive_thermal::calc_trdepm(double signet[9], double suction, double Temper, double em, double dsuction, double dTemper, double dsignet[9], double fu) { |
double pefsat=(signet[0]+signet[4]+signet[8])/3+suction; |
double dpefsat=(dsignet[0]+dsignet[4]+dsignet[8])/3+dsuction; |
double demdpm=give_demdpm(pefsat, em); |
double trdepm=demdpm*dpefsat/(1+em)+alpha_s*dTemper; |
garray_set(depm,0,9); |
depm[0]=depm[4]=depm[8]=-kappam*(dpefsat/pefsat)/3; |
for(int i=0; i<3; i++) depm[3*i+i]+=alpha_s*dTemper/3; |
if(fu>1) |
fu=1; |
if((depm[0]+depm[4]+depm[8])>0) { |
for(int i=0; i<3; i++) depm[3*i+i]*=(1.0-fu); |
} |
if(fu>1) fu=1; |
if(trdepm>0) trdepm*=(1.0-fu); |
return trdepm; |
} |
double Hypoplasti_unsat_expansive_thermal::give_demdpm(double pefsat, double em) { |
if(pefsat>-1) pefsat=-1; |
double demdpm = -kappam*(1+em)/pefsat; |
return demdpm; |
} |
/** |
The function calculates current position and slope of normal compression line Nuse and lambda_use, and also the derivatives (dpe/ds)/pe and (dpe/dT)/pe |
703,7 → 720,7 |
// Hvorslev equivalent pressure - equation (74) of Masin[2] |
double pe=exp((Nuse-log(1+evoid))/lambda_use); |
dpeds_divpe=0; |
double eM=qstatev[5]; // takes the macrostructural void ratio from the state variables vector |
double sewM=aer*sairentry0*eM0/eM*(aTparam+bTparam*Temper)/(aTparam+bTparam*Trparam); |
729,7 → 746,7 |
*/ |
void Hypoplasti_unsat_expansive_thermal::give_LNH(double signet[9], double suction, |
double Temper, double qstatev[], double hypo_L[3][3][3][3], double hypo_N[3][3], double H_unsat[3][3], |
double HT_unsat[3][3], double fm, double &fu) { |
double HT_unsat[3][3], bool swelling, double &fu) { |
double sig_ef[9]; |
double stresssuction=0; |
740,9 → 757,9 |
garray_set(&T[0][0], 0, 3*3); |
garray_move(sig_ef, &T[0][0], 3*3); |
double p_mean=-gtrace(T)/3; |
if(p_mean<0) { |
if(p_mean<1) { |
if(debug) cout<<"Correcting mean stress, p_mean="<<p_mean<<endl; |
p_mean=0; |
p_mean=1; |
} |
double kron_delta[3][3]; |
866,15 → 883,19 |
//get lambda_act for constant suction; |
double eM=qstatev[5]; |
double em=qstatev[4]; |
double pefsat=-((signet[0]+signet[4]+signet[8])/3+suction); |
double lambda_act=lambda_use; |
if (unsat_active) { |
// lambda_act=lambda_use/(1.0-(nparam-lparam*log(p))*(1.0+e)/e); |
lambda_act=(lambda_use*eM*(1+em)-(p_mean/pefsat)*kappam*(1+eM)*(1+em)*(nparam-lparam*log(p_mean))-(p_mean/pefsat)*kappam*fm*eM*(1+em))/(eM*(1+em)-(1+evoid)*(nparam-lparam*log(p_mean))); |
// double A=kappam*(1+eM)*(nparam-lparam*log(p))/eM+kappam*fm; |
// double citatel=lambda_use-A*(p/pefsat)*(1-kappam*(1+eM)*SrM*lambdap0*suction/(eM*pefsat)); |
// double jmenovatel=1-(1+e)/(eM*(1+em))*(nparam-lparam*log(p)-A*SrM*lambdap0*suction/pefsat); |
// lambda_act=citatel/jmenovatel; |
double fm=0, fm_lambda_act=0; |
double re=qstatev[8]; // takes re (relative void ratio) |
double sewM=aer*sairentry0*eM0/eM*(aTparam+bTparam*Temper)/(aTparam+bTparam*Trparam); |
give_fm(fm, fm_lambda_act, suction, sewM, re, swelling); |
double pefsat=(signet[0]+signet[4]+signet[8])/3+suction; |
double demdpm=give_demdpm(pefsat, em); |
double p_mean_positive=p_mean; |
if(p_mean_positive<1.0) p_mean_positive=1.0; |
lambda_act=(lambda_use*eM*(1+em)+demdpm*p_mean_positive*(1+eM)*(nparam-lparam*log(p_mean_positive))+fm_lambda_act*demdpm*p_mean_positive*eM)/(eM*(1+em)-(1+evoid)*(nparam-lparam*log(p_mean_positive))); |
} |
fs=9*p_mean/2*(1/kappa+1/lambda_act)/Am; |
garray_multiply(&hypo_L[0][0][0][0], &hypo_L[0][0][0][0], fs, 81); |
927,10 → 948,10 |
fu=gscalar_power(pdivpsbs, 2); |
else if (pdivpsbs>5) |
fu=gscalar_power(5, 2); |
double cic=1; |
if(nparam<0) fu=0; |
double fu_Hunsat = nparam<0 ? 0 : fu; |
bool m0_OCRindep_collapse=true; |
double cic=1; |
if(m0_OCRindep_collapse && fd<fdsbs) { |
cic=(lambda_act+kappa)*(gscalar_power(2.0,alpha_power)-fd)+2*kappa*fd; |
cic=cic/((lambda_act+kappa)*(gscalar_power(2.0,alpha_power)-fdsbs)+2*kappa*fdsbs); |
940,8 → 961,8 |
garray_multiply(&T[0][0], &H_unsat[0][0], dpeds_divpe*cic*lambda_use/lambda_act, 9); |
garray_set(&HT_unsat[0][0], 0, 3*3); |
garray_multiply(&T[0][0], &HT_unsat[0][0], dpedT_divpe*cic*lambda_use/lambda_act, 9); |
garray_multiply(&H_unsat[0][0], &H_unsat[0][0], fu, 9); //H times fd/fdSOM |
garray_multiply(&HT_unsat[0][0], &HT_unsat[0][0], fu, 9); //HT times fd/fdSOM |
garray_multiply(&H_unsat[0][0], &H_unsat[0][0], fu_Hunsat, 9); //H times fd/fdSOM |
garray_multiply(&HT_unsat[0][0], &HT_unsat[0][0], fu_Hunsat, 9); //HT times fd/fdSOM |
} |
double Hypoplasti_unsat_expansive_thermal::give_SrM_new(double suction, double SrM, double eM, double Temper, double sewM, double se, double dsuction, double deM, double dTemper, double a_scan, int flag) { |
960,7 → 981,7 |
double dSrM_dse=rlambda_for_se*lambdap0*SrM/se; |
double dse_deM=-sairentry0*eM0/(eM*eM)*(aTparam+bTparam*Temper)/(aTparam+bTparam*Trparam); |
double dse_dT=sairentry0*eM0*bTparam/(eM*(aTparam+bTparam*Trparam)); |
double dSrM=dSrM_ds*dsuction+dSrM_dse*(dse_deM*deM+dse_dT*dTemper); |
SrM_new=SrM+dSrM; |
970,8 → 991,8 |
} |
double Hypoplasti_unsat_expansive_thermal_original::give_rlambda(double suction, double a_scan, double dsuction, double sewM, double SrM, double& rlambda_for_ascan, double& rlambda_for_se) { |
double Hypoplasti_unsat_expansive_thermal_2017::give_rlambda(double suction, double a_scan, double dsuction, double sewM, double SrM, double& rlambda_for_ascan, double& rlambda_for_se) { |
double rlambda=0; |
if(a_scan<1-1.0e-10 && a_scan>1.0e-10 && aer<1) |
rlambda=rlambdascan; |
985,23 → 1006,23 |
return rlambda; |
} |
double Hypoplasti_unsat_expansive_thermal::give_rlambda(double suction, double a_scan, double dsuction, double sewM, double SrM, double& rlambda_for_ascan, double& rlambda_for_se) { |
double Hypoplasti_unsat_expansive_thermal_2022::give_rlambda(double suction, double a_scan, double dsuction, double sewM, double SrM, double& rlambda_for_ascan, double& rlambda_for_se) { |
double scanpower=3; |
double SrMlimit=0.75; |
double SrMmax=1.0; |
double WRCpower=1.1; |
double Sepower=3; |
double Sepower=3.0; |
double fact=a_scan; //wetting within main curves |
if(dsuction>0) fact=1-a_scan; //drying within main curves |
double rlambda=1; |
rlambda_for_se=1; |
if(fact<1.e-10) fact=0; |
if(aer<1) rlambda=gscalar_power(fact, scanpower); |
if(SrM>1) SrM=1; |
if(suction>=sewM) {//drying from 0 |
rlambda=0; |
1008,24 → 1029,57 |
rlambda_for_se=0; |
} |
rlambda_for_ascan=rlambda; |
//wetting to 0, rlambda_for_ascan remains 1 here |
if(dsuction>0 && SrM>SrMlimit) { |
rlambda=gscalar_power((SrMmax-SrM)/(1-SrMlimit), WRCpower); |
rlambda_for_se=gscalar_power((SrMmax-SrM)/(1-SrMlimit), Sepower); |
rlambda=gscalar_power((SrMmax-SrM)/(SrMmax-SrMlimit), WRCpower); |
rlambda_for_se=gscalar_power((SrMmax-SrM)/(SrMmax-SrMlimit), Sepower); |
} |
return rlambda; |
return rlambda; |
} |
void Hypoplasti_unsat_expansive_thermal::direct_stiffness_matrix(double strain_gen[], double stress_gen[], double qstatev[], |
double dstrain_gen[], double dtime, double *DDtan_gen, double parms[], int kinc) { |
double Hypoplasti_unsat_expansive_thermal::give_rlambda(double suction, double a_scan, double dsuction, double sewM, double SrM, double& rlambda_for_ascan, double& rlambda_for_se) { |
double scanpower=3; |
double SrMlimit=0.2; //was SrMlimit=0.75; |
double SrMmax=1.0; |
double WRCpower=1.0; //was WRCpower=1.1; |
double Sepower=3.0; |
double fact=a_scan; //wetting within main curves |
if(dsuction>0) fact=1-a_scan; //drying within main curves |
double rlambda=1; |
rlambda_for_se=1; |
if(fact<1.e-10) fact=0; |
if(aer<1) rlambda=gscalar_power(fact, scanpower); |
if(SrM>1) SrM=1; |
if(suction>=sewM) {//drying from 0 |
rlambda=0; |
rlambda_for_se=0; |
} |
rlambda_for_ascan=rlambda; |
//wetting to 0, rlambda_for_ascan remains 1 here |
if(dsuction>0 && SrM>SrMlimit) { |
rlambda=gscalar_power((SrMmax-SrM)/(SrMmax-SrMlimit), WRCpower); |
rlambda_for_se=gscalar_power((SrMmax-SrM)/(SrMmax-SrMlimit), Sepower); |
} |
return rlambda; |
} |
void Hypoplasti_unsat_expansive_thermal::direct_stiffness_matrix(double strain_gen[], double stress_gen[], double qstatev[], |
double dstrain_gen[], double dtime, double *DDtan_gen, double parms[], int kinc, int flag) { |
double signet[9]; |
double Sr=0; |
double othervar[5]={0,0,0,0,0}; |
convert_from_general(stress_gen, signet, othervar, ngstress-6, 1); |
convert_from_general(stress_gen, signet, othervar, ngstress-6, 1); |
Sr=othervar[0]; |
double ddum9[9]; |
1032,11 → 1086,19 |
convert_from_general(strain_gen, ddum9, othervar, ngstrain-6, 2); |
double suction=othervar[0]; |
double Temper=othervar[1]; |
double pertinc_all[c_ngstrain]; |
garray_set(pertinc_all, 0, ngstrain); |
for(int i=0; i<6; i++) pertinc_all[i]=1.e-6; |
pertinc_all[6]=-sairentry0/100; //ds |
pertinc_all[7]=0.1; //dT |
if(flag!=3) { //segmentation fault without this |
for(int i=0; i<ngstrain; i++) { |
if(dstrain_gen[i]<0) pertinc_all[i]=-gscalar_dabs(pertinc_all[i]); |
else pertinc_all[i]=gscalar_dabs(pertinc_all[i]); |
} |
} |
garray_set(DDtan_gen, 0, c_ngstrain*c_ngstress); |
1083,9 → 1145,8 |
garray_set(&hypo_N[0][0],0,9); |
garray_set(&H_unsat[0][0],0,9); |
garray_set(&HT_unsat[0][0],0,9); |
double fm=0; |
double fu=0; |
give_LNH(signet, suction, Temper, qstatev, hypo_L, hypo_N, H_unsat, HT_unsat, fm, fu); |
give_LNH(signet, suction, Temper, qstatev, hypo_L, hypo_N, H_unsat, HT_unsat, false, fu); |
garray_move(&hypo_L[0][0][0][0], &DDtan[0][0][0][0], 81); |
convert4th_to_abaqus(DDtan, DDtan_abq); |
1097,18 → 1158,18 |
} |
} |
void Hypoplasti_unsat_expansive_thermal::initialise_variables(double strain_gen[], double stress_gen[], double qstatev[], |
void Hypoplasti_unsat_expansive_thermal::initialise_variables(double strain_gen[], double stress_gen[], double qstatev[], |
double dstrain_gen[], double dtime, double parms[], int kinc) { |
double signet[9]; |
garray_set(signet, 0.0, 9); |
double othervar[5]={0,0,0,0,0}; |
convert_from_general(stress_gen, signet, othervar, ngstress-6, 1); |
convert_from_general(stress_gen, signet, othervar, ngstress-6, 1); |
double Sr=othervar[0]; |
double dqstatev[c_nstatev]; |
garray_set(dqstatev, 0.0, nstatev); |
double zeroinctens[9]={0,0,0,0,0,0,0,0,0}; |
double ddum9[9]={0,0,0,0,0,0,0,0,0}; |
double zeroincscal=0; |
1127,7 → 1188,7 |
if(qstatev[5]<0) { |
cout<<"Initial value of eM is lower than 0 and this is not allowed, please re-initialise, eM="<<qstatev[5]<<endl; |
exit(0); |
exit(1); |
} |
double ddum3333[3][3][3][3]; |
1135,7 → 1196,7 |
double ddum=0; |
garray_set(&ddum3333[0][0][0][0],0,81); |
garray_set(&ddum33[0][0],0,9); |
give_LNH(signet, suction, Temper, qstatev, ddum3333, ddum33, ddum33, ddum33, ddum, fu); |
give_LNH(signet, suction, Temper, qstatev, ddum3333, ddum33, ddum33, ddum33, false, fu); |
if(fu>1) { |
cout<<"Warning, void ratio and stress state were initialised outside SBS, fu="<<fu<<endl; |
} |
1173,22 → 1234,29 |
aer=parms[20]; |
lambdap0=parms[21]; |
pt=parms[22]; |
alphaG=1; |
alphanu=alphaG; |
alphaE=gscalar_power(alphaG,1./0.8); |
rlambdascan=0.1; |
//end define parameters |
//end define parameters |
} |
long General_model::calc_rkf(double strain_gen[], double stress_gen[], double qstatev[], double dstrain_gen[], double dtime, |
double parms[], double rkf_statev[], double rkf_parms[], int kinc) { |
long errorrkf = false; |
//if not specified, initialise rkf_parms & rkf_statev to default values |
if(rkf_parms==NULL) { |
double rkf_parms_default[nrkf_parms] = {1.0e-5,1.0e-17,1,1.0e-3,7}; |
//Order of parameters in the array rkf_parms |
//rkf_parms[0] = err_sig, default 1.e-3 |
//rkf_parms[1] = h_min, default 1.e-17 |
//rkf_parms[2] = ni, default 1000 |
//rkf_parms[3] = sv_rkf_zero, default 1.e-3 |
//rkf_parms[4] = rkt, default 4 |
double rkf_parms_default[nrkf_parms] = {1.0e-3,1.0e-17,1000,1.0e-3,4}; //{1.0e-5,1.0e-17,1,1.0e-3,7}; |
rkf_parms=&rkf_parms_default[0]; |
} |
if(rkf_statev==NULL) { |
1195,42 → 1263,42 |
double rkf_statev_default[nrkf_statev] = {0,0,1,0.1}; |
rkf_statev=&rkf_statev_default[0]; |
} |
int rkt = rkf_parms[4]<10 ? rkf_parms[4]:(rkf_parms[4]-10); |
int rkt = rkf_parms[4]; |
switch (rkt){ |
case 1: { //case rkt=1 forward Euler |
case 1: { //case rkt=1 forward Euler |
double signet[9]; |
garray_set(signet, 0.0, 9); |
double othervar[5]={0,0,0,0,0}; |
convert_from_general(stress_gen, signet, othervar, ngstress-6, 1); |
double Sr=othervar[0]; |
double ddum9[9]; |
convert_from_general(strain_gen, ddum9, othervar, ngstrain-6, 2); |
double suction=othervar[0]; |
double Temper=othervar[1]; |
double dstress_gen[max_ngstress]; |
double dqstatev[max_nstatev]; |
garray_set(dstress_gen, 0.0, ngstress); |
garray_set(dqstatev, 0.0, nstatev); |
double gmod_deps[9]; |
garray_set(gmod_deps, 0, 9); |
garray_set(gmod_deps, 0, 9); |
convert_from_general(dstrain_gen, gmod_deps, othervar, ngstrain-6, 2); |
double dsuction=othervar[0]; |
double dTemper=othervar[1]; |
double dsignet[9]; |
garray_set(dsignet, 0, 9); |
double Sr_new=0; |
errorrkf = calc_fsigq(signet, suction, Temper, qstatev, gmod_deps, dsuction, dTemper, dtime, dsignet, Sr_new, dqstatev, kinc); |
othervar[0]=Sr_new-Sr; |
garray_set(dstress_gen,0,ngstress); |
convert_to_general(dstress_gen, dsignet, othervar,(ngstress-6),1); |
//Update external variables |
for (int i=0; i<ngstress; i++) stress_gen[i] += dstress_gen[i]; |
for (int i=0; i<nstatev; i++) qstatev[i] += dqstatev[i]; |
1363,7 → 1431,7 |
double General_model::gscalar_power( double a, double b ) { |
/* if(b==0.5 && a<0) { |
cout<<"Attempting to calculate square root of a negative number"; |
exit(0); |
exit(1); |
} |
double result=0.; |
if ( b==0. ) |
1379,7 → 1447,7 |
return ret; |
} |
else if (a>=0 && !isnan(a) && !isnan(b)) return 0; |
else |
else |
{ |
if(debug) cout<<"Error in calculating power "<<a<<"^"<<b<<endl; |
return(0.0); |
1394,26 → 1462,26 |
return tmp; |
} |
void General_model::garray_add( double a[], double b[], double c[], long int n ) { |
register long int i=0; |
long int i=0; |
for ( i=0; i<n; i++ ) c[i] = a[i] + b[i]; |
} |
double General_model::garray_inproduct( double a[], double b[], long int n ) { |
register long int i=0; |
long int i=0; |
double result=0.; |
for ( i=0; i<n; i++ ) result += a[i]*b[i]; |
return result; |
} |
void General_model::garray_move( double from[], double to[], long int n ) { |
// register long int i=0; |
// long int i=0; |
// for ( i=0; i<n; i++ ) to[i] = from[i]; |
memcpy(to, from, sizeof(*from)*n); |
} |
void General_model::garray_multiply( double a[], double b[], double c, long int n ) { |
register long int i=0; |
long int i=0; |
for ( i=0; i<n; i++ ) b[i] = c * a[i]; |
} |
void General_model::garray_set( double *ptr, double value, long int n ) { //@GS initialises the array to "value" (e.g. to zero) |
// register long int i=0; |
// long int i=0; |
// for ( i=0; i<n; i++ ) *(ptr+i) = value; |
if (value == 0.0) |
memset(ptr, 0, sizeof(*ptr)*n); |
1443,13 → 1511,13 |
} |
else { |
cout<<"n must be 1-3"<<endl; |
exit(0); |
exit(1); |
} |
} |
return result; |
} |
void General_model::gmatrix_ab( double *a, double *b, double *c, long int n, long int m, long int k ) { // c[n][k] = a[n][m] * b[m][k] |
register long int i=0, j=0, l=0; |
long int i=0, j=0, l=0; |
for ( i=0; i<n; i++ ) { |
for ( j=0; j<k; j++ ) { |
1462,7 → 1530,7 |
} |
} |
void General_model::gmatrix_a4b( double a[3][3][3][3], double b[], double c[] ) { |
register long int i=0, j=0, k=0, l=0; |
long int i=0, j=0, k=0, l=0; |
for ( i=0; i<3; i++ ) { |
for ( j=0; j<3; j++ ) { |
1484,10 → 1552,9 |
return round(value * factor) / factor; |
} |
long General_model::test_math_err() { |
if ((errno == EDOM) || (errno == ERANGE)) |
return 1; |
return 0; |
if (errno == EDOM) return 1; |
else if(errno == ERANGE) return 2; |
else return 0; |
} |
//@GS Functions adapted from SIFEL |
1529,7 → 1596,8 |
long k, j; |
long ni = rkf_parms[2]; |
long stopk = 0; |
long ngcomp = max_ngstress + max_nstatev; |
long max_ngcomp = max_ngstress + max_nstatev; |
long ngcomp = ngstress + nstatev; |
double k1[max_ngstress + max_nstatev], k2[max_ngstress + max_nstatev], y1[max_ngstress + max_nstatev], y2[max_ngstress + max_nstatev], y_hat[max_ngstress + max_nstatev], y_til[max_ngstress + max_nstatev], y_err[max_ngstress + max_nstatev]; |
double strain_gen_aux[max_ngstrain], dstrain_gen_aux[max_ngstrain]; |
long herr; |
1537,6 → 1605,20 |
double g_suction=0, g_dsuction=0, g_Temper=0, g_dTemper=0, g_Sr=0, g_Sr_new=0; |
double g_signet[9], g_deps[9], g_ddum9[9], g_othervar[5], g_dsignet[9], g_dSr[1]; |
long error=0; |
//initialising variables |
for (j=0; j<max_ngcomp; j++) { |
k1[j]=0; |
k2[j]=0; |
y1[j]=0; |
y2[j]=0; |
y_hat[j]=0; |
y_til[j]=0; |
y_err[j]=0; |
if(j<max_ngstrain) { |
strain_gen_aux[j]=0; |
dstrain_gen_aux[j]=0; |
} |
} |
//} |
//{ preparation |
// set initial substep length |
1561,7 → 1643,7 |
//{ first call to calc_fsigq |
// calculate Forward Euler |
convert_from_general (y1, g_signet, g_othervar, (ngstress-6), 1); |
g_Sr = g_othervar[0]; |
convert_from_general (strain_gen_aux, g_ddum9, g_othervar, (ngstrain-6), 2); |
g_suction=g_othervar[0]; |
1588,7 → 1670,7 |
//{ second call to calc_fsigq |
// calculate Forward Euler for half step |
convert_from_general (y1, g_signet, g_othervar, (ngstress-6), 1); |
g_Sr = g_othervar[0]; |
convert_from_general (strain_gen_aux, g_ddum9, g_othervar, (ngstrain-6), 2); |
g_suction=g_othervar[0]; |
1614,7 → 1696,7 |
//} |
//{ third call to calc_fsigq |
convert_from_general (y2, g_signet, g_othervar, (ngstress-6), 1); |
g_Sr = g_othervar[0]; |
convert_from_general (strain_gen_aux, g_ddum9, g_othervar, (ngstrain-6), 2); |
g_suction=g_othervar[0]; |
1745,10 → 1827,11 |
double dtmin = rkf_parms[1]; |
double idtsub = dtsub; |
double sv_rkf_zero = rkf_parms[3]; //needed |
long k; |
long j, k; |
long ni = rkf_parms[2]; |
long stopk = 0; |
long ngcomp = max_ngstress + max_nstatev; |
long max_ngcomp = max_ngstress + max_nstatev; |
long ngcomp = ngstress + nstatev; |
double k1[max_ngstress + max_nstatev], y1[max_ngstress + max_nstatev]; |
double strain_gen_aux[max_ngstrain], dstrain_gen_aux[max_ngstrain]; |
// additional variables (for calc_fsigq) |
1755,6 → 1838,15 |
double g_suction=0, g_dsuction=0, g_Temper=0, g_dTemper=0, g_Sr=0, g_Sr_new=0; |
double g_signet[9], g_deps[9], g_ddum9[9], g_othervar[5], g_dsignet[9], g_dSr[1]; |
long error=0; |
//initialising variables |
for (j=0; j<max_ngcomp; j++) { |
k1[j]=0; |
y1[j]=0; |
if(j<max_ngstrain) { |
strain_gen_aux[j]=0; |
dstrain_gen_aux[j]=0; |
} |
} |
//} |
//{ preparation |
// set initial substep length |
1772,7 → 1864,7 |
// dstrain_gen_aux = h*dstrain_gen; |
garray_addmult(NULL, dstrain_gen, h, dstrain_gen_aux, ngstrain); |
convert_from_general (y1, g_signet, g_othervar, (ngstress-6), 1); |
g_Sr = g_othervar[0]; |
convert_from_general (strain_gen_aux, g_ddum9, g_othervar, (ngstrain-6), 2); |
g_suction=g_othervar[0]; |
1789,7 → 1881,7 |
if (check_math_error() || errorfsigq) return 1; |
garray_add(y1, k1, y1, ngcomp); |
neval += 3; |
rkf_statev[0] = neval; |
// substep is accepted, !FE solution taken |
1855,7 → 1947,8 |
long k, j; |
long ni = rkf_parms[2]; |
long stopk = 0; |
long ngcomp = max_ngstress + max_nstatev; |
long max_ngcomp = max_ngstress + max_nstatev; |
long ngcomp = ngstress + nstatev; |
long stvcomp; |
double k1[max_ngstress+ max_nstatev], k2[max_ngstress + max_nstatev], k3[max_ngstress + max_nstatev], y1[max_ngstress + max_nstatev], y2[max_ngstress + max_nstatev], y3[max_ngstress + max_nstatev], y_hat[max_ngstress + max_nstatev], y_til[max_ngstress + max_nstatev], y_err[max_ngstress + max_nstatev]; |
double strain_gen_aux[max_ngstrain], dstrain_gen_aux[max_ngstrain]; |
1864,6 → 1957,22 |
double g_suction=0, g_dsuction=0, g_Temper=0, g_dTemper=0, g_Sr=0, g_Sr_new=0; |
double g_signet[9], g_deps[9], g_ddum9[9], g_othervar[5], g_dsignet[9], g_dSr[1]; |
long error=0; |
//initialising variables |
for (j=0; j<max_ngcomp; j++) { |
k1[j]=0; |
k2[j]=0; |
k3[j]=0; |
y1[j]=0; |
y2[j]=0; |
y3[j]=0; |
y_hat[j]=0; |
y_til[j]=0; |
y_err[j]=0; |
if(j<max_ngstrain) { |
strain_gen_aux[j]=0; |
dstrain_gen_aux[j]=0; |
} |
} |
//} |
//{ preparation |
// set initial substep length |
1889,7 → 1998,7 |
//{ first call to calc_fsigq |
// calculate initial vector of coefficients for the first stage of Runge-Kutta method |
convert_from_general (y1, g_signet, g_othervar, (ngstress-6), 1); |
g_Sr = g_othervar[0]; |
convert_from_general (strain_gen_aux, g_ddum9, g_othervar, (ngstrain-6), 2); |
g_suction=g_othervar[0]; |
1929,7 → 2038,7 |
//{ second call to calc_fsigq |
// calculate coefficients for the second stage of Runge-Kutta method |
convert_from_general (y2, g_signet, g_othervar, (ngstress-6), 1); |
g_Sr = g_othervar[0]; |
convert_from_general (strain_gen_aux, g_ddum9, g_othervar, (ngstrain-6), 2); |
g_suction=g_othervar[0]; |
1962,7 → 2071,7 |
//{ third call to calc_fsigq |
// calculate coefficients for the third stage of Runge-Kutta method |
convert_from_general (y3, g_signet, g_othervar, (ngstress-6), 1); |
g_Sr = g_othervar[0]; |
convert_from_general (strain_gen_aux, g_ddum9, g_othervar, (ngstrain-6), 2); |
g_suction=g_othervar[0]; |
2127,7 → 2236,8 |
long k, j; |
long ni = rkf_parms[2]; |
long stopk = 0; |
long ngcomp = max_ngstress + max_nstatev; |
long max_ngcomp = max_ngstress + max_nstatev; |
long ngcomp = ngstress + nstatev; |
long stvcomp; |
double k1[max_ngstress + max_nstatev], k2[max_ngstress + max_nstatev], k3[max_ngstress + max_nstatev], k4[max_ngstress + max_nstatev]; |
double y1[max_ngstress + max_nstatev], y2[max_ngstress + max_nstatev], y3[max_ngstress + max_nstatev], y_hat[max_ngstress + max_nstatev], y_til[max_ngstress + max_nstatev], y_err[max_ngstress + max_nstatev]; |
2137,6 → 2247,23 |
double g_suction=0, g_dsuction=0, g_Temper=0, g_dTemper=0, g_Sr=0, g_Sr_new=0; |
double g_signet[9], g_deps[9], g_ddum9[9], g_othervar[5], g_dsignet[9], g_dSr[1]; |
long error=0; |
//initialising variables |
for (j=0; j<max_ngcomp; j++) { |
k1[j]=0; |
k2[j]=0; |
k3[j]=0; |
k4[j]=0; |
y1[j]=0; |
y2[j]=0; |
y3[j]=0; |
y_hat[j]=0; |
y_til[j]=0; |
y_err[j]=0; |
if(j<max_ngstrain) { |
strain_gen_aux[j]=0; |
dstrain_gen_aux[j]=0; |
} |
} |
//} |
//{ preparation |
// set initial substep length |
2216,7 → 2343,7 |
//{ second call to calc_fsigq |
// calculate coefficients for the second stage of Runge-Kutta method |
errorfsigq += correct_statev_values(strain_gen_aux, y2, y2+ngstress, dstrain_gen_aux, 4); |
convert_from_general (y2, g_signet, g_othervar, (ngstress-6), 1); |
convert_from_general (y2, g_signet, g_othervar, (ngstress-6), 1); |
g_Sr = g_othervar[0]; |
convert_from_general (strain_gen_aux, g_ddum9, g_othervar, (ngstrain-6), 2); |
g_suction=g_othervar[0]; |
2369,7 → 2496,7 |
// select optimal RK substep length |
h = min2(4.0*h, h_opt); |
if (h > 1.0) h = 1.0; |
if(err_sig >= 1) h = 1/err_sig; //Constant number of substeps |
if(err_sig >= 1) h = 1/err_sig; //Constant number of substeps |
// store the last attained RK substep length to be the initial substep length in the next RKF method call |
dtsub = h; |
rkf_statev[3] = dtsub; |
2458,7 → 2585,8 |
long k, j; |
long ni = rkf_parms[2]; |
long stopk = 0; |
long ngcomp = max_ngstress + max_nstatev; |
long max_ngcomp = max_ngstress + max_nstatev; |
long ngcomp = ngstress + nstatev; |
long stvcomp; |
double k1[max_ngstress + max_nstatev], k2[max_ngstress + max_nstatev], k3[max_ngstress + max_nstatev], k4[max_ngstress + max_nstatev], k5[max_ngstress + max_nstatev]; |
double y1[max_ngstress + max_nstatev], y2[max_ngstress + max_nstatev], y3[max_ngstress + max_nstatev], y4[max_ngstress + max_nstatev], y_hat[max_ngstress + max_nstatev], y_til[max_ngstress + max_nstatev], y_err[max_ngstress + max_nstatev]; |
2468,6 → 2596,24 |
double g_suction=0, g_dsuction=0, g_Temper=0, g_dTemper=0, g_Sr=0, g_Sr_new=0; |
double g_signet[9], g_deps[9], g_ddum9[9], g_othervar[5], g_dsignet[9], g_dSr[1]; |
long error=0; |
//initialising variables |
for (j=0; j<max_ngcomp; j++) { |
k1[j]=0; |
k2[j]=0; |
k3[j]=0; |
k4[j]=0; |
y1[j]=0; |
y2[j]=0; |
y3[j]=0; |
y4[j]=0; |
y_hat[j]=0; |
y_til[j]=0; |
y_err[j]=0; |
if(j<max_ngstrain) { |
strain_gen_aux[j]=0; |
dstrain_gen_aux[j]=0; |
} |
} |
//} |
//{ preparation |
// set initial substep length |
2492,7 → 2638,7 |
//{ first call to calc_fsigq |
// calculate initial vector of coefficients for the first stage of Runge-Kutta method |
convert_from_general (y1, g_signet, g_othervar, (ngstress-6), 1); |
g_Sr = g_othervar[0]; |
convert_from_general (strain_gen_aux, g_ddum9, g_othervar, (ngstrain-6), 2); |
g_suction=g_othervar[0]; |
2535,7 → 2681,7 |
//{ second call to calc_fsigq |
// calculate coefficients for the second stage of Runge-Kutta method |
convert_from_general (y2, g_signet, g_othervar, (ngstress-6), 1); |
g_Sr = g_othervar[0]; |
convert_from_general (strain_gen_aux, g_ddum9, g_othervar, (ngstrain-6), 2); |
g_suction=g_othervar[0]; |
2568,7 → 2714,7 |
//{ third call to calc_fsigq |
// calculate coefficients for the third stage of Runge-Kutta method |
convert_from_general (y3, g_signet, g_othervar, (ngstress-6), 1); |
g_Sr = g_othervar[0]; |
convert_from_general (strain_gen_aux, g_ddum9, g_othervar, (ngstrain-6), 2); |
g_suction=g_othervar[0]; |
2601,7 → 2747,7 |
//{ fourth call to calc_fsigq |
// calculate coefficients for the fourth stage of Runge-Kutta method |
convert_from_general (y4, g_signet, g_othervar, (ngstress-6), 1); |
g_Sr = g_othervar[0]; |
convert_from_general (strain_gen_aux, g_ddum9, g_othervar, (ngstrain-6), 2); |
g_suction=g_othervar[0]; |
2635,7 → 2781,7 |
//{ fifth call to calc_fsigq |
// calculate coefficients for the fifth stage of Runge-Kutta method |
convert_from_general (y_til, g_signet, g_othervar, (ngstress-6), 1); |
g_Sr = g_othervar[0]; |
convert_from_general (strain_gen_aux, g_ddum9, g_othervar, (ngstrain-6), 2); |
g_suction=g_othervar[0]; |
2792,7 → 2938,8 |
long k, j; |
long ni = rkf_parms[2]; |
long stopk = 0; |
long ngcomp = max_ngstress + max_nstatev; |
long max_ngcomp = max_ngstress + max_nstatev; |
long ngcomp = ngstress + nstatev; |
long stvcomp; |
double k1[max_ngstress + max_nstatev], k2[max_ngstress + max_nstatev], k3[max_ngstress + max_nstatev], k4[max_ngstress + max_nstatev], k5[max_ngstress + max_nstatev], k6[max_ngstress + max_nstatev]; |
double y1[max_ngstress + max_nstatev], y2[max_ngstress + max_nstatev], y3[max_ngstress + max_nstatev], y4[max_ngstress + max_nstatev], y5[max_ngstress + max_nstatev], y6[max_ngstress + max_nstatev]; |
2803,6 → 2950,29 |
double g_suction=0, g_dsuction=0, g_Temper=0, g_dTemper=0, g_Sr=0, g_Sr_new=0; |
double g_signet[9], g_deps[9], g_ddum9[9], g_othervar[5], g_dsignet[9], g_dSr[1]; |
long error=0; |
//initialising variables |
for (j=0; j<max_ngcomp; j++) { |
k1[j]=0; |
k2[j]=0; |
k3[j]=0; |
k4[j]=0; |
k5[j]=0; |
k6[j]=0; |
y1[j]=0; |
y2[j]=0; |
y3[j]=0; |
y4[j]=0; |
y5[j]=0; |
y6[j]=0; |
y_hat[j]=0; |
y_til[j]=0; |
y_err[j]=0; |
if(j<max_ngstrain) { |
strain_gen_aux[j]=0; |
dstrain_gen_aux[j]=0; |
} |
} |
//} |
//{ preparation |
// set initial substep length |
2828,7 → 2998,7 |
//{ first call to calc_fsigq |
// calculate initial vector of coefficients for the first stage of Runge-Kutta method |
convert_from_general (y1, g_signet, g_othervar, (ngstress-6), 1); |
g_Sr = g_othervar[0]; |
convert_from_general (strain_gen_aux, g_ddum9, g_othervar, (ngstrain-6), 2); |
g_suction=g_othervar[0]; |
2871,7 → 3041,7 |
//{ second call to calc_fsigq |
// calculate coefficients for the second stage of Runge-Kutta method |
convert_from_general (y2, g_signet, g_othervar, (ngstress-6), 1); |
g_Sr = g_othervar[0]; |
convert_from_general (strain_gen_aux, g_ddum9, g_othervar, (ngstrain-6), 2); |
g_suction=g_othervar[0]; |
2904,7 → 3074,7 |
//{ third call to calc_fsigq |
// calculate coefficients for the third stage of Runge-Kutta method |
convert_from_general (y3, g_signet, g_othervar, (ngstress-6), 1); |
g_Sr = g_othervar[0]; |
convert_from_general (strain_gen_aux, g_ddum9, g_othervar, (ngstrain-6), 2); |
g_suction=g_othervar[0]; |
2937,7 → 3107,7 |
//{ fourth call to calc_fsigq |
// calculate coefficients for the fourth stage of Runge-Kutta method |
convert_from_general (y4, g_signet, g_othervar, (ngstress-6), 1); |
g_Sr = g_othervar[0]; |
convert_from_general (strain_gen_aux, g_ddum9, g_othervar, (ngstrain-6), 2); |
g_suction=g_othervar[0]; |
2970,7 → 3140,7 |
//{ fifth call to calc_fsigq |
// calculate coefficients for the fifth stage of Runge-Kutta method |
convert_from_general (y5, g_signet, g_othervar, (ngstress-6), 1); |
g_Sr = g_othervar[0]; |
convert_from_general (strain_gen_aux, g_ddum9, g_othervar, (ngstrain-6), 2); |
g_suction=g_othervar[0]; |
3003,7 → 3173,7 |
//{ sixth call to calc_fsigq |
// calculate coefficients for the sixth stage of Runge-Kutta method |
convert_from_general (y6, g_signet, g_othervar, (ngstress-6), 1); |
g_Sr = g_othervar[0]; |
convert_from_general (strain_gen_aux, g_ddum9, g_othervar, (ngstrain-6), 2); |
g_suction=g_othervar[0]; |
3177,7 → 3347,7 |
} |
void General_model::garray_subtract (double a[], double b[], double c[], long int n) { |
register long int i=0; |
long int i=0; |
for (i=0; i<n; i++) c[i] = a[i] - b[i]; |
} |
3204,7 → 3374,7 |
return sqrt(s); |
} |
long Hypoplasti_unsat_expansive_thermal::correct_statev_values(double strain_gen[], double stress_gen[], |
long Hypoplasti_unsat_expansive_thermal::correct_statev_values(double strain_gen[], double stress_gen[], |
double qstatev[], double dstrain_gen[], int call) { |
//BEGIN tension cutoff |
3213,18 → 3383,18 |
convert_from_general (strain_gen, ddum9, othervar, ngstrain-6, 2); |
double suction=othervar[0]; |
double Temper=othervar[1]; |
double signet[9]={0,0,0,0,0,0,0,0,0}; |
convert_from_general (stress_gen, signet, othervar, ngstress-6, 1); |
double sigef[9]={0,0,0,0,0,0,0,0,0}; |
double SrM=qstatev[6]; |
make_sig_unsat(signet, suction, SrM, sigef, suction); |
double chixsuction=sigef[0]-signet[0]; |
double signet_corrected[9]={0,0,0,0,0,0,0,0,0}; |
garray_move(signet, signet_corrected, 9); |
bool printstat=false; |
if(sigef[0]>0) { |
printstat=true; |
3243,12 → 3413,12 |
} |
long errormath = 0; |
if(debug & printstat & call != 4) { |
if (call == 3) errormath++; |
cout<<"Correcting signet, call "<<call<<", signet[0]="<<signet[0]<<", signet[4]="<<signet[4]<<", signet[8]="<<signet[8]<<", sigef[0]="<<sigef[0]<<", sigef[4]="<<sigef[4]<<", sigef[8]="<<sigef[8]<<", suction="<<suction<<", dsuction="<<dstrain_gen[6]<<", SrM="<<SrM<<endl; |
cout<<"Correcting signet, call "<<call<<", signet[0]="<<signet[0]<<", signet[4]="<<signet[4]<<", signet[8]="<<signet[8]<<", sigef[0]="<<sigef[0]<<", sigef[4]="<<sigef[4]<<", sigef[8]="<<sigef[8]<<", suction="<<suction<<", dsuction="<<dstrain_gen[6]<<", SrM="<<SrM<<endl; |
garray_move(signet_corrected, signet, 9); |
} |
convert_to_general(stress_gen, signet, othervar, ngstress-6, 1); |
//END tension cutoff |
3256,7 → 3426,7 |
for(int i=0; i<ngstrain; i++) {if(isnan( dstrain_gen[i] )) errormath++;} |
for(int i=0; i<ngstress; i++) {if(isnan( stress_gen[i] )) errormath++;} |
for(int i=0; i<nstatev; i++) {if(isnan( qstatev[i] )) errormath++;} |
return(errormath); |
} |
3264,14 → 3434,14 |
//Check that dSr/ds is not negative, which is not physical |
if(strain_gen[6]>sairentry0 && DDtan_gen[54]<0) DDtan_gen[54]=0; |
//check NAN error of stiffness matrix |
long errormath = 0; |
long errormath = 0; |
for(int j=0; j<ngstress*ngstrain; j++) if(isnan(DDtan_gen[j])) errormath += 1; |
return (errormath); |
}; |
bool General_model::check_math_error() { |
bool matherror=test_math_err(); |
long General_model::check_math_error() { |
long matherror=test_math_err(); |
errno = 0; |
if(matherror) return(true); |
else return(false); |
if(matherror) return(matherror); |
else return(0); |
} |
/trunk/SIFEL/MEFEL/SRC/generalmod.h |
---|
41,7 → 41,7 |
struct General_model { |
//Numbers of variables |
int nparms, nstatev, ngstrain, ngstress; |
int nparms, nstatev, ngstrain, ngstress, voidrat_index, Sr_index; |
static const int max_ngstrain = 8; |
static const int max_ngstress = 7; |
static const int max_nstatev = 20; |
50,14 → 50,14 |
static const int nrkf_statev = 4; |
bool debug; |
General_model(int np, int ns, int ngstra, int ngstre) : nparms(np), nstatev(ns), ngstrain(ngstra), ngstress(ngstre) {}; |
General_model(int np, int ns, int ngstra, int ngstre, int vri, int Sri) : nparms(np), nstatev(ns), ngstrain(ngstra), ngstress(ngstre), voidrat_index(vri), Sr_index(Sri) {}; |
//Updated soil_model with Runge-Kutta schemes |
virtual long soil_model(double strain_gen[], double stress_gen[], double qstatev[], |
double dstrain_gen[], double dtime, double *DDtan_gen, double parms[], double rkf_statev[], double rkf_parms[], int flag, int kinc=0, int ipp=0) {return(0);}; |
virtual bool calc_fsigq(double signet[9], double suction, double Temper, double *qstatev, |
double deps[9], double dsuction, double dTemper, double dtime, |
double deps[9], double dsuction, double dTemper, double dtime, |
double dsignet[9], double &Sr_new, double dqstatev[], int kinc) {return(0);}; |
//Functions for general stress-full 9x9 convention conversion |
108,7 → 108,7 |
//Additional routines |
long rkf_redstep (double rc, double &h, double hmin); |
bool check_math_error(); |
long check_math_error(); |
virtual long correct_statev_values(double strain_gen[], double stress_gen[], double qstatev[], double dstrain_gen[], int call) {return(0);}; |
virtual long correct_DDtan_gen(double strain_gen[], double stress_gen[], double *DDtan_gen) {return(0);}; |
}; |
117,12 → 117,14 |
/****************** double-porosity structure, thermal effects. Updated version ***********************************/ |
struct Hypoplasti_unsat_expansive_thermal : General_model { |
Hypoplasti_unsat_expansive_thermal() : General_model(c_nparms, c_nstatev, c_ngstrain, c_ngstress){}; |
Hypoplasti_unsat_expansive_thermal() : General_model(c_nparms, c_nstatev, c_ngstrain, c_ngstress, c_voidrat_index, c_Sr_index){}; |
static const int c_ngstrain = 8; |
static const int c_ngstress = 7; |
static const int c_nstatev = 9; |
static const int c_nparms = 23; |
static const int c_voidrat_index = 0; |
static const int c_Sr_index = 2; |
static const bool debug = false; |
//Model parameters and other constants |
139,6 → 141,9 |
/* functions which distinguish original and updated versions */ |
virtual double give_rlambda(double suction, double a_scan, double dsuction, double sewM, double SrM, double& rlambda_for_ascan, double& rlambda_for_se); |
virtual void give_fm(double& fm, double& fm_lambda_act, double suction, double sewM, double re, bool swelling); |
virtual double give_demdpm(double pefsat, double em); |
virtual double init_em_pefsat(double pefsat); |
//Model-specific routines |
void initialise_variables(double strain_gen[], double stress_gen[], double qstatev[], double dstrain_gen[], double dtime, |
145,7 → 150,7 |
double parms[], int kinc); |
void initialise_parameters(double parms[]); |
bool calc_fsigq(double signet[9], double suction, double Temper, double *qstatev, |
double deps[9], double dsuction, double dTemper, double dtime, |
double deps[9], double dsuction, double dTemper, double dtime, |
double dsignet[9], double &Sr_new, double dqstatev[], int kinc); |
void update_hisv(double signet[9], double suction, double Temper, double *qstatev, |
double deps[9], double dsuction, double dTemper, |
152,15 → 157,14 |
double dsignet[9], double &Sr, double *dqstatev, int flag, double fu, int kinc); |
void make_sig_unsat(double sig[3*3], double suction, double SrM, |
double tensor_unsat[3*3], double &scalar_unsat); |
void calc_depm(double signet[9], double suction, double Temper, double dsuction, |
double dTemper, double dsignet[9], double depm[9], double fu); |
double calc_trdepm(double signet[9], double suction, double Temper, double em, double dsuction, |
double dTemper, double dsignet[9], double fu); |
void calc_N_lambda_dpeds(double &Nuse, double &lambda_use, double &dpeds_divpe, double &dpedT_divpe, |
double signet[9], double suction, double Temper, double *qstatev); |
void give_LNH(double signet[9], double dsuction, double Temper, double qstatev[], |
double hypo_L[3][3][3][3], double hypo_N[3][3], double H_unsat[3][3], double HT_unsat[3][3], double fm, |
double hypo_L[3][3][3][3], double hypo_N[3][3], double H_unsat[3][3], double HT_unsat[3][3], bool swelling, |
double &fu); |
void direct_stiffness_matrix(double strain_gen[], double stress_gen[], double qstatev[], double dstrain_gen[], |
double dtime, double *DDtan_gen, double parms[], int kinc); |
void direct_stiffness_matrix(double strain_gen[], double stress_gen[], double qstatev[], double dstrain_gen[], double dtime, double *DDtan_gen, double parms[], int kinc, int flag); |
double give_SrM_new(double suction, double SrM, double eM, double Temper, double sewM, double se, double dsuction, double deM, double dTemper, double a_scan, int flag); |
//Additional routines |
173,11 → 177,27 |
/* Version "Mašín, D. (2017). Coupled thermohydromechanical double structure model for expansive soils. ASCE Journal of Engineering Mechanics 143, No. 9." |
*/ |
struct Hypoplasti_unsat_expansive_thermal_original : Hypoplasti_unsat_expansive_thermal { |
Hypoplasti_unsat_expansive_thermal_original() : Hypoplasti_unsat_expansive_thermal(){}; |
struct Hypoplasti_unsat_expansive_thermal_2017 : Hypoplasti_unsat_expansive_thermal { |
Hypoplasti_unsat_expansive_thermal_2017() : Hypoplasti_unsat_expansive_thermal(){}; |
/* functions which distinguish original and updated versions */ |
virtual double give_rlambda(double suction, double a_scan, double dsuction, double sewM, double SrM, double& rlambda_for_ascan, double& rlambda_for_se); |
virtual void give_fm(double& fm, double& fm_lambda_act, double suction, double sewM, double re, bool swelling); |
}; |
/****************** Hypoplasticity for unsaturated soils, expansive soils with *******************/ |
/****************** double-porosity structure, thermal effects. ***********************************/ |
/* Version "Svoboda, J., Mašín, D., Najser, J. Vašíček, R., Hanusová, I. and Hausmannová, L. (2022). BCV bentonite hydromechanical behaviour and modelling. Acta Geotechnica (in print). |
" |
*/ |
struct Hypoplasti_unsat_expansive_thermal_2022 : Hypoplasti_unsat_expansive_thermal { |
Hypoplasti_unsat_expansive_thermal_2022() : Hypoplasti_unsat_expansive_thermal(){}; |
/* functions which distinguish original and updated versions */ |
virtual double give_rlambda(double suction, double a_scan, double dsuction, double sewM, double SrM, double& rlambda_for_ascan, double& rlambda_for_se); |
virtual void give_fm(double& fm, double& fm_lambda_act, double suction, double sewM, double re, bool swelling); |
}; |
#endif |
/trunk/SIFEL/MEFEL/SRC/global.cpp |
---|
93,6 → 93,7 |
Neval = 0.0; |
Omp_wtime = 0.0; |
Elemfrc = NULL; |
} |
106,7 → 107,7 |
Modified by Tomas Koudelka, 08.2021 |
*/ |
void delete_glob(void) |
{ |
{ |
delete Smat; Smat = NULL; |
delete Mmat; Mmat = NULL; |
delete Dmat; Dmat = NULL; |
175,6 → 176,8 |
delete Pqifc; Pqifc = NULL; |
delete Tlatt; Tlatt = NULL; |
delete [] Elemfrc; |
Ndofm = Mespr = 0; |
} |
/trunk/SIFEL/MEFEL/SRC/global.h |
---|
96,6 → 96,7 |
class quadrilatkirch; |
class dkq; |
class tetralattice; |
struct vector; |
#endif |
#ifndef EXTERN |
328,6 → 329,9 |
EXTERN double Omp_wtime; |
// array of element internal force vectors Elemfrc[i][j] means j-th component of internal force vector of i-th element |
EXTERN vector *Elemfrc; |
/// function initializes all global variables to null values |
void initnull_glob (void); |
/trunk/SIFEL/MEFEL/SRC/globmat.cpp |
---|
24,6 → 24,9 |
#include <omp.h> |
#endif |
//#define DEBUGELEMFRC |
//#include <chrono> |
//#include <thread> |
/** |
Function assembles stiffness %matrix. |
59,12 → 62,11 |
if (Mp->lbtype==1) |
abort (); |
/* |
FILE *ma; |
ma=fopen ("matice.txt","w"); |
*/ |
//FILE *ma; |
//ma=fopen ("matice.txt","w"); |
for (i=0;i<Mt->ne;i++){ |
if (Gtm->leso[i]==1){ |
// only active elements are assembled |
140,10 → 142,12 |
Smat->localize (lm,cn,i); |
} |
} |
/* |
Smat->printmat (ma); |
fclose (ma); |
*/ |
//Smat->printmat (ma); |
//fclose (ma); |
/* |
fclose (ma); |
509,11 → 513,24 |
vector ifor, aifor; |
vector r, mstr; |
matrix bd, dd; |
ivector h(Ndofm); |
long hi = 0; |
// function computes strains at integration points |
if (Mp->strcomp) |
compute_ipstrains (lcid); |
#ifdef DEBUGELEMFRC |
if (Elemfrc == NULL){ |
Elemfrc = new vector[Mt->ne]; |
for (i=0; i<Mt->ne; i++){ |
ndofe = Mt->give_ndofe (i); |
reallocv(ndofe, Elemfrc[i]); |
} |
} |
#endif |
// number of elements |
long ne=Mt->ne; |
#ifdef INC_OPENMP |
528,16 → 545,18 |
#pragma omp parallel \ |
num_threads(Numth),\ |
private(i, j, ndofe, ndofemn, eid, cn, err, ifor, aifor, r, mstr, bd, dd),\ |
firstprivate(ncomp) |
firstprivate(ncomp), shared(intfor, hi, h) |
{ |
#pragma omp for nowait, reduction(+:mstresscomp[:6]) |
#pragma omp for reduction(+:mstresscomp[:6]) |
#endif |
for (i=0;i<ne;i++){ |
for (i=0;i<ne;i++) { |
if (Gtm->leso[i]==1){ |
#ifdef INC_OPENMP |
//eid = Gtm->ompelord[i]; |
eid = i; |
// if (omp_get_thread_num() == 1) |
// std::this_thread::sleep_for(std::chrono::milliseconds(1)); |
#else |
eid = i; |
#endif |
583,8 → 602,8 |
if (mstress_cn[j]){ |
#ifdef INC_OPENMP |
mstresscomp[j] += ifor[j]; |
//#pragma omp atomic update |
// intfor[mstress_cn[j]-1] += ifor[j]; |
#pragma omp atomic update |
intfor[mstress_cn[j]-1] += ifor[j]; |
#else |
intfor[mstress_cn[j]-1] += ifor[j]; |
#endif |
603,9 → 622,21 |
} |
else{ |
// the element does not contain hanging node nor homogenization |
locglob (intfor,ifor.a,cn.a,ndofe); |
#ifdef INC_OPENMP |
#pragma omp critical |
{ |
h[hi] = hi; |
hi++; |
locglob (intfor,ifor.a,cn.a,ndofe); |
} |
#else |
locglob (intfor,ifor.a,cn.a,ndofe); |
#endif |
} |
} |
#ifdef DEBUGELEMFRC |
copyv(ifor, Elemfrc[i]); |
#endif |
} |
#ifdef INC_OPENMP |
} |
624,6 → 655,30 |
druntime = (clock() - druntime)/(double)CLOCKS_PER_SEC; |
Omp_wtime += druntime; |
#endif |
#ifdef DEBUGELEMFRC |
fprintf(Out, "\nistep=%ld, jstep=%ld\n", Mp->istep, Mp->jstep); |
// nullv (intfor,Ndofm); |
for(i=0; i<Mt->ne; i++){ |
/* ndofe=Mt->give_ndofe(i); |
ndofemn = Gtm->give_ndofe (i); |
reallocv (RSTCKIVEC(ndofemn,cn)); |
Mt->give_code_numbers (i,cn.a); |
locglob (intfor,Elemfrc[i].a, cn.a, ndofe);*/ |
fprintf(Out, "eid=%4ld\n", i+1); |
for(j=0; j<Elemfrc[i].n; j++) |
fprintf(Out, " % .15le", Elemfrc[i][j]); |
fprintf(Out, "\n"); |
} |
fprintf(Out, "\nElement order: istep=%ld, jstep=%ld\n", Mp->istep, Mp->jstep); |
for(i=0; i<Mt->ne; i++) |
fprintf(Out, "%5ld\n", h(i)); |
/* |
fprintf(Out, "\nInternal force vector: istep=%ld, jstep=%ld\n", Mp->istep, Mp->jstep); |
for(i=0; i<Ndofm; i++){ |
fprintf(Out, " % .15le\n", intfor[i]); |
}*/ |
fflush(Out); |
#endif |
} |
1039,7 → 1094,7 |
for(i=0; i<Mm->tnip; i++) |
{ |
u = Mm->givenonmechq(pore_pressure, i); |
u = Mm->givenonmechq(eff_pore_pressure, i); |
reallocv(RSTCKVEC(Mm->ip[i].ncompstr, sig)); |
sigt[0] = sigt[1] = sigt[2] = u; |
give_red_vector(sigt,sig,Mm->ip[i].ssst); |
1381,7 → 1436,110 |
} |
/** |
The function extracts prescribed displacements on one element. |
@param lcid - number of load case |
@param eid - element id |
@param r - array of prescribed displacements, it is output parameter |
@return The function returns extracted prescribed displacements in the array r from previous time step. Only for time-dependent problems. |
20/04/2023 by TKr according to JK |
*/ |
void elprevprdispl (long lcid,long eid,double *r) |
{ |
long i,ii,ndofe,ndofemn; |
double oldtime; |
ivector cn,nod,ncn; |
vector rr; |
// the number of DOFs on element |
// this number is equal to the number of DOFs without hanging nodes |
ndofe = Mt->give_ndofe (eid); |
// the number of DOFs on element |
// this number is equal to the number of DOFs with master nodes generated by hanging nodes |
ndofemn = Gtm->give_ndofe (eid); |
if (ndofe != ndofemn){ |
// there are hanging nodes on element |
reallocv (RSTCKIVEC(ndofemn,cn)); |
reallocv (RSTCKVEC(ndofemn,rr)); |
ndofe=ndofemn; |
} |
else{ |
// there are no hanging nodes on element |
reallocv (RSTCKIVEC(ndofe,cn)); |
reallocv (RSTCKVEC(ndofe,rr)); |
} |
// code numbers on element |
Mt->give_code_numbers (eid,cn.a); |
switch (Mp->tprob){ |
case forced_dynamics: |
case mech_timedependent_prob:{ |
oldtime = Mp->time-Mp->timecon.backwarddt; |
// lcid must be equal to zero |
for (i=0;i<ndofe;i++){ |
ii=cn[i]; |
if (ii<0) |
rr[i]=Mb->dlc[lcid].get_pd(oldtime, ii); |
} |
break; |
} |
case growing_mech_structure:{ |
oldtime = Mp->time-Mp->timecon.backwarddt; |
// lcid must be equal to zero |
// loop over the number of DOFs on element (including DOFs in hanging nodes) |
for (i=0;i<ndofe;i++){ |
ii=cn[i]; |
if (ii<0) |
rr[i]=Mb->dlc[lcid].get_pd(oldtime, ii); |
} |
// initial displacements from previous free state of dof |
// in the case that the dof has got support or prescribed displacement actually |
// must not be included to the computation of the right hand side because |
// the displacements of the neighbour free dofs are already included in the |
// displacement vector (r) as well as in the load vector from the previous time step (fp) |
break; |
} |
default:{ |
print_err("unknown type of problem is required", __FILE__, __LINE__, __func__); |
} |
}// end of the switch (Mp->tprob) |
// the variables ndofe and ndofemn have to be obtained again |
// because they are possibly rewritten |
// |
// the number of DOFs on element |
// this number is equal to the number of DOFs without hanging nodes |
ndofe = Mt->give_ndofe (eid); |
// the number of DOFs on element |
// this number is equal to the number of DOFs with master nodes generated by hanging nodes |
ndofemn = Gtm->give_ndofe (eid); |
if (ndofe != ndofemn){ |
// there are hanging nodes on element |
mxv (Mt->elements[eid].tmat->a,rr.a,r,ndofe,ndofemn); |
} |
else{ |
// there are no hanging nodes on element |
copyv (rr,r); |
} |
if (Mp->tprob == growing_mech_structure){ |
// subtraction of initial displacements |
Mt->elements[eid].subtrinitdispl (r,ndofe); |
} |
} |
/** |
The function extracts displacements on one node with the index nid and stores them in the %vector r. |
/trunk/SIFEL/MEFEL/SRC/globmat.h |
---|
25,6 → 25,7 |
void eldispl (long lcid,long eid,double *r); |
void elprdispl (long lcid,long eid,double *r); |
void elprevprdispl (long lcid,long eid,double *r); |
void noddispl (long lcid,double *r, long nid); |
void select_noddispl (long lcid,double *r,long nid); |
/trunk/SIFEL/MEFEL/SRC/homogmatm.cpp |
---|
0,0 → 1,412 |
/* |
File: homogmatm.cpp |
Author: Tomas Krejci, 22/07/2022 |
Purpose: Calculates properties of homogenized elastic material |
*/ |
#include "mechmat.h" |
#include "probdesc.h" |
#include "homogmatm.h" |
#include "matrix.h" |
#include "vector.h" |
#include "stochdriver.h" |
#include "global.h" |
#include "intpoints.h" |
#include "vecttens.h" |
/** |
Constructor initializes data members to zero or default values. |
Created by TKr, |
*/ |
homogmatm::homogmatm (void) |
{ |
allocm (6,6,dd); |
hom_mattypem = 0; |
hom_mattypem_number = 0; |
} |
/** |
Destructor is defined only for the formal purposes. |
Created by TKr, |
*/ |
homogmatm::~homogmatm (void) |
{ |
destrm(dd); |
} |
/** |
Function reads material parameters from the opened text file. |
@param in - pointer to the opened XFILE |
@return The function does not return anything. |
Created by TKr, |
*/ |
void homogmatm::read (XFILE *in) |
{ |
xfscanf (in,"%ld %ld",&hom_mattypem,&hom_mattypem_number); |
hom_mattypem_number = hom_mattypem_number-1; |
} |
/** |
Function prints material parameters into the opened text file. |
@param out - pointer to the opened FILE |
@return The function does not return anything. |
Created by TKr |
*/ |
void homogmatm::print (FILE *out) |
{ |
fprintf (out," %ld %ld",hom_mattypem,hom_mattypem_number+1); |
} |
/** |
Function assembles stiffness %matrix of material. |
@param d - stiffness %matrix of material (output) |
@param ssst - strain/stress state |
@return The function returns material stiffness %matrix in the parameter d. |
Created by TKr |
*/ |
void homogmatm::matstiff (matrix &d,strastrestate ssst) |
{ |
switch (ssst){ |
case planestress:{ |
matstiff_plstress (d); |
break; |
} |
case planestrain:{ |
matstiff_plstrain (d); |
break; |
} |
case axisymm:{ |
matstiff_axi (d); |
break; |
} |
case spacestress:{ |
matstiff_spacestr (d); |
break; |
} |
default:{ |
print_err("unknown number of components of stress tensor is required", __FILE__, __LINE__, __func__); |
} |
} |
} |
/** |
Function creates stiffness matrix of the elastic |
isotropic material for 2D problems (plane stress). |
@param d - stiffness matrix of the material |
@return The function returns material stiffness %matrix in the parameter d. |
Created by TKr |
*/ |
void homogmatm::matstiff_plstress (matrix &d) |
{ |
d[0][0] = dd[0][0]; d[0][1] = dd[0][1]; d[0][2] = dd[0][2]; |
d[1][0] = dd[1][0]; d[1][1] = dd[1][1]; d[1][2] = dd[1][2]; |
d[2][0] = dd[2][0]; d[2][1] = dd[2][1]; d[2][2] = dd[2][2]; |
} |
/** |
Function creates stiffness %matrix of the elastic |
isotropic material for 2D problems (plane strain). |
@param d - stiffness %matrix of the material |
@return The function returns material stiffness %matrix in the parameter d. |
Created by TKr |
*/ |
void homogmatm::matstiff_plstrain (matrix &d) |
{ |
d[0][0] = dd[0][0]; d[0][1] = dd[0][1]; d[0][2] = dd[0][2]; |
d[1][0] = dd[1][0]; d[1][1] = dd[1][1]; d[1][2] = dd[1][2]; |
d[2][0] = dd[2][0]; d[2][1] = dd[2][1]; d[2][2] = dd[2][2]; |
// zde rozmyslet |
if (d.m > 3) |
{ |
d[0][3] = dd[0][1]; d[1][3] = dd[1][0]; |
d[3][0] = dd[1][0]; d[3][1] = dd[1][0]; d[3][3] = dd[1][1]; |
} |
} |
/** |
Function creates stiffness %matrix of the elastic |
isotropic material for 2D axisymmetric problems. |
@param d - stiffness %matrix of the material |
@return The function returns material stiffness %matrix in the parameter d. |
Created by TKr, 19.7.2001 |
*/ |
void homogmatm::matstiff_axi (matrix &d) |
{ |
d[0][0] = dd[0][0]; d[0][1] = dd[0][1]; d[0][2] = dd[0][2]; d[0][3] = dd[0][3]; |
d[1][0] = dd[1][0]; d[1][1] = dd[1][1]; d[1][2] = dd[1][2]; d[1][3] = dd[1][3]; |
d[2][0] = dd[2][0]; d[2][1] = dd[2][1]; d[2][2] = dd[2][2]; d[2][3] = dd[2][3]; |
d[3][0] = dd[3][0]; d[3][1] = dd[3][1]; d[3][2] = dd[3][2]; d[3][3] = dd[3][3]; |
} |
/** |
Function creates stiffness %matrix of the elastic |
isotropic material for 3D problems. |
@param d - stiffness %matrix of the material |
Created by TKr |
*/ |
void homogmatm::matstiff_spacestr (matrix &d) |
{ |
d[0][0] = dd[0][0]; d[0][1] = dd[0][1]; d[0][2] = dd[0][2]; d[0][3] = dd[0][3]; d[0][4] = dd[0][4]; d[0][5] = dd[0][5]; |
d[1][0] = dd[1][0]; d[1][1] = dd[1][1]; d[1][2] = dd[1][2]; d[1][3] = dd[1][3]; d[1][4] = dd[1][4]; d[1][5] = dd[1][5]; |
d[2][0] = dd[2][0]; d[2][1] = dd[2][1]; d[2][2] = dd[2][2]; d[2][3] = dd[2][3]; d[2][4] = dd[2][4]; d[2][5] = dd[2][5]; |
d[3][0] = dd[3][0]; d[3][1] = dd[3][1]; d[3][2] = dd[3][2]; d[3][3] = dd[3][3]; d[3][4] = dd[3][4]; d[3][5] = dd[3][5]; |
d[4][0] = dd[4][0]; d[4][1] = dd[4][1]; d[4][2] = dd[4][2]; d[4][3] = dd[4][3]; d[4][4] = dd[4][4]; d[4][5] = dd[4][5]; |
d[5][0] = dd[5][0]; d[5][1] = dd[5][1]; d[5][2] = dd[5][2]; d[5][3] = dd[5][3]; d[5][4] = dd[5][4]; d[5][5] = dd[5][5]; |
} |
/** |
Function assembles compliance %matrix of material. |
@param c - complience %matrix of material (output) |
@param ssst - strain/stress state |
@return The function returns material complience %matrix in the parameter d. |
Created by TKr |
*/ |
void homogmatm::matcompl (matrix &c,strastrestate ssst) |
{ |
matrix d; |
allocm (6,6,d); |
matstiff (d,ssst); |
//c = invm(d); |
destrm(d); |
} |
/** |
function assembles the conductivity %matrix after homogenization |
@param d - array of %matrix entries |
Created by TKr |
*/ |
void homogmatm::assemble_matrices (double *d,long ncomp,long dim) |
{ |
if (ncomp == 3){ |
dd[0][0]=d[0]; dd[0][1]=d[1]; dd[0][2]=d[2]; |
dd[1][0]=d[3]; dd[1][1]=d[4]; dd[1][2]=d[5]; |
dd[2][0]=d[6]; dd[2][1]=d[7]; dd[2][2]=d[8]; |
/* fprintf (Out,"\n"); |
fprintf (Out,"\n\n d[0] = %e",d[0]); |
fprintf (Out,"\n\n d[1] = %e",d[1]); |
fprintf (Out,"\n\n d[2] = %e",d[2]); |
fprintf (Out,"\n\n d[3] = %e",d[3]); |
fprintf (Out,"\n\n d[4] = %e",d[4]); |
fprintf (Out,"\n\n d[5] = %e",d[5]); |
fprintf (Out,"\n\n d[6] = %e",d[6]); |
fprintf (Out,"\n\n d[7] = %e",d[7]); |
fprintf (Out,"\n\n d[8] = %e",d[8]); |
fprintf (Out,"\n"); |
fflush(Out); |
*/ |
} |
if (ncomp == 4){ |
dd[0][0]=d[0]; dd[0][1]=d[1]; dd[0][2]=d[2]; dd[0][3]=d[3]; |
dd[1][0]=d[4]; dd[1][1]=d[5]; dd[1][2]=d[6]; dd[1][3]=d[7]; |
dd[2][0]=d[8]; dd[2][1]=d[9]; dd[2][2]=d[10]; dd[2][3]=d[11]; |
dd[3][0]=d[12]; dd[3][1]=d[13]; dd[3][2]=d[14]; dd[3][3]=d[15]; |
} |
if (ncomp == 6){ |
dd[0][0]=d[0]; dd[0][1]=d[1]; dd[0][2]=d[2]; dd[0][3]=d[3]; dd[0][4]=d[4]; dd[0][5]=d[5]; |
dd[1][0]=d[6]; dd[1][1]=d[7]; dd[1][2]=d[8]; dd[1][3]=d[9]; dd[1][4]=d[10]; dd[1][5]=d[11]; |
dd[2][0]=d[12]; dd[2][1]=d[13]; dd[2][2]=d[14]; dd[2][3]=d[15]; dd[2][4]=d[16]; dd[2][5]=d[17]; |
dd[3][0]=d[18]; dd[3][1]=d[19]; dd[3][2]=d[20]; dd[3][3]=d[21]; dd[3][4]=d[22]; dd[3][5]=d[23]; |
dd[4][0]=d[24]; dd[4][1]=d[25]; dd[4][2]=d[26]; dd[4][3]=d[27]; dd[4][4]=d[28]; dd[4][5]=d[29]; |
dd[5][0]=d[30]; dd[5][1]=d[31]; dd[5][2]=d[32]; dd[5][3]=d[33]; dd[5][4]=d[34]; dd[5][5]=d[35]; |
/* fprintf (Out,"\n"); |
fprintf (Out,"\n\n d[0] = %e",d[0]); |
fprintf (Out,"\n\n d[1] = %e",d[1]); |
fprintf (Out,"\n\n d[2] = %e",d[2]); |
fprintf (Out,"\n\n d[3] = %e",d[3]); |
fprintf (Out,"\n\n d[4] = %e",d[4]); |
fprintf (Out,"\n\n d[5] = %e",d[5]); |
fprintf (Out,"\n\n d[6] = %e",d[6]); |
fprintf (Out,"\n\n d[7] = %e",d[7]); |
fprintf (Out,"\n\n d[8] = %e",d[8]); |
fprintf (Out,"\n\n d[9] = %e",d[9]); |
fprintf (Out,"\n\n d[10] = %e",d[10]); |
fprintf (Out,"\n\n d[11] = %e",d[11]); |
fprintf (Out,"\n\n d[12] = %e",d[12]); |
fprintf (Out,"\n\n d[13] = %e",d[13]); |
fprintf (Out,"\n\n d[14] = %e",d[14]); |
fprintf (Out,"\n\n d[15] = %e",d[15]); |
fprintf (Out,"\n\n d[16] = %e",d[16]); |
fprintf (Out,"\n\n d[17] = %e",d[17]); |
fprintf (Out,"\n\n d[18] = %e",d[18]); |
fprintf (Out,"\n\n d[19] = %e",d[19]); |
fprintf (Out,"\n\n d[20] = %e",d[20]); |
fprintf (Out,"\n\n d[21] = %e",d[21]); |
fprintf (Out,"\n\n d[22] = %e",d[22]); |
fprintf (Out,"\n\n d[23] = %e",d[23]); |
fprintf (Out,"\n\n d[24] = %e",d[24]); |
fprintf (Out,"\n\n d[25] = %e",d[25]); |
fprintf (Out,"\n\n d[26] = %e",d[26]); |
fprintf (Out,"\n\n d[27] = %e",d[27]); |
fprintf (Out,"\n\n d[28] = %e",d[28]); |
fprintf (Out,"\n\n d[29] = %e",d[29]); |
fprintf (Out,"\n\n d[30] = %e",d[30]); |
fprintf (Out,"\n\n d[31] = %e",d[31]); |
fprintf (Out,"\n\n d[32] = %e",d[32]); |
fprintf (Out,"\n\n d[33] = %e",d[33]); |
fprintf (Out,"\n\n d[34] = %e",d[34]); |
fprintf (Out,"\n\n d[35] = %e",d[35]); |
fprintf (Out,"\n"); |
fflush(Out); |
*/ |
} |
} |
/** |
This function initializes material model data |
with respect of consistency parameter gamma. |
@param ipp - integration point number |
@param ido - index of internal variables for given material in the ipp other array |
Created by TKr |
*/ |
void homogmatm::initval(long ipp, long im, long ido) |
{ |
//Mm->ip[ipp].other[ido+0] = Mm->ip[ipp].eqother[ido+0] = 0.0; |
//Mm->ip[ipp].other[ido+1] = Mm->ip[ipp].eqother[ido+1] = 0.0; |
} |
/** |
Function computes true stresses. |
@param ipp - number of integration point |
@return The function does not return anything. |
Created by TKr |
*/ |
void homogmatm::nlstresses (long ipp, long im, long ido) |
{ |
long i, n = Mm->ip[ipp].ncompstr; |
vector eps(n),sig(n),epst(ASTCKVEC(6)); |
strastrestate ssst = Mm->ip[ipp].ssst; |
matrix d(n,n); |
// initial values |
for (i=0;i<n;i++){ |
eps[i]=Mm->ip[ipp].strain[i]; |
} |
matstiff (d,ssst); |
mxv (d,eps,sig); |
/* //it is necessary to complete here: |
if (Mm->ip[ipp].ssst == planestress) |
Mm->ip[ipp].strain[3] = -nu / (1.0 - nu) * (eps[0]+eps[1]); |
*/ |
if ((Mp->eigstrains == 4) || (Mp->eigstrains == 5)) |
{ |
for (i=0;i<n;i++) |
sig(i) += Mm->eigstresses[ipp][i]; |
} |
for (i=0;i<n;i++){ |
Mm->ip[ipp].stress[i]=sig(i); |
} |
} |
/** |
This function updates values in the other array reached in the previous equlibrium state to |
values reached in the new actual equilibrium state. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
Created by TKr |
*/ |
void homogmatm::updateval (long ipp,long ido) |
{ |
//Mm->ip[ipp].eqother[ido+0] = Mm->ip[ipp].other[ido+0]; // |
//Mm->ip[ipp].eqother[ido+1] = Mm->ip[ipp].other[ido+1]; // |
} |
/** |
The function returns rate of the volumetric strain rate at the given integration point. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
@return The function returns rate of the volumetric strain. |
Created by TKr according to Tomas Koudelka |
*/ |
double homogmatm::give_strain_vol(long ipp, long ido) |
{ |
//return Mm->ip[ipp].eqother[ido+1]; |
} |
/trunk/SIFEL/MEFEL/SRC/homogmatm.h |
---|
0,0 → 1,49 |
#ifndef HOMOGMATM_H |
#define HOMOGMATM_H |
#include "alias.h" |
#include "genfile.h" |
#include "iotools.h" |
struct matrix; |
struct vector; |
struct atsel; |
/** |
The class homogmatm defines elastic isotropic material model. |
Material parameters are: |
- Young's modulus (modulus of elasticity) |
- Poisson's ratio |
Created by TKr, |
*/ |
class homogmatm |
{ |
public: |
homogmatm (void); |
~homogmatm (void); |
void read (XFILE *in); |
void print (FILE *out); |
void matstiff (matrix &d,strastrestate ssst); |
void matstiff_plstress (matrix &d); |
void matstiff_plstrain (matrix &d); |
void matstiff_axi (matrix &d); |
void matstiff_spacestr (matrix &d); |
void matcompl (matrix &c,strastrestate ssst); |
void assemble_matrices (double *d,long ncomp, long dim); |
void initval(long ipp, long im, long ido); |
void nlstresses (long ipp, long im, long ido); |
void updateval (long ipp,long ido); |
double give_strain_vol(long ipp, long ido); |
matrix dd; |
long hom_mattypem; //material type for mogenization |
long hom_mattypem_number; //number of material for homogenization |
}; |
#endif |
/trunk/SIFEL/MEFEL/SRC/hypoplunsatexptherm2.cpp |
---|
1,1190 → 1,1187 |
#include <stdlib.h> |
#include <float.h> |
#include "generalmod.h" |
#include "global.h" |
#include <stdlib.h> |
#include <float.h> |
#include "generalmod.h" |
#include "global.h" |
#include "probdesc.h" |
#include "mechmat.h" |
#include "mechtop.h" |
#include "intpoints.h" |
#include "element.h" |
#include "tensor.h" |
#include "vecttens.h" |
#include "mathem.h" |
#include "vector.h" |
#include "vecttens.h" |
#include "hypoplunsatexptherm2.h" |
#define nijac 200 |
#define limit 1.0e-15 // zero limit for principal values of tensors (Jacobi method) |
hypoplast_unsat_exp_therm::hypoplast_unsat_exp_therm() |
{ |
phideg = lam_star = kap_star = n_star = 0.0; |
nu = n = l = nt = lt = m = alpha_s = kap_m = sm_star = 0.0; |
em_star = s_airentry0 = em0 = tr = at = bt = lambdap0 = aer = p_t = 0.0; |
// retrieve number of parameters, number of state variables and number of generalized vector components |
nparams=huet.nparms; // number of parameters |
nstatev=huet.nstatev; // number of state variables (10 for actual implementation, see constructor in generalmod.h) |
ngstrain=huet.ngstrain; // number of generalised strain tensor components (8 for actual implementation, see constructor in generalmod.h) |
ngstress=huet.ngstress; // number of generalised stress tensor components (7 for actual implementation, see constructor in generalmod.h) |
nrkfparams=huet.nrkf_parms; // number of RKF method parameters |
nrkfstatev=huet.nrkf_statev; // number of RKF method parameters |
params = new double[nparams]; |
rkfparams = new double[nrkfparams]; |
pr_suc_fl = no; |
pr_tempr_fl = no; |
// maximum value of 'zero' level of state variables for RKF time integration |
// it may be rewritten by RKF tolerance if its value is less than the value specified here |
sv_rkf_zero = 1.0e-3; |
} |
hypoplast_unsat_exp_therm::~hypoplast_unsat_exp_therm() |
{ |
delete [] params; |
delete [] rkfparams; |
} |
/** |
The function reads material parameters from the opened text file given |
by the parameter in. |
@param in - pointer to the opened input text file |
@return The function does not return anything. |
Created by Tomas Koudelka, 30.1.2014 |
*/ |
void hypoplast_unsat_exp_therm::read(XFILE *in) |
{ |
xfscanf(in, "%k %le %k %le %k %le %k %le", |
"phi", &phideg, "lam_star", &lam_star, |
"kap_star", &kap_star, "N_star", &n_star); |
xfscanf(in, "%k %le %k %le %k %le %k %le %k %le %k %le", |
"nu", &nu, "n", &n, "l", &l, "nT", &nt, "lT", <, "m", &m); |
xfscanf(in, "%k %le %k %le %k %le %k %le %k %le %k %le %k %le", |
"alpha_s", &alpha_s, "kap_m", &kap_m, "sm_star", &sm_star, |
"em_star", &em_star, "csh", &csh, "s_airentry0", &s_airentry0, "em0", &em0); |
xfscanf(in, "%k %le %k %le %k %le %k %le %k %le %k %le", |
"tr", &tr, "at", &at, "bt", &bt, |
"aer", &aer, "lambdap0", &lambdap0, "p_t", &p_t); |
// xfscanf(in, "%k %le %k %le","einit", &einit, "ascaninit", &ascaninit); |
xfscanf(in, "%k%m", "presc_suction", &answertype_kwdset, &pr_suc_fl); |
if (pr_suc_fl == yes) |
suc_fn.read(in); |
xfscanf(in, "%k%m", "presc_tempr", &answertype_kwdset, &pr_tempr_fl); |
if (pr_tempr_fl == yes) |
tempr_fn.read(in); |
sra.read(in); |
if (sv_rkf_zero > sra.err) |
sv_rkf_zero = sra.err; |
if (phideg <= 0.0) |
{ |
print_err("phi must be positive (phi = %le)", __FILE__, __LINE__, __func__, phideg); |
abort(); |
} |
if (p_t < 0.0) |
{ |
print_err("p_t must not be negative (p_t = %le)", __FILE__, __LINE__, __func__, p_t); |
abort(); |
} |
if (lam_star <= 0.0) |
{ |
print_err("lam_star must be positive (lam_star = %le)", __FILE__, __LINE__, __func__, lam_star); |
abort(); |
} |
if (kap_star <= 0.0) |
{ |
print_err("kap_star must be positive (kap_star = %le)", __FILE__, __LINE__, __func__, kap_star); |
abort(); |
} |
if (n_star <= 0.0) |
{ |
print_err("n_star must be positive (n_star = %le)", __FILE__, __LINE__, __func__, n_star); |
abort(); |
} |
// temporary check for Mock-up test |
if (aer != 1.0) |
{ |
print_err("temporary check for Mock-up experiment - aer is not set to 1.0 (aer = %le)", __FILE__, __LINE__, __func__, aer); |
abort(); |
} |
// temporary check for Mock-up test |
if (aer != 1.0) |
{ |
print_err("temporary check for Mock-up experiment - aer is not set to 1.0 (aer = %le)", __FILE__, __LINE__, __func__, aer); |
abort(); |
} |
/* |
if (rr <= 0.0) |
{ |
print_err("rr must be positive (rr = %le)", __FILE__, __LINE__, __func__, rr); |
abort(); |
} |
if (s_e0 < 0.0) |
{ |
print_err("s_e0 must not be negative (s_e0 = %le)", __FILE__, __LINE__, __func__, s_e0); |
abort(); |
} |
*/ |
params[0] = phideg; |
params[1] = lam_star; |
params[2] = kap_star; |
params[3] = n_star; |
params[4] = nu; |
params[5] = n; |
params[6] = l; |
params[7] = nt; |
params[8] = lt; |
params[9] = m; |
params[10] = alpha_s; |
params[11] = kap_m; |
params[12] = sm_star; |
params[13] = em_star; |
params[14] = csh; |
params[15] = s_airentry0; |
params[16] = em0; |
params[17] = tr; |
params[18] = at; |
params[19] = bt; |
params[20] = aer; |
params[21] = lambdap0; |
params[22] = p_t; |
//params[21] = einit; |
//params[22] = ascaninit; |
rkfparams[0] = sra.give_err_sig(); |
rkfparams[1] = sra.give_hmin(); |
rkfparams[2] = sra.give_ni(); |
rkfparams[3] = sv_rkf_zero; |
rkfparams[4] = (int)sra.give_rkt(); |
} |
/** |
The function prints material parameters into the opened text file given |
by the parameter out. |
@param out - pointer to the opened output text file |
@return The function does not return anything. |
Created by Tomas Koudelka, koudelka@cml.fsv.cvut.cz, 17.12.2015 |
*/ |
void hypoplast_unsat_exp_therm::print(FILE *out) |
{ |
fprintf(out, "%le %le %le %le\n", |
phideg, lam_star, kap_star, n_star); |
fprintf(out, "%le %le %le %le %le %le\n", |
nu, n, l, nt, lt, m); |
fprintf(out, "%le %le %le %le %le %le %le\n", |
alpha_s, kap_m, sm_star, em_star, csh, s_airentry0, em0); |
fprintf(out, "%le %le %le %le %le %le\n",tr, at, bt, aer, lambdap0, p_t); |
fprintf(out, "%d ", int(pr_suc_fl)); |
if (pr_suc_fl == yes) |
suc_fn.print(out); |
fprintf(out, "%d ", int(pr_tempr_fl)); |
if (pr_tempr_fl == yes) |
tempr_fn.print(out); |
fprintf(out, "\n"); |
sra.print(out); |
} |
/** |
The function initializes material model. Retrieves initial values of the following |
quantities |
@param ipp - integration point number |
@param ido - index of internal variables for given material in the ipp other array |
@return The function does not return anything but updates initial value of Sr and stress vector |
in eqother array. |
Created by Tomas Koudelka, 1.10.2015 |
*/ |
void hypoplast_unsat_exp_therm::initval (long ipp,long ido) |
{ |
// data handled by MEFEL |
long ncomp = Mm->ip[ipp].ncompstr; // number of reduced stress/strain components |
strastrestate ssst = Mm->ip[ipp].ssst; // stress/strain state indicator |
vector sig(ASTCKVEC(ngstress)), eps(ASTCKVEC(ngstrain)); |
vector deps(ASTCKVEC(ngstrain)), dstatev(ASTCKVEC(nstatev)); |
matrix dd_gen(ASTCKMAT(ngstress,ngstrain)); |
double *statev = Mm->ip[ipp].eqother+ido+2*ncomp+3; |
int herr; |
if (statev[0] == 0.0) // initial void ratio was not set => model has not been initialized yet |
{ |
statev[0] = Mm->ic[ipp][0]; // initialize actual value of void ratio |
statev[7] = Mm->ic[ipp][1]; // initialize actual value of ascan |
// set initial value of effective stresses from eigenstresses |
// eigenstress is assumed to be net stress, i.e. sig_{net} = sig_{tot} - u_a.I |
if ((Mp->eigstrains == 4) || (Mp->eigstrains == 5)) |
{ |
for (long i=0; i<ncomp; i++) |
{ |
Mm->ip[ipp].eqother[ido+ncomp+i] = Mm->eigstresses[ipp][i]; |
Mm->ip[ipp].stress[i] = Mm->eigstresses[ipp][i]; |
} |
} |
} |
if (pr_suc_fl == yes) |
statev[1] = suc_fn.getval(Mp->time); //initial prescribed suction pressure s (positive) |
else |
statev[1] = Mm->givenonmechq(suction, ipp); // initial suction pressure s (positive) |
statev[2] = 0.0; // initial degree of saturation S_r |
if (pr_tempr_fl == yes) |
statev[3] = tempr_fn.getval(Mp->time); //initial prescribed temperature |
else |
statev[3] = Mm->givenonmechq(temperature, ipp); // initial temperature T |
give_full_vector(sig.a, Mm->ip[ipp].stress, ssst); |
give_full_vector(eps.a, Mm->ip[ipp].strain, ssst); |
// set remaining components of generalized strain vector |
eps(6) = statev[1]; // set suction to the corresponding component of generalized strain vector |
eps(7) = statev[3]; // set temperature to the corresponding component of generalized strain vector |
// initialize model |
herr = huet.soil_model(eps.a, sig.a, statev, deps.a, 1.0, NULL, params, NULL, rkfparams, 0, Mp->jstep,ipp); |
if (herr) |
{ |
print_err("hypoplasticity model cannot be initialized on element %ld (ip=%ld)", __FILE__, __LINE__, __func__, Mm->elip[ipp]+1, ipp+1); |
abort(); |
} |
statev[2] = sig(6); // store computed initial Sr |
// prepare working copy of array of internal variables |
// eqother values have been already set because statev array is a reference to the eqother array |
copyv(statev, Mm->ip[ipp].other+ido+2*ncomp+3, nstatev); |
// set initial values for dSr/ds and dSr/dT according to generalized stiffness matrix |
herr = huet.soil_model(eps.a, sig.a, statev, NULL, 1.0, dd_gen.a, params, NULL, rkfparams, 3, Mp->jstep,ipp); |
if (herr) |
{ |
print_err("generalized stiffness matrix cannot be initialized on element %ld (ip=%ld)", __FILE__, __LINE__, __func__, Mm->elip[ipp]+1, ipp+1); |
abort(); |
} |
Mm->ip[ipp].eqother[2*ncomp+3+nstatev+8] = dd_gen(ngstress-1, ngstrain-2); // store dSr/ds matrix component |
Mm->ip[ipp].eqother[2*ncomp+3+nstatev+9] = dd_gen(ngstress-1, ngstrain-1); // store dSr/dT matrix component |
Mm->ip[ipp].eqother[ido+2*ncomp+3+nstatev+11] = dd_gen(ngstress-1, 0);//+dd_gen(ngstress-1, 1)+dd_gen(ngstress-1, 2); // compute and store dSr/depsv from matrix components |
// actualize 'consistent' material stiffness matrix |
copym(dd_gen, Mm->ip[ipp].eqother+ido+2*ncomp+3+nstatev+12); |
// actualize other array by the computed values |
memcpy(Mm->ip[ipp].other, Mm->ip[ipp].eqother, sizeof(*Mm->ip[ipp].other)*Mm->ip[ipp].ncompother); |
} |
/** |
The function computes material stiffnes %matrix. |
@param d - allocated matrix structure for material stiffness %matrix (output) |
@param ipp - integration point number |
@param ido - index of internal variables for given material in the ipp other array |
@return The function returns stiffness %matrix in the parameter d. |
Created by Tomas Koudelka, 1.10.2015 |
*/ |
void hypoplast_unsat_exp_therm::matstiff (matrix &d,long ipp,long ido) |
{ |
long i; |
// data handled by MEFEL |
long ncomp = Mm->ip[ipp].ncompstr; |
strastrestate ssst = Mm->ip[ipp].ssst; |
double aux; |
matrix dd_gen(ASTCKMAT(ngstress,ngstrain)), dd(ASTCKMAT(6,6)); |
/* |
vector sig(ASTCKVEC(ngstress)), eps(ASTCKVEC(ngstrain)), deps(ASTCKVEC(ngstrain)); |
vector statev(ASTCKVEC(nstatev)); |
int herr; |
long j; |
// convert stress and strain vectors to full 6 component vectors |
give_full_vector(sig.a, Mm->ip[ipp].stress, ssst); |
give_full_vector(eps.a, Mm->ip[ipp].strain, ssst); |
// stress vector must be reoredred |
// SIFEL ordering is sig11, sig22, sig33, sig23, sig13, sig12 |
// ABAQUS ordering is sig11, sig22, sig33, sig12, sig13, sig23 |
aux = sig(3); |
sig(3) = sig(5); |
sig(5) = aux; |
// strain vector must be reoredred |
// SIFEL ordering is eps11, eps22, eps33, gamma23, gamma13, gamma12 |
// ABAQUS ordering is eps11, eps22, eps33, gamma12, gamma13, gamma23 |
aux = eps(3); |
eps(3) = eps(5); |
eps(5) = aux; |
// assemble generalized strain, stress and strain increment vectors |
eps(6) = Mm->ip[ipp].other[ido+2*ncomp+3+1]; // suction from the actual time step |
eps(7) = Mm->ip[ipp].other[ido+2*ncomp+3+3]; // temperature from the actual time step |
sig(6) = Mm->ip[ipp].other[ido+2*ncomp+3+2]; // degree of saturation Sr from the actual time step |
// prepare working copy of internal variables |
for (i=ido+2*ncomp+3, j=0; i<ido+2*ncomp+3+nstatev; i++, j++) |
statev(j) = Mm->ip[ipp].other[i]; |
herr = huet.soil_model(eps.a, sig.a, statev.a, NULL, NULL, NULL, dd_gen.a, params, 1, Mp->jstep); |
if (herr) |
{ |
print_err("math error detected in hypoplastic model on element %ld (ip=%ld)", __FILE__, __LINE__, __func__, Mm->elip[ipp]+1, ipp+1); |
abort(); |
} |
*/ |
// retrieve actual generalized material stiffness matrix from the other array |
makerefm(dd_gen, Mm->ip[ipp].other+2*ncomp+3+nstatev+12, ngstress, ngstrain); |
// reorder stiffness matrix in the full-length format |
// |
// swap the fourth and sixth columns except of the fourth and sixth elements |
for (i=0; i<ngstress; i++) |
{ |
if ((i == 3) || (i==5)) |
continue; |
aux = dd_gen(i,3); |
dd_gen(i,3) = dd_gen(i,5); |
dd_gen(i,5) = aux; |
} |
// swap the fourth and sixth rows except of the fourth and sixth elements |
for (i=0; i<ngstrain; i++) |
{ |
if ((i == 3) || (i==5)) |
continue; |
aux = dd_gen(3,i); |
dd_gen(3,i) = dd_gen(5,i); |
dd_gen(5,i) = aux; |
} |
// swap elements on intersections of the fourth and sixth columns and rows |
aux = dd_gen(3,3); |
dd_gen(3,3) = dd_gen(5,5); |
dd_gen(5,5) = aux; |
aux = dd_gen(3,5); |
dd_gen(3,5) = dd_gen(5,3); |
dd_gen(5,3) = aux; |
// extract the stiffness matrix for the mechanics |
extractm(dd, dd_gen, 0, 6); |
// convert stiffness matrix to the reduced format suitable for element stiffness matrix |
tensor4_ematrix (d, dd, ssst); |
} |
/** |
The function computes stress increments due to pore pressure change in the integration point and stores |
them into eqother array. |
@param ipp - integration point pointer |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
@return The function does not return anything but stores the resulting values in the eqother array. |
Created by Tomas Koudelka, 11.2015 |
*/ |
void hypoplast_unsat_exp_therm::nlstressesincr (long ipp, long im, long ido) |
{ |
long i, j; |
long ncomp = Mm->ip[ipp].ncompstr; |
strastrestate ssst = Mm->ip[ipp].ssst; |
double aux; |
double ds; |
vector sig(ASTCKVEC(ngstress)), eps(ASTCKVEC(ngstrain)); |
vector statev(ASTCKVEC(nstatev)); |
matrix dd_gen; |
//int herr; |
// This procedure is supposed to be called at the beginning of the actual time step |
// and therefore the ip.stress and ip.strain arrays must contain values |
// from the last equilibrium step |
// convert stress and strain vectors to full 6 component vectors |
give_full_vector(sig.a, Mm->ip[ipp].stress, ssst); |
give_full_vector(eps.a, Mm->ip[ipp].strain, ssst); |
// stress vector must be reoredred |
// SIFEL ordering is sig11, sig22, sig33, sig23, sig13, sig12 |
// ABAQUS ordering is sig11, sig22, sig33, sig12, sig13, sig23 |
aux = sig(3); |
sig(3) = sig(5); |
sig(5) = aux; |
// strain vector must be reoredred |
// SIFEL ordering is eps11, eps22, eps33, gamma23, gamma13, gamma12 |
// ABAQUS ordering is eps11, eps22, eps33, gamma12, gamma13, gamma23 |
aux = eps(3); |
eps(3) = eps(5); |
eps(5) = aux; |
// assemble generalized strain, stress and strain increment vectors |
eps(6) = Mm->ip[ipp].eqother[ido+2*ncomp+3+1]; // suction from the previous time step |
eps(7) = Mm->ip[ipp].eqother[ido+2*ncomp+3+3]; // temperature from the previous time step |
sig(6) = Mm->ip[ipp].eqother[ido+2*ncomp+3+2]; // degree of saturation Sr from the previous time step |
// prepare working copy of internal variables |
for (i=ido+2*ncomp+3, j=0; i<ido+2*ncomp+3+nstatev; i++, j++) |
statev(j) = Mm->ip[ipp].eqother[i]; |
// retrieve actual generalized material stiffness matrix from the other array |
makerefm(dd_gen, Mm->ip[ipp].other+2*ncomp+3+nstatev+12, ngstress, ngstrain); |
/* |
reallocm(RSTCKMAT(dd_gen, ngstress,ngstrain)); |
herr = huet.soil_model(eps.a, sig.a, statev.a, NULL, NULL, NULL, dd_gen.a, params, 3, Mp->jstep); |
if (herr) |
{ |
print_err("math error detected in hypoplastic model on element %ld (ip=%ld)", __FILE__, __LINE__, __func__, Mm->elip[ipp]+1, ipp+1); |
abort(); |
} |
*/ |
if (pr_suc_fl == yes) //prescribed suction pressure s |
ds = (suc_fn.getval(Mp->time)-Mm->ip[ipp].eqother[ido+2*ncomp+3+1]); //suction pressure increment ds = du_a - du_w |
else // suction is obtained from METR |
ds = Mm->givenonmechq(suction, ipp) - Mm->ip[ipp].eqother[ido+2*ncomp+3+1]; |
// calculate negative increment of stresses due to change in suction (-du = -ds*chi) |
// which will be used in calculation of nodal forces and added to the right hand side vector |
// K*dr = df_e - \int B^T*du dV |
for (i=0;i<3;i++) |
Mm->ip[ipp].eqother[ido+2*ncomp+i] = -ds*dd_gen(i,6); |
//Mm->ip[ipp].eqother[ido+2*ncomp+i] = 0.0; |
} |
/** |
The function computes stress increment due to pore pressure change in the integration point and stores |
them into ip stress array. |
@param lcid - load case id |
@param ipp - integration point number |
@param im - index of the material in the tm and idm arrays on integration point |
@param ido - index of internal variables in the ip's ipp eqother array |
@param fi - first index of the required stress increment component |
@param sig - %vector containing stress increment components (output) |
@return The function returns %vector of stress increments in the parameter sig. |
Created by Tomas Koudelka, 11.2015 |
*/ |
void hypoplast_unsat_exp_therm::givestressincr (long lcid, long ipp, long im, long ido, long fi, vector &sig) |
{ |
nullv(sig); |
long i, j, ncomp = Mm->ip[ipp].ncompstr; |
for (i=fi, j=0; i<3 && j<sig.n; i++, j++) |
sig(j) = Mm->ip[ipp].eqother[ido+2*ncomp+i]; |
} |
/** |
The function computes correct stresses in the integration point and stores |
them into ip stress array. |
@param ipp - integration point pointer |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
@return The function does not return anything. |
Created by Tomas Koudelka, 1.10.2015 |
*/ |
void hypoplast_unsat_exp_therm::nlstresses (long ipp, long im, long ido) |
{ |
long i, j, rkf_stat; |
// long herr; |
// data handled by MEFEL |
long ncomp = Mm->ip[ipp].ncompstr; |
long neval = long(Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+5]); |
strastrestate ssst = Mm->ip[ipp].ssst; |
double aux, dtsub, sro; |
double pnewdt = 1.0; // reduction coefficient for new time step |
double dtime = Mp->timecon.actualforwtimeincr(); |
vector sig(ASTCKVEC(ngstress)), eps(ASTCKVEC(ngstrain)), deps(ASTCKVEC(ngstrain)); |
vector statev(ASTCKVEC(nstatev)); |
vector epseq(ASTCKVEC(ngstrain)); |
vector sigeq(ASTCKVEC(ngstress)); |
vector stateveq(ASTCKVEC(nstatev)); |
// rktype rkt = sra.give_rkt(); // type of Runge-Kutta method |
matrix dd_gen(ASTCKMAT(ngstress,ngstrain)); |
// counter of number of steps performed in RKF method within one time step |
long nstep = long(Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+6]); |
// the minimum step length attained in RKF method within one time step |
double mindt = Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+7]; |
// stress array have to contain values from the last attained equilibrium state |
for (i=0; i<ncomp; i++) |
Mm->ip[ipp].stress[i] = Mm->ip[ipp].eqother[ido+ncomp+i]; |
// calculate strain increments and store them in eps temporarily |
for (i=0; i<ncomp; i++) |
eps(i) = Mm->ip[ipp].strain[i]-Mm->ip[ipp].eqother[ido+i]; |
// convert stress, strain and strain increment vectors to full 6 componet vectors |
give_full_vector(sig.a, Mm->ip[ipp].stress, ssst); |
give_full_vector(deps.a, eps.a, ssst); |
nullv(eps); |
give_full_vector(eps.a, Mm->ip[ipp].eqother+ido, ssst); |
// stress vector must be reoredred |
// SIFEL ordering is sig11, sig22, sig33, sig23, sig13, sig12 |
// ABAQUS ordering is sig11, sig22, sig33, sig12, sig13, sig23 |
aux = sig(3); |
sig(3) = sig(5); |
sig(5) = aux; |
// strain vector must be reoredred |
// SIFEL ordering is eps11, eps22, eps33, gamma23, gamma13, gamma12 |
// ABAQUS ordering is eps11, eps22, eps33, gamma12, gamma13, gamma23 |
aux = eps(3); |
eps(3) = eps(5); |
eps(5) = aux; |
// strain increment vector must be reoredred |
// SIFEL ordering is deps11, deps22, deps33, dgamma23, dgamma13, dgamma12 |
// ABAQUS ordering is deps11, deps22, deps33, dgamma12, dgamma13, dgamma23 |
aux = deps(3); |
deps(3) = deps(5); |
deps(5) = aux; |
// assemble generalized strain |
eps(6) = Mm->ip[ipp].eqother[ido+2*ncomp+3+1]; // suction from the previous time step |
eps(7) = Mm->ip[ipp].eqother[ido+2*ncomp+3+3]; // temperature from the previous time step |
// assemble generalized stress vector |
sro = sig(6) = Mm->ip[ipp].eqother[ido+2*ncomp+3+2]; // degree of saturation Sr from the previous time step |
// assemble generalized strain increment vector |
if (pr_suc_fl == yes) //prescribed suction pressure s (positive) |
deps(6) = suc_fn.getval(Mp->time) - Mm->ip[ipp].eqother[ido+2*ncomp+3+1]; // suction increment ds |
else |
deps(6) = Mm->givenonmechq(suction, ipp) - Mm->ip[ipp].eqother[ido+2*ncomp+3+1]; // suction pressure increment ds |
if (pr_tempr_fl == yes) //prescribed temperature T |
deps(7) = tempr_fn.getval(Mp->time) - Mm->ip[ipp].eqother[ido+2*ncomp+3+3]; // temperature increment dT |
else |
deps(7) = Mm->givenonmechq(temperature, ipp) - Mm->ip[ipp].eqother[ido+2*ncomp+3+3]; // temperature increment dT |
// prepare working copy of internal variables from the last equilibrium state |
for (i=ido+2*ncomp+3, j=0; i<ido+2*ncomp+3+nstatev; i++, j++) |
statev(j) = Mm->ip[ipp].eqother[i]; |
dtsub = Mm->ip[ipp].eqother[ido+2*ncomp+3+nstatev]; |
// create copy of strain, stress and state variable vectors from the last equilibrium state |
copyv(eps, epseq); |
copyv(sig, sigeq); |
copyv(statev, stateveq); |
// compute new values of stress vector and state variable increments |
vector rkf_statev(ASTCKVEC(nrkfstatev)); |
rkf_statev[0] = Mm->ip[ipp].eqother[ido+2*ncomp+3+nstatev+5]; |
rkf_statev[1] = Mm->ip[ipp].eqother[ido+2*ncomp+3+nstatev+6]; |
rkf_statev[2] = Mm->ip[ipp].eqother[ido+2*ncomp+3+nstatev+7]; |
rkf_statev[3] = Mm->ip[ipp].eqother[ido+2*ncomp+3+nstatev]; |
//if((Mp->time >= 5.375400e+05) && ipp == 0) |
//fprintf (stdout,"\n zde cas!!"); //debug |
rkf_stat = huet.soil_model(eps.a, sig.a, statev.a, deps.a, dtime, dd_gen.a, params, rkf_statev.a, rkfparams, 1, Mp->jstep, ipp); |
// actualize RKF state variables |
neval = long(rkf_statev[0]); |
nstep = long(rkf_statev[1]); |
mindt = rkf_statev[2]; |
dtsub = rkf_statev[3]; |
// store 'consistent' material stiffness matrix |
copym(dd_gen, Mm->ip[ipp].other+ido+2*ncomp+3+nstatev+12); |
/* |
switch (rkt) |
{ |
case fwdeulert: |
{ |
vector dsig(ASTCKVEC(ngstress)); |
vector dstatev(ASTCKVEC(nstatev)); |
rkf_stat = huet.soil_model(eps.a, sig.a, statev.a, deps.a, dsig.a, dstatev.a, NULL, params, 2, Mp->jstep); |
addv(sig, dsig, sig); |
addv(statev, dstatev, statev); |
neval += 1; |
nstep += 1; |
mindt = 1.0; |
break; |
} |
case heunt: |
rkf_stat = adfwdeuler(eps, sig, statev, deps, dtsub, neval, nstep, mindt); |
break; |
case rkf23t: |
rkf_stat = rkf23(ipp, eps, sig, statev, deps, dtsub, neval, nstep, mindt); |
break; |
case rkf23bst: |
rkf_stat = rkf23bs(eps, sig, statev, deps, dtsub, neval, nstep, mindt); |
break; |
case rkf34t: |
rkf_stat = rkf34(eps, sig, statev, deps, dtsub, neval, nstep, mindt); |
break; |
case rkf45t: |
rkf_stat = rkf45(eps, sig, statev, deps, dtsub, neval, nstep, mindt); |
break; |
default: |
print_err("unknown Runge-Kutta method is required", __FILE__, __LINE__, __func__); |
} |
*/ |
if (rkf_stat){ |
fprintf(Out, "\nRKF failed - rkf_stat=%ld, element=%ld, ip=%ld, loc_ip=%ld, istep=%ld, jstep=%ld, dt=%le", |
rkf_stat, Mm->elip[ipp], ipp, ipp-Mt->elements[Mm->elip[ipp]].ipp[0][0]+1, Mp->istep, Mp->jstep, Mp->timecon.actualforwtimeincr()); |
fprintf(Out, "\nsig\n"); |
printv(Out, sig); |
fprintf(Out, "\neps\n"); |
printv(Out, eps); |
fprintf(Out, "\ndeps\n"); |
printv(Out, deps); |
fprintf(Out, "\nstatev\n"); |
printv(Out, statev); |
fprintf(Out, "\n\n"); |
pnewdt = 0.5; // RKF was not able integrate quantities with required error => decrease time step in the solver |
} |
// stress vector must be reoredred to SIFEL notation |
// SIFEL ordering is sig11, sig22, sig33, sig23, sig13, sig12 |
// ABAQUS ordering is sig11, sig22, sig33, sig12, sig13, sig23 |
aux = sig(3); |
sig(3) = sig(5); |
sig(5) = aux; |
// store stress in reduced notation to the integration point |
give_red_vector(sig.a, Mm->ip[ipp].stress, ssst); |
// actual value of generalized strain vector |
// addv(eps,deps,eps); |
// store actual value of strain vector |
Mm->storeother(ipp, ido, ncomp, Mm->ip[ipp].strain); |
// store actual value of stress vector |
Mm->storeother(ipp, ido+ncomp, ncomp, Mm->ip[ipp].stress); |
// store actual value of state variables |
Mm->storeother(ipp, ido+2*ncomp+3, nstatev, statev.a); |
// store actual value of suction |
Mm->ip[ipp].other[ido+2*ncomp+3+1] = eps(6); |
// store actual value of temperature |
Mm->ip[ipp].other[ido+2*ncomp+3+3] = eps(7); |
// store actual value of RK substep coefficient |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev]= dtsub; |
// store actual value of time step coefficient |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+1]= pnewdt; |
// store actual number of model evaluation - only for testing purposes |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+5]= neval; |
// store actual number of performed RKF steps - only for testing purposes |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+6]= nstep; |
// store the minimum RKF step length - only for testing purposes |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+7]= mindt; |
// volumetric strain rate is computed via generalized trapesoidal rule |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+10]= 0.5*((deps(0)+deps(1)+deps(2))/dtime + Mm->ip[ipp].eqother[ido+2*ncomp+3+nstatev+10]); |
// volumetric strain rate |
//Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+10]= (deps(0)+deps(1)+deps(2))/dtime; |
/* |
// assemble non-mechanical blocks (all except of sig-eps block) of generalized stiffness matrix |
herr = huet.soil_model(epseq.a, sigeq.a, stateveq.a, NULL, NULL, NULL, dd_gen.a, params, 3, Mp->jstep); |
if (herr) |
{ |
print_err("generalized stiffness matrix cannot be assembled on element %ld (ip=%ld)", __FILE__, __LINE__, __func__, Mm->elip[ipp]+1, ipp+1); |
abort(); |
} |
// store derivatives of degree of saturation Sr |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+8] = dd_gen(ngstress-1, ngstrain-2); // store dSr/ds matrix component |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+9] = dd_gen(ngstress-1, ngstrain-1); // store dSr/dT matrix component |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+11] = dd_gen(ngstress-1, 0)+dd_gen(ngstress-1, 1)+dd_gen(ngstress-1, 2); // compute and store dSr/depsv from matrix components |
*/ |
// calculate additional quantities used for output of results |
double epsv; |
// calculate volumetric strain |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+2]= epsv = eps(0)+eps(1)+eps(2); |
// suction increment |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+3]= eps(6)-Mm->ip[ipp].eqother[ido+2*ncomp+3+1]; |
// depsV |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+4]= deps(0)+deps(1)+deps(2); |
/* |
// calculate strain deviator |
epsv *= 1.0/3.0; |
eps(0) -= epsv; |
eps(1) -= epsv; |
eps(2) -= epsv; |
deviator(eps, eps); |
// vertical strain deviator component |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+3]= eps(1); |
// calculate stress deviator |
deviator(sig, sig); |
// vertical stress deviator component |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+4]= sig(1); |
*/ |
} |
/** |
The function reduces step length in Runge-Kutta-Fehlberg methods according to given |
coefficient and minimum step length. |
@param rc - reduction coefficient of step length (input) |
@param h - actual/modified step length (input/output) |
@param hmin - minimum step length (input) |
@retval 0 - On sucessfull step reduction. |
@retval 1 - The minimum step length has been attained and the step cannot be reduced further. |
Created by Tomas Koudelka, 24.5.2016 |
*/ |
long hypoplast_unsat_exp_therm::rkf_redstep(double rc, double &h, double hmin) |
{ |
if (h > hmin) |
{ |
h *= rc; |
if (h < hmin) |
h = hmin; |
return 0; |
} |
else |
return 1; |
} |
/** |
The function returns time step size required by the hypoplsaticity model. It is represented by ratio |
of required time step size to the actual one or 1.0 for no change in time step size. |
@param ipp - integration point number in the mechmat ip array. |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
@return The function returns required time step size provided by the hypoplasticity model |
Created by Tomas Koudelka, 1.10.2015 |
*/ |
double hypoplast_unsat_exp_therm::dstep_red(long ipp, long im, long ido) |
{ |
long ncomp = Mm->ip[ipp].ncompstr; |
return (Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+1]); |
} |
/** |
Function updates values in the other array reached in the previous equlibrium state to |
values reached in the new actual equilibrium state. |
@param ipp - integration point number in the mechmat ip array. |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
@return The function does not return anything. |
Created by Tomas Koudelka, 1.10.2015 |
*/ |
void hypoplast_unsat_exp_therm::updateval (long ipp,long im,long ido) |
{ |
long i, j; |
// long herr; |
long n = Mm->givencompeqother(ipp,im); |
long ncomp = Mm->ip[ipp].ncompstr; |
strastrestate ssst = Mm->ip[ipp].ssst; |
double aux; |
vector sigeq(ASTCKVEC(ngstress)); |
vector epseq(ASTCKVEC(ngstrain)); |
vector stateveq(ASTCKVEC(nstatev)); |
// matrix dd_gen(ASTCKMAT(ngstress,ngstrain)); |
// convert stress, strain and strain increment vectors to full 6 componet vectors |
give_full_vector(epseq.a, Mm->ip[ipp].strain, ssst); |
give_full_vector(sigeq.a, Mm->ip[ipp].stress, ssst); |
// stress vector must be reoredred |
// SIFEL ordering is sig11, sig22, sig33, sig23, sig13, sig12 |
// ABAQUS ordering is sig11, sig22, sig33, sig12, sig13, sig23 |
aux = sigeq(3); |
sigeq(3) = sigeq(5); |
sigeq(5) = aux; |
// strain vector must be reoredred |
// SIFEL ordering is eps11, eps22, eps33, gamma23, gamma13, gamma12 |
// ABAQUS ordering is eps11, eps22, eps33, gamma12, gamma13, gamma23 |
aux = epseq(3); |
epseq(3) = epseq(5); |
epseq(5) = aux; |
// assemble generalized strain increment vector |
if (pr_suc_fl == yes) //prescribed suction pressure s (positive) |
epseq(6) = suc_fn.getval(Mp->time); // suction s defined by user function |
else |
epseq(6) = Mm->givenonmechq(suction, ipp); // suction s from TRFEL |
if (pr_tempr_fl == yes) //prescribed temperature T |
epseq(7) = tempr_fn.getval(Mp->time); // temperature T defined by user function |
else |
epseq(7) = Mm->givenonmechq(temperature, ipp); // temperature T from TRFEL |
// assemble generalized stress vector |
sigeq(6) = Mm->ip[ipp].other[ido+2*ncomp+3+2]; // actual degree of saturation Sr |
// prepare working copy of internal variables from the last equilibrium state |
for (i=ido+2*ncomp+3, j=0; i<ido+2*ncomp+3+nstatev; i++, j++) |
stateveq(j) = Mm->ip[ipp].other[i]; |
/* |
// assemble non-mechanical blocks (all except of sig-eps block) of generalized stiffness matrix |
herr = huet.soil_model(epseq.a, sigeq.a, stateveq.a, NULL, NULL, NULL, dd_gen.a, params, 3, Mp->jstep); |
if (herr) |
{ |
print_err("generalized stiffness matrix cannot be assembled on element %ld (ip=%ld)", __FILE__, __LINE__, __func__, Mm->elip[ipp]+1, ipp+1); |
abort(); |
} |
// store derivatives of degree of saturation Sr |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+8] = dd_gen(ngstress-1, ngstrain-2); // store dSr/ds matrix component |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+9] = dd_gen(ngstress-1, ngstrain-1); // store dSr/dT matrix component |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+11] = dd_gen(ngstress-1, 0)+dd_gen(ngstress-1, 1)+dd_gen(ngstress-1, 2); // compute dSr/depsv from matrix components |
*/ |
matrix dd_gen; |
makerefm(dd_gen, Mm->ip[ipp].other+ido+2*ncomp+3+nstatev+12, ngstress, ngstrain); |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+8] = dd_gen(ngstress-1, ngstrain-2); // store dSr/ds matrix component |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+9] = dd_gen(ngstress-1, ngstrain-1); // store dSr/dT matrix component |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+11] = dd_gen(ngstress-1, 0);//+dd_gen(ngstress-1, 1)+dd_gen(ngstress-1, 2); // compute dSr/depsv from matrix components |
// copy internal variables from working array to the equilibrium array |
for (i=0;i<n;i++) |
Mm->ip[ipp].eqother[ido+i]=Mm->ip[ipp].other[ido+i]; |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+5] = 0; // zero neval at the end of actual time step |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+6] = 0; // zero nstep at the end of actual time step |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+7] = 1.0; // set mindt to 1 at the end of actual time step |
} |
/** |
The funtion marks required non-mechanical quantities in the array anmq. |
@param anmq - array with flags for used material types |
anmq[i] = 1 => qunatity type nonmechquant(i+1) is required |
anmq[i] = 0 => qunatity type nonmechquant(i+1) is not required |
@return The function does not return anything, but it may change content of anmq array. |
Created by Tomas Koudelka, 1.10.2015 |
*/ |
void hypoplast_unsat_exp_therm::give_reqnmq(long *anmq) |
{ |
// anmq[saturation_degree-1] = 1; |
if (pr_suc_fl == no) |
anmq[suction-1] = 1; |
if (pr_tempr_fl == no) |
anmq[temperature-1] = 1; |
} |
/** |
The function returns the number of eqother array componets of the material model. |
@param ipp - integration point number in the mechmat ip array. |
@retval The function returns value of |
Created by Tomas Koudelka, 4.3.2019 |
*/ |
long hypoplast_unsat_exp_therm::givencompeqother(long ipp) |
{ |
long ncompstr = Mm->ip[ipp].ncompstr; |
return 2*ncompstr+3+nstatev+12+ngstress*ngstrain; |
} |
/** |
The function extracts actual degree of saturation for the actual attained state. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
@retval The function returns value of actual degree of saturation Sr. |
Created by Tomas Koudelka, 25.5.2016 |
*/ |
double hypoplast_unsat_exp_therm::give_sr(long ipp, long ido) |
{ |
long ncompstr = Mm->ip[ipp].ncompstr; |
return Mm->ip[ipp].other[ido+2*ncompstr+3+2]; |
} |
/** |
The function computes actual derivative of degree of saturation with respect to suction |
for the actual attained state. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
@retval The function returns value of derivative of actual degree of saturation with respect to suction dSr/ds. |
Created by Tomas Koudelka, 25.5.2016 |
*/ |
double hypoplast_unsat_exp_therm::give_dsr_ds(long ipp, long ido) |
{ |
long ncomp = Mm->ip[ipp].ncompstr; |
double dsr = Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+8]; |
return dsr; |
} |
/** |
The function computes actual derivative of degree of saturation with respect to temperature |
for the actual attained state. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
@retval The function returns value of derivative of actual degree of saturation with respect to suction dSr/ds. |
Created by Tomas Koudelka, 29.6.2017 |
*/ |
double hypoplast_unsat_exp_therm::give_dsr_dtemp(long ipp, long ido) |
{ |
long ncomp = Mm->ip[ipp].ncompstr; |
double dsr = Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+9]; |
return dsr; |
} |
/** |
The function computes actual derivative of degree of saturation with respect to volumetric strain |
for the attained equilibrium state. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
@retval The function returns value of derivative of actual degree of saturation with respect to suction dSr/ds. |
Created by Tomas Koudelka, 29.6.2018 |
*/ |
double hypoplast_unsat_exp_therm::give_dsr_depsv(long ipp, long ido) |
{ |
long ncomp = Mm->ip[ipp].ncompstr; |
double dsr = Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+11]; |
return dsr; |
} |
/** |
The function extracts actual porosity for the actual attained state. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
@retval The function returns value of actual porosity. |
Created by Tomas Koudelka, 25.5.2016 |
*/ |
double hypoplast_unsat_exp_therm::give_porosity(long ipp, long ido) |
{ |
long ncompstr = Mm->ip[ipp].ncompstr; |
double e = Mm->ip[ipp].other[ido+2*ncompstr+3]; // actual void ratio |
return (e/(1.0+e)); |
} |
/** |
The function extracts actual void ratio for the actual attained state. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
@retval The function returns value of actual porosity e. |
Created by Tomas Koudelka, 25.5.2016 |
*/ |
double hypoplast_unsat_exp_therm::give_void_ratio(long ipp, long ido) |
{ |
long ncompstr = Mm->ip[ipp].ncompstr; |
return Mm->ip[ipp].other[ido+2*ncompstr+3]; |
} |
/** |
The function returns rate of the volumetric strain at the given integration point. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
@return The function returns rate of the volumetric strain. |
Created by Tomas Koudelka 05.2018 |
*/ |
double hypoplast_unsat_exp_therm::give_strain_vol_rate(long ipp, long ido) |
{ |
long ncomp = Mm->ip[ipp].ncompstr; |
return Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+10]; |
} |
/** |
The function changes material parameters for stochastic analysis. |
@param atm - selected material parameters (parameters which are changed) |
@param val - array containing new values of parameters |
@return The function does not return anything. |
Created by Tomas Koudelka, 30.1.2014 |
*/ |
void hypoplast_unsat_exp_therm::changeparam (atsel &atm,vector &val) |
{ |
long i; |
for (i=0;i<atm.num;i++){ |
switch (atm.atrib[i]){ |
case 0:{ |
phideg=val[i]; |
break; |
} |
case 1:{ |
lam_star=val[i]; |
break; |
} |
case 2:{ |
kap_star=val[i]; |
break; |
} |
case 3:{ |
n_star=val[i]; |
break; |
} |
case 4:{ |
nu=val[i]; |
break; |
} |
case 5:{ |
n=val[i]; |
break; |
} |
case 6:{ |
l=val[i]; |
break; |
} |
case 7:{ |
nt=val[i]; |
break; |
} |
case 8:{ |
lt=val[i]; |
break; |
} |
case 9:{ |
m=val[i]; |
break; |
} |
case 10:{ |
alpha_s=val[i]; |
break; |
} |
case 11:{ |
kap_m=val[i]; |
break; |
} |
case 12:{ |
sm_star=val[i]; |
break; |
} |
case 13:{ |
em_star=val[i]; |
break; |
} |
case 14:{ |
s_airentry0=val[i]; |
break; |
} |
case 15:{ |
em0=val[i]; |
break; |
} |
case 16:{ |
tr=val[i]; |
break; |
} |
case 17:{ |
at=val[i]; |
break; |
} |
case 18:{ |
bt=val[i]; |
break; |
} |
case 19:{ |
aer=val[i]; |
break; |
} |
case 20:{ |
p_t=val[i]; |
break; |
} |
default:{ |
fprintf (stderr,"\n\n wrong number of atribute in function changeparam (file %s, line %d).\n",__FILE__,__LINE__); |
} |
} |
} |
} |
#include "intpoints.h" |
#include "element.h" |
#include "tensor.h" |
#include "vecttens.h" |
#include "mathem.h" |
#include "vector.h" |
#include "vecttens.h" |
#include "hypoplunsatexptherm2.h" |
#define nijac 200 |
#define limit 1.0e-15 // zero limit for principal values of tensors (Jacobi method) |
hypoplast_unsat_exp_therm::hypoplast_unsat_exp_therm() |
{ |
phideg = lam_star = kap_star = n_star = 0.0; |
nu = n = l = nt = lt = m = alpha_s = kap_m = sm_star = 0.0; |
em_star = s_airentry0 = em0 = tr = at = bt = lambdap0 = aer = p_t = 0.0; |
// retrieve number of parameters, number of state variables and number of generalized vector components |
nparams=huet.nparms; // number of parameters |
nstatev=huet.nstatev; // number of state variables (10 for actual implementation, see constructor in generalmod.h) |
ngstrain=huet.ngstrain; // number of generalised strain tensor components (8 for actual implementation, see constructor in generalmod.h) |
ngstress=huet.ngstress; // number of generalised stress tensor components (7 for actual implementation, see constructor in generalmod.h) |
nrkfparams=huet.nrkf_parms; // number of RKF method parameters |
nrkfstatev=huet.nrkf_statev; // number of RKF method parameters |
params = new double[nparams]; |
rkfparams = new double[nrkfparams]; |
pr_suc_fl = no; |
pr_tempr_fl = no; |
// maximum value of 'zero' level of state variables for RKF time integration |
// it may be rewritten by RKF tolerance if its value is less than the value specified here |
sv_rkf_zero = 1.0e-3; |
} |
hypoplast_unsat_exp_therm::~hypoplast_unsat_exp_therm() |
{ |
delete [] params; |
delete [] rkfparams; |
} |
/** |
The function reads material parameters from the opened text file given |
by the parameter in. |
@param in - pointer to the opened input text file |
@return The function does not return anything. |
Created by Tomas Koudelka, 30.1.2014 |
*/ |
void hypoplast_unsat_exp_therm::read(XFILE *in) |
{ |
xfscanf(in, "%k %le %k %le %k %le %k %le", |
"phi", &phideg, "lam_star", &lam_star, |
"kap_star", &kap_star, "N_star", &n_star); |
xfscanf(in, "%k %le %k %le %k %le %k %le %k %le %k %le", |
"nu", &nu, "n", &n, "l", &l, "nT", &nt, "lT", <, "m", &m); |
xfscanf(in, "%k %le %k %le %k %le %k %le %k %le %k %le %k %le", |
"alpha_s", &alpha_s, "kap_m", &kap_m, "sm_star", &sm_star, |
"em_star", &em_star, "csh", &csh, "s_airentry0", &s_airentry0, "em0", &em0); |
xfscanf(in, "%k %le %k %le %k %le %k %le %k %le %k %le", |
"tr", &tr, "at", &at, "bt", &bt, |
"aer", &aer, "lambdap0", &lambdap0, "p_t", &p_t); |
// xfscanf(in, "%k %le %k %le","einit", &einit, "ascaninit", &ascaninit); |
xfscanf(in, "%k%m", "presc_suction", &answertype_kwdset, &pr_suc_fl); |
if (pr_suc_fl == yes) |
suc_fn.read(in); |
xfscanf(in, "%k%m", "presc_tempr", &answertype_kwdset, &pr_tempr_fl); |
if (pr_tempr_fl == yes) |
tempr_fn.read(in); |
sra.read(in); |
if (sv_rkf_zero > sra.err) |
sv_rkf_zero = sra.err; |
if (phideg <= 0.0) |
{ |
print_err("phi must be positive (phi = %le)", __FILE__, __LINE__, __func__, phideg); |
abort(); |
} |
if (p_t < 0.0) |
{ |
print_err("p_t must not be negative (p_t = %le)", __FILE__, __LINE__, __func__, p_t); |
abort(); |
} |
if (lam_star <= 0.0) |
{ |
print_err("lam_star must be positive (lam_star = %le)", __FILE__, __LINE__, __func__, lam_star); |
abort(); |
} |
if (kap_star <= 0.0) |
{ |
print_err("kap_star must be positive (kap_star = %le)", __FILE__, __LINE__, __func__, kap_star); |
abort(); |
} |
if (n_star <= 0.0) |
{ |
print_err("n_star must be positive (n_star = %le)", __FILE__, __LINE__, __func__, n_star); |
abort(); |
} |
// temporary check for Mock-up test |
if (aer != 1.0) |
{ |
print_err("temporary check for Mock-up experiment - aer is not set to 1.0 (aer = %le)", __FILE__, __LINE__, __func__, aer); |
abort(); |
} |
// temporary check for Mock-up test |
if (aer != 1.0) |
{ |
print_err("temporary check for Mock-up experiment - aer is not set to 1.0 (aer = %le)", __FILE__, __LINE__, __func__, aer); |
abort(); |
} |
/* |
if (rr <= 0.0) |
{ |
print_err("rr must be positive (rr = %le)", __FILE__, __LINE__, __func__, rr); |
abort(); |
} |
if (s_e0 < 0.0) |
{ |
print_err("s_e0 must not be negative (s_e0 = %le)", __FILE__, __LINE__, __func__, s_e0); |
abort(); |
} |
*/ |
params[0] = phideg; |
params[1] = lam_star; |
params[2] = kap_star; |
params[3] = n_star; |
params[4] = nu; |
params[5] = n; |
params[6] = l; |
params[7] = nt; |
params[8] = lt; |
params[9] = m; |
params[10] = alpha_s; |
params[11] = kap_m; |
params[12] = sm_star; |
params[13] = em_star; |
params[14] = csh; |
params[15] = s_airentry0; |
params[16] = em0; |
params[17] = tr; |
params[18] = at; |
params[19] = bt; |
params[20] = aer; |
params[21] = lambdap0; |
params[22] = p_t; |
//params[21] = einit; |
//params[22] = ascaninit; |
rkfparams[0] = sra.give_err_sig(); |
rkfparams[1] = sra.give_hmin(); |
rkfparams[2] = sra.give_ni(); |
rkfparams[3] = sv_rkf_zero; |
rkfparams[4] = (int)sra.give_rkt(); |
} |
/** |
The function prints material parameters into the opened text file given |
by the parameter out. |
@param out - pointer to the opened output text file |
@return The function does not return anything. |
Created by Tomas Koudelka, koudelka@cml.fsv.cvut.cz, 17.12.2015 |
*/ |
void hypoplast_unsat_exp_therm::print(FILE *out) |
{ |
fprintf(out, "%le %le %le %le\n", |
phideg, lam_star, kap_star, n_star); |
fprintf(out, "%le %le %le %le %le %le\n", |
nu, n, l, nt, lt, m); |
fprintf(out, "%le %le %le %le %le %le %le\n", |
alpha_s, kap_m, sm_star, em_star, csh, s_airentry0, em0); |
fprintf(out, "%le %le %le %le %le %le\n",tr, at, bt, aer, lambdap0, p_t); |
fprintf(out, "%d ", int(pr_suc_fl)); |
if (pr_suc_fl == yes) |
suc_fn.print(out); |
fprintf(out, "%d ", int(pr_tempr_fl)); |
if (pr_tempr_fl == yes) |
tempr_fn.print(out); |
fprintf(out, "\n"); |
sra.print(out); |
} |
/** |
The function initializes material model. Retrieves initial values of the following |
quantities |
@param ipp - integration point number |
@param ido - index of internal variables for given material in the ipp other array |
@return The function does not return anything but updates initial value of Sr and stress vector |
in eqother array. |
Created by Tomas Koudelka, 1.10.2015 |
*/ |
void hypoplast_unsat_exp_therm::initval (long ipp,long ido) |
{ |
// data handled by MEFEL |
long ncomp = Mm->ip[ipp].ncompstr; // number of reduced stress/strain components |
strastrestate ssst = Mm->ip[ipp].ssst; // stress/strain state indicator |
vector sig(ASTCKVEC(ngstress)), eps(ASTCKVEC(ngstrain)); |
vector deps(ASTCKVEC(ngstrain)), dstatev(ASTCKVEC(nstatev)); |
matrix dd_gen(ASTCKMAT(ngstress,ngstrain)); |
double *statev = Mm->ip[ipp].eqother+ido+2*ncomp+3; |
int herr; |
if (statev[0] == 0.0) // initial void ratio was not set => model has not been initialized yet |
{ |
statev[0] = Mm->ic[ipp][0]; // initialize actual value of void ratio |
statev[7] = Mm->ic[ipp][1]; // initialize actual value of ascan |
// set initial value of effective stresses from eigenstresses |
// eigenstress is assumed to be net stress, i.e. sig_{net} = sig_{tot} - u_a.I |
if ((Mp->eigstrains == 4) || (Mp->eigstrains == 5)) |
{ |
for (long i=0; i<ncomp; i++) |
{ |
Mm->ip[ipp].eqother[ido+ncomp+i] = Mm->eigstresses[ipp][i]; |
Mm->ip[ipp].stress[i] = Mm->eigstresses[ipp][i]; |
} |
} |
} |
if (pr_suc_fl == yes) |
statev[1] = suc_fn.getval(Mp->time); //initial prescribed suction pressure s (positive) |
else |
statev[1] = Mm->givenonmechq(suction, ipp); // initial suction pressure s (positive) |
statev[2] = 0.0; // initial degree of saturation S_r |
if (pr_tempr_fl == yes) |
statev[3] = tempr_fn.getval(Mp->time); //initial prescribed temperature |
else |
statev[3] = Mm->givenonmechq(temperature, ipp); // initial temperature T |
give_full_vector(sig.a, Mm->ip[ipp].stress, ssst); |
give_full_vector(eps.a, Mm->ip[ipp].strain, ssst); |
// set remaining components of generalized strain vector |
eps(6) = statev[1]; // set suction to the corresponding component of generalized strain vector |
eps(7) = statev[3]; // set temperature to the corresponding component of generalized strain vector |
// initialize model |
herr = huet.soil_model(eps.a, sig.a, statev, deps.a, 1.0, NULL, params, NULL, rkfparams, 0, Mp->jstep,ipp); |
if (herr) |
{ |
print_err("hypoplasticity model cannot be initialized on element %ld (ip=%ld)", __FILE__, __LINE__, __func__, Mm->elip[ipp]+1, ipp+1); |
abort(); |
} |
statev[2] = sig(6); // store computed initial Sr |
// prepare working copy of array of internal variables |
// eqother values have been already set because statev array is a reference to the eqother array |
copyv(statev, Mm->ip[ipp].other+ido+2*ncomp+3, nstatev); |
// set initial values for dSr/ds and dSr/dT according to generalized stiffness matrix |
herr = huet.soil_model(eps.a, sig.a, statev, NULL, 1.0, dd_gen.a, params, NULL, rkfparams, 3, Mp->jstep,ipp); |
if (herr) |
{ |
print_err("generalized stiffness matrix cannot be initialized on element %ld (ip=%ld)", __FILE__, __LINE__, __func__, Mm->elip[ipp]+1, ipp+1); |
abort(); |
} |
Mm->ip[ipp].eqother[2*ncomp+3+nstatev+8] = dd_gen(ngstress-1, ngstrain-2); // store dSr/ds matrix component |
Mm->ip[ipp].eqother[2*ncomp+3+nstatev+9] = dd_gen(ngstress-1, ngstrain-1); // store dSr/dT matrix component |
Mm->ip[ipp].eqother[ido+2*ncomp+3+nstatev+11] = dd_gen(ngstress-1, 0);//+dd_gen(ngstress-1, 1)+dd_gen(ngstress-1, 2); // compute and store dSr/depsv from matrix components |
// actualize 'consistent' material stiffness matrix |
copym(dd_gen, Mm->ip[ipp].eqother+ido+2*ncomp+3+nstatev+12); |
// actualize other array by the computed values |
memcpy(Mm->ip[ipp].other, Mm->ip[ipp].eqother, sizeof(*Mm->ip[ipp].other)*Mm->ip[ipp].ncompother); |
} |
/** |
The function computes material stiffnes %matrix. |
@param d - allocated matrix structure for material stiffness %matrix (output) |
@param ipp - integration point number |
@param ido - index of internal variables for given material in the ipp other array |
@return The function returns stiffness %matrix in the parameter d. |
Created by Tomas Koudelka, 1.10.2015 |
*/ |
void hypoplast_unsat_exp_therm::matstiff (matrix &d,long ipp,long ido) |
{ |
long i; |
// data handled by MEFEL |
long ncomp = Mm->ip[ipp].ncompstr; |
strastrestate ssst = Mm->ip[ipp].ssst; |
double aux; |
matrix dd_gen(ASTCKMAT(ngstress,ngstrain)), dd(ASTCKMAT(6,6)); |
/* |
vector sig(ASTCKVEC(ngstress)), eps(ASTCKVEC(ngstrain)), deps(ASTCKVEC(ngstrain)); |
vector statev(ASTCKVEC(nstatev)); |
int herr; |
long j; |
// convert stress and strain vectors to full 6 component vectors |
give_full_vector(sig.a, Mm->ip[ipp].stress, ssst); |
give_full_vector(eps.a, Mm->ip[ipp].strain, ssst); |
// stress vector must be reoredred |
// SIFEL ordering is sig11, sig22, sig33, sig23, sig13, sig12 |
// ABAQUS ordering is sig11, sig22, sig33, sig12, sig13, sig23 |
aux = sig(3); |
sig(3) = sig(5); |
sig(5) = aux; |
// strain vector must be reoredred |
// SIFEL ordering is eps11, eps22, eps33, gamma23, gamma13, gamma12 |
// ABAQUS ordering is eps11, eps22, eps33, gamma12, gamma13, gamma23 |
aux = eps(3); |
eps(3) = eps(5); |
eps(5) = aux; |
// assemble generalized strain, stress and strain increment vectors |
eps(6) = Mm->ip[ipp].other[ido+2*ncomp+3+1]; // suction from the actual time step |
eps(7) = Mm->ip[ipp].other[ido+2*ncomp+3+3]; // temperature from the actual time step |
sig(6) = Mm->ip[ipp].other[ido+2*ncomp+3+2]; // degree of saturation Sr from the actual time step |
// prepare working copy of internal variables |
for (i=ido+2*ncomp+3, j=0; i<ido+2*ncomp+3+nstatev; i++, j++) |
statev(j) = Mm->ip[ipp].other[i]; |
herr = huet.soil_model(eps.a, sig.a, statev.a, NULL, NULL, NULL, dd_gen.a, NULL, 1, Mp->jstep); |
if (herr) |
{ |
print_err("math error detected in hypoplastic model on element %ld (ip=%ld)", __FILE__, __LINE__, __func__, Mm->elip[ipp]+1, ipp+1); |
abort(); |
} |
*/ |
// retrieve actual generalized material stiffness matrix from the other array |
makerefm(dd_gen, Mm->ip[ipp].other+2*ncomp+3+nstatev+12, ngstress, ngstrain); |
// reorder stiffness matrix in the full-length format |
// |
// swap the fourth and sixth columns except of the fourth and sixth elements |
for (i=0; i<ngstress; i++) |
{ |
if ((i == 3) || (i==5)) |
continue; |
aux = dd_gen(i,3); |
dd_gen(i,3) = dd_gen(i,5); |
dd_gen(i,5) = aux; |
} |
// swap the fourth and sixth rows except of the fourth and sixth elements |
for (i=0; i<ngstrain; i++) |
{ |
if ((i == 3) || (i==5)) |
continue; |
aux = dd_gen(3,i); |
dd_gen(3,i) = dd_gen(5,i); |
dd_gen(5,i) = aux; |
} |
// swap elements on intersections of the fourth and sixth columns and rows |
aux = dd_gen(3,3); |
dd_gen(3,3) = dd_gen(5,5); |
dd_gen(5,5) = aux; |
aux = dd_gen(3,5); |
dd_gen(3,5) = dd_gen(5,3); |
dd_gen(5,3) = aux; |
// extract the stiffness matrix for the mechanics |
extractm(dd, dd_gen, 0, 6); |
// convert stiffness matrix to the reduced format suitable for element stiffness matrix |
tensor4_ematrix (d, dd, ssst); |
} |
/** |
The function computes stress increments due to pore pressure change in the integration point and stores |
them into eqother array. |
@param ipp - integration point pointer |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
@return The function does not return anything but stores the resulting values in the eqother array. |
Created by Tomas Koudelka, 11.2015 |
*/ |
void hypoplast_unsat_exp_therm::nlstressesincr (long ipp, long im, long ido) |
{ |
long i, j; |
long ncomp = Mm->ip[ipp].ncompstr; |
strastrestate ssst = Mm->ip[ipp].ssst; |
double aux; |
double ds; |
vector sig(ASTCKVEC(ngstress)), eps(ASTCKVEC(ngstrain)); |
vector statev(ASTCKVEC(nstatev)); |
matrix dd_gen; |
//int herr; |
// This procedure is supposed to be called at the beginning of the actual time step |
// and therefore the ip.stress and ip.strain arrays must contain values |
// from the last equilibrium step |
// convert stress and strain vectors to full 6 component vectors |
give_full_vector(sig.a, Mm->ip[ipp].stress, ssst); |
give_full_vector(eps.a, Mm->ip[ipp].strain, ssst); |
// stress vector must be reoredred |
// SIFEL ordering is sig11, sig22, sig33, sig23, sig13, sig12 |
// ABAQUS ordering is sig11, sig22, sig33, sig12, sig13, sig23 |
aux = sig(3); |
sig(3) = sig(5); |
sig(5) = aux; |
// strain vector must be reoredred |
// SIFEL ordering is eps11, eps22, eps33, gamma23, gamma13, gamma12 |
// ABAQUS ordering is eps11, eps22, eps33, gamma12, gamma13, gamma23 |
aux = eps(3); |
eps(3) = eps(5); |
eps(5) = aux; |
// assemble generalized strain, stress and strain increment vectors |
eps(6) = Mm->ip[ipp].eqother[ido+2*ncomp+3+1]; // suction from the previous time step |
eps(7) = Mm->ip[ipp].eqother[ido+2*ncomp+3+3]; // temperature from the previous time step |
sig(6) = Mm->ip[ipp].eqother[ido+2*ncomp+3+2]; // degree of saturation Sr from the previous time step |
// prepare working copy of internal variables |
for (i=ido+2*ncomp+3, j=0; i<ido+2*ncomp+3+nstatev; i++, j++) |
statev(j) = Mm->ip[ipp].eqother[i]; |
// retrieve actual generalized material stiffness matrix from the other array |
makerefm(dd_gen, Mm->ip[ipp].other+2*ncomp+3+nstatev+12, ngstress, ngstrain); |
/* |
reallocm(RSTCKMAT(dd_gen, ngstress,ngstrain)); |
herr = huet.soil_model(eps.a, sig.a, statev.a, NULL, NULL, NULL, dd_gen.a, NULL, 3, Mp->jstep); |
if (herr) |
{ |
print_err("math error detected in hypoplastic model on element %ld (ip=%ld)", __FILE__, __LINE__, __func__, Mm->elip[ipp]+1, ipp+1); |
abort(); |
} |
*/ |
if (pr_suc_fl == yes) //prescribed suction pressure s |
ds = (suc_fn.getval(Mp->time)-Mm->ip[ipp].eqother[ido+2*ncomp+3+1]); //suction pressure increment ds = du_a - du_w |
else // suction is obtained from METR |
ds = Mm->givenonmechq(suction, ipp) - Mm->ip[ipp].eqother[ido+2*ncomp+3+1]; |
// calculate negative increment of stresses due to change in suction (-du = -ds*chi) |
// which will be used in calculation of nodal forces and added to the right hand side vector |
// K*dr = df_e - \int B^T*du dV |
for (i=0;i<3;i++) |
Mm->ip[ipp].eqother[ido+2*ncomp+i] = -ds*dd_gen(i,6); |
//Mm->ip[ipp].eqother[ido+2*ncomp+i] = 0.0; |
} |
/** |
The function computes stress increment due to pore pressure change in the integration point and stores |
them into ip stress array. |
@param lcid - load case id |
@param ipp - integration point number |
@param im - index of the material in the tm and idm arrays on integration point |
@param ido - index of internal variables in the ip's ipp eqother array |
@param fi - first index of the required stress increment component |
@param sig - %vector containing stress increment components (output) |
@return The function returns %vector of stress increments in the parameter sig. |
Created by Tomas Koudelka, 11.2015 |
*/ |
void hypoplast_unsat_exp_therm::givestressincr (long lcid, long ipp, long im, long ido, long fi, vector &sig) |
{ |
nullv(sig); |
long i, j, ncomp = Mm->ip[ipp].ncompstr; |
for (i=fi, j=0; i<3 && j<sig.n; i++, j++) |
sig(j) = Mm->ip[ipp].eqother[ido+2*ncomp+i]; |
} |
/** |
The function computes correct stresses in the integration point and stores |
them into ip stress array. |
@param ipp - integration point pointer |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
@return The function does not return anything. |
Created by Tomas Koudelka, 1.10.2015 |
*/ |
void hypoplast_unsat_exp_therm::nlstresses (long ipp, long im, long ido) |
{ |
long i, j, rkf_stat; |
// long herr; |
// data handled by MEFEL |
long ncomp = Mm->ip[ipp].ncompstr; |
long neval = long(Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+5]); |
strastrestate ssst = Mm->ip[ipp].ssst; |
double aux, dtsub, sro; |
double pnewdt = 1.0; // reduction coefficient for new time step |
double dtime = Mp->timecon.actualforwtimeincr(); |
vector sig(ASTCKVEC(ngstress)), eps(ASTCKVEC(ngstrain)), deps(ASTCKVEC(ngstrain)); |
vector statev(ASTCKVEC(nstatev)); |
vector epseq(ASTCKVEC(ngstrain)); |
vector sigeq(ASTCKVEC(ngstress)); |
vector stateveq(ASTCKVEC(nstatev)); |
// rktype rkt = sra.give_rkt(); // type of Runge-Kutta method |
matrix dd_gen(ASTCKMAT(ngstress,ngstrain)); |
// counter of number of steps performed in RKF method within one time step |
long nstep = long(Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+6]); |
// the minimum step length attained in RKF method within one time step |
double mindt = Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+7]; |
// stress array have to contain values from the last attained equilibrium state |
for (i=0; i<ncomp; i++) |
Mm->ip[ipp].stress[i] = Mm->ip[ipp].eqother[ido+ncomp+i]; |
// calculate strain increments and store them in eps temporarily |
for (i=0; i<ncomp; i++) |
eps(i) = Mm->ip[ipp].strain[i]-Mm->ip[ipp].eqother[ido+i]; |
// convert stress, strain and strain increment vectors to full 6 componet vectors |
give_full_vector(sig.a, Mm->ip[ipp].stress, ssst); |
give_full_vector(deps.a, eps.a, ssst); |
nullv(eps); |
give_full_vector(eps.a, Mm->ip[ipp].eqother+ido, ssst); |
// stress vector must be reoredred |
// SIFEL ordering is sig11, sig22, sig33, sig23, sig13, sig12 |
// ABAQUS ordering is sig11, sig22, sig33, sig12, sig13, sig23 |
aux = sig(3); |
sig(3) = sig(5); |
sig(5) = aux; |
// strain vector must be reoredred |
// SIFEL ordering is eps11, eps22, eps33, gamma23, gamma13, gamma12 |
// ABAQUS ordering is eps11, eps22, eps33, gamma12, gamma13, gamma23 |
aux = eps(3); |
eps(3) = eps(5); |
eps(5) = aux; |
// strain increment vector must be reoredred |
// SIFEL ordering is deps11, deps22, deps33, dgamma23, dgamma13, dgamma12 |
// ABAQUS ordering is deps11, deps22, deps33, dgamma12, dgamma13, dgamma23 |
aux = deps(3); |
deps(3) = deps(5); |
deps(5) = aux; |
// assemble generalized strain |
eps(6) = Mm->ip[ipp].eqother[ido+2*ncomp+3+1]; // suction from the previous time step |
eps(7) = Mm->ip[ipp].eqother[ido+2*ncomp+3+3]; // temperature from the previous time step |
// assemble generalized stress vector |
sro = sig(6) = Mm->ip[ipp].eqother[ido+2*ncomp+3+2]; // degree of saturation Sr from the previous time step |
// assemble generalized strain increment vector |
if (pr_suc_fl == yes) //prescribed suction pressure s (positive) |
deps(6) = suc_fn.getval(Mp->time) - Mm->ip[ipp].eqother[ido+2*ncomp+3+1]; // suction increment ds |
else |
deps(6) = Mm->givenonmechq(suction, ipp) - Mm->ip[ipp].eqother[ido+2*ncomp+3+1]; // suction pressure increment ds |
if (pr_tempr_fl == yes) //prescribed temperature T |
deps(7) = tempr_fn.getval(Mp->time) - Mm->ip[ipp].eqother[ido+2*ncomp+3+3]; // temperature increment dT |
else |
deps(7) = Mm->givenonmechq(temperature, ipp) - Mm->ip[ipp].eqother[ido+2*ncomp+3+3]; // temperature increment dT |
// prepare working copy of internal variables from the last equilibrium state |
for (i=ido+2*ncomp+3, j=0; i<ido+2*ncomp+3+nstatev; i++, j++) |
statev(j) = Mm->ip[ipp].eqother[i]; |
dtsub = Mm->ip[ipp].eqother[ido+2*ncomp+3+nstatev]; |
// create copy of strain, stress and state variable vectors from the last equilibrium state |
copyv(eps, epseq); |
copyv(sig, sigeq); |
copyv(statev, stateveq); |
// compute new values of stress vector and state variable increments |
vector rkf_statev(ASTCKVEC(nrkfstatev)); |
rkf_statev[0] = Mm->ip[ipp].eqother[ido+2*ncomp+3+nstatev+5]; |
rkf_statev[1] = Mm->ip[ipp].eqother[ido+2*ncomp+3+nstatev+6]; |
rkf_statev[2] = Mm->ip[ipp].eqother[ido+2*ncomp+3+nstatev+7]; |
rkf_statev[3] = Mm->ip[ipp].eqother[ido+2*ncomp+3+nstatev]; |
rkf_stat = huet.soil_model(eps.a, sig.a, statev.a, deps.a, dtime, dd_gen.a, NULL, rkf_statev.a, rkfparams, 1, Mp->jstep,ipp); |
// actualize RKF state variables |
neval = long(rkf_statev[0]); |
nstep = long(rkf_statev[1]); |
mindt = rkf_statev[2]; |
dtsub = rkf_statev[3]; |
// store 'consistent' material stiffness matrix |
copym(dd_gen, Mm->ip[ipp].other+ido+2*ncomp+3+nstatev+12); |
/* |
switch (rkt) |
{ |
case fwdeulert: |
{ |
vector dsig(ASTCKVEC(ngstress)); |
vector dstatev(ASTCKVEC(nstatev)); |
rkf_stat = huet.soil_model(eps.a, sig.a, statev.a, deps.a, dsig.a, dstatev.a, NULL, NULL, 2, Mp->jstep); |
addv(sig, dsig, sig); |
addv(statev, dstatev, statev); |
neval += 1; |
nstep += 1; |
mindt = 1.0; |
break; |
} |
case heunt: |
rkf_stat = adfwdeuler(eps, sig, statev, deps, dtsub, neval, nstep, mindt); |
break; |
case rkf23t: |
rkf_stat = rkf23(ipp, eps, sig, statev, deps, dtsub, neval, nstep, mindt); |
break; |
case rkf23bst: |
rkf_stat = rkf23bs(eps, sig, statev, deps, dtsub, neval, nstep, mindt); |
break; |
case rkf34t: |
rkf_stat = rkf34(eps, sig, statev, deps, dtsub, neval, nstep, mindt); |
break; |
case rkf45t: |
rkf_stat = rkf45(eps, sig, statev, deps, dtsub, neval, nstep, mindt); |
break; |
default: |
print_err("unknown Runge-Kutta method is required", __FILE__, __LINE__, __func__); |
} |
*/ |
if (rkf_stat){ |
fprintf(Out, "\nRKF failed - rkf_stat=%ld, element=%ld, ip=%ld, loc_ip=%ld, istep=%ld, jstep=%ld, dt=%le", |
rkf_stat, Mm->elip[ipp], ipp, ipp-Mt->elements[Mm->elip[ipp]].ipp[0][0]+1, Mp->istep, Mp->jstep, Mp->timecon.actualforwtimeincr()); |
fprintf(Out, "\nsig\n"); |
printv(Out, sig); |
fprintf(Out, "\neps\n"); |
printv(Out, eps); |
fprintf(Out, "\ndeps\n"); |
printv(Out, deps); |
fprintf(Out, "\nstatev\n"); |
printv(Out, statev); |
fprintf(Out, "\n\n"); |
pnewdt = 0.5; // RKF was not able integrate quantities with required error => decrease time step in the solver |
} |
// stress vector must be reoredred to SIFEL notation |
// SIFEL ordering is sig11, sig22, sig33, sig23, sig13, sig12 |
// ABAQUS ordering is sig11, sig22, sig33, sig12, sig13, sig23 |
aux = sig(3); |
sig(3) = sig(5); |
sig(5) = aux; |
// store stress in reduced notation to the integration point |
give_red_vector(sig.a, Mm->ip[ipp].stress, ssst); |
// actual value of generalized strain vector |
// addv(eps,deps,eps); |
// store actual value of strain vector |
Mm->storeother(ipp, ido, ncomp, Mm->ip[ipp].strain); |
// store actual value of stress vector |
Mm->storeother(ipp, ido+ncomp, ncomp, Mm->ip[ipp].stress); |
// store actual value of state variables |
Mm->storeother(ipp, ido+2*ncomp+3, nstatev, statev.a); |
// store actual value of suction |
Mm->ip[ipp].other[ido+2*ncomp+3+1] = eps(6); |
// store actual value of temperature |
Mm->ip[ipp].other[ido+2*ncomp+3+3] = eps(7); |
// store actual value of RK substep coefficient |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev]= dtsub; |
// store actual value of time step coefficient |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+1]= pnewdt; |
// store actual number of model evaluation - only for testing purposes |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+5]= neval; |
// store actual number of performed RKF steps - only for testing purposes |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+6]= nstep; |
// store the minimum RKF step length - only for testing purposes |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+7]= mindt; |
// volumetric strain rate is computed via generalized trapesoidal rule |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+10]= 0.5*((deps(0)+deps(1)+deps(2))/dtime + Mm->ip[ipp].eqother[ido+2*ncomp+3+nstatev+10]); |
// volumetric strain rate |
//Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+10]= (deps(0)+deps(1)+deps(2))/dtime; |
/* |
// assemble non-mechanical blocks (all except of sig-eps block) of generalized stiffness matrix |
herr = huet.soil_model(epseq.a, sigeq.a, stateveq.a, NULL, NULL, NULL, dd_gen.a, NULL, 3, Mp->jstep); |
if (herr) |
{ |
print_err("generalized stiffness matrix cannot be assembled on element %ld (ip=%ld)", __FILE__, __LINE__, __func__, Mm->elip[ipp]+1, ipp+1); |
abort(); |
} |
// store derivatives of degree of saturation Sr |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+8] = dd_gen(ngstress-1, ngstrain-2); // store dSr/ds matrix component |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+9] = dd_gen(ngstress-1, ngstrain-1); // store dSr/dT matrix component |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+11] = dd_gen(ngstress-1, 0)+dd_gen(ngstress-1, 1)+dd_gen(ngstress-1, 2); // compute and store dSr/depsv from matrix components |
*/ |
// calculate additional quantities used for output of results |
double epsv; |
// calculate volumetric strain |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+2]= epsv = eps(0)+eps(1)+eps(2); |
// suction increment |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+3]= eps(6)-Mm->ip[ipp].eqother[ido+2*ncomp+3+1]; |
// depsV |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+4]= deps(0)+deps(1)+deps(2); |
/* |
// calculate strain deviator |
epsv *= 1.0/3.0; |
eps(0) -= epsv; |
eps(1) -= epsv; |
eps(2) -= epsv; |
deviator(eps, eps); |
// vertical strain deviator component |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+3]= eps(1); |
// calculate stress deviator |
deviator(sig, sig); |
// vertical stress deviator component |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+4]= sig(1); |
*/ |
} |
/** |
The function reduces step length in Runge-Kutta-Fehlberg methods according to given |
coefficient and minimum step length. |
@param rc - reduction coefficient of step length (input) |
@param h - actual/modified step length (input/output) |
@param hmin - minimum step length (input) |
@retval 0 - On sucessfull step reduction. |
@retval 1 - The minimum step length has been attained and the step cannot be reduced further. |
Created by Tomas Koudelka, 24.5.2016 |
*/ |
long hypoplast_unsat_exp_therm::rkf_redstep(double rc, double &h, double hmin) |
{ |
if (h > hmin) |
{ |
h *= rc; |
if (h < hmin) |
h = hmin; |
return 0; |
} |
else |
return 1; |
} |
/** |
The function returns time step size required by the hypoplsaticity model. It is represented by ratio |
of required time step size to the actual one or 1.0 for no change in time step size. |
@param ipp - integration point number in the mechmat ip array. |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
@return The function returns required time step size provided by the hypoplasticity model |
Created by Tomas Koudelka, 1.10.2015 |
*/ |
double hypoplast_unsat_exp_therm::dstep_red(long ipp, long im, long ido) |
{ |
long ncomp = Mm->ip[ipp].ncompstr; |
return (Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+1]); |
} |
/** |
Function updates values in the other array reached in the previous equlibrium state to |
values reached in the new actual equilibrium state. |
@param ipp - integration point number in the mechmat ip array. |
@param im - index of material type for given ip |
@param ido - index of internal variables for given material in the ipp other array |
@return The function does not return anything. |
Created by Tomas Koudelka, 1.10.2015 |
*/ |
void hypoplast_unsat_exp_therm::updateval (long ipp,long im,long ido) |
{ |
long i, j; |
// long herr; |
long n = Mm->givencompeqother(ipp,im); |
long ncomp = Mm->ip[ipp].ncompstr; |
strastrestate ssst = Mm->ip[ipp].ssst; |
double aux; |
vector sigeq(ASTCKVEC(ngstress)); |
vector epseq(ASTCKVEC(ngstrain)); |
vector stateveq(ASTCKVEC(nstatev)); |
// matrix dd_gen(ASTCKMAT(ngstress,ngstrain)); |
// convert stress, strain and strain increment vectors to full 6 componet vectors |
give_full_vector(epseq.a, Mm->ip[ipp].strain, ssst); |
give_full_vector(sigeq.a, Mm->ip[ipp].stress, ssst); |
// stress vector must be reoredred |
// SIFEL ordering is sig11, sig22, sig33, sig23, sig13, sig12 |
// ABAQUS ordering is sig11, sig22, sig33, sig12, sig13, sig23 |
aux = sigeq(3); |
sigeq(3) = sigeq(5); |
sigeq(5) = aux; |
// strain vector must be reoredred |
// SIFEL ordering is eps11, eps22, eps33, gamma23, gamma13, gamma12 |
// ABAQUS ordering is eps11, eps22, eps33, gamma12, gamma13, gamma23 |
aux = epseq(3); |
epseq(3) = epseq(5); |
epseq(5) = aux; |
// assemble generalized strain increment vector |
if (pr_suc_fl == yes) //prescribed suction pressure s (positive) |
epseq(6) = suc_fn.getval(Mp->time); // suction s defined by user function |
else |
epseq(6) = Mm->givenonmechq(suction, ipp); // suction s from TRFEL |
if (pr_tempr_fl == yes) //prescribed temperature T |
epseq(7) = tempr_fn.getval(Mp->time); // temperature T defined by user function |
else |
epseq(7) = Mm->givenonmechq(temperature, ipp); // temperature T from TRFEL |
// assemble generalized stress vector |
sigeq(6) = Mm->ip[ipp].other[ido+2*ncomp+3+2]; // actual degree of saturation Sr |
// prepare working copy of internal variables from the last equilibrium state |
for (i=ido+2*ncomp+3, j=0; i<ido+2*ncomp+3+nstatev; i++, j++) |
stateveq(j) = Mm->ip[ipp].other[i]; |
/* |
// assemble non-mechanical blocks (all except of sig-eps block) of generalized stiffness matrix |
herr = huet.soil_model(epseq.a, sigeq.a, stateveq.a, NULL, NULL, NULL, dd_gen.a, NULL, 3, Mp->jstep); |
if (herr) |
{ |
print_err("generalized stiffness matrix cannot be assembled on element %ld (ip=%ld)", __FILE__, __LINE__, __func__, Mm->elip[ipp]+1, ipp+1); |
abort(); |
} |
// store derivatives of degree of saturation Sr |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+8] = dd_gen(ngstress-1, ngstrain-2); // store dSr/ds matrix component |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+9] = dd_gen(ngstress-1, ngstrain-1); // store dSr/dT matrix component |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+11] = dd_gen(ngstress-1, 0)+dd_gen(ngstress-1, 1)+dd_gen(ngstress-1, 2); // compute dSr/depsv from matrix components |
*/ |
matrix dd_gen; |
makerefm(dd_gen, Mm->ip[ipp].other+ido+2*ncomp+3+nstatev+12, ngstress, ngstrain); |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+8] = dd_gen(ngstress-1, ngstrain-2); // store dSr/ds matrix component |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+9] = dd_gen(ngstress-1, ngstrain-1); // store dSr/dT matrix component |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+11] = dd_gen(ngstress-1, 0);//+dd_gen(ngstress-1, 1)+dd_gen(ngstress-1, 2); // compute dSr/depsv from matrix components |
// copy internal variables from working array to the equilibrium array |
for (i=0;i<n;i++) |
Mm->ip[ipp].eqother[ido+i]=Mm->ip[ipp].other[ido+i]; |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+5] = 0; // zero neval at the end of actual time step |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+6] = 0; // zero nstep at the end of actual time step |
Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+7] = 1.0; // set mindt to 1 at the end of actual time step |
} |
/** |
The funtion marks required non-mechanical quantities in the array anmq. |
@param anmq - array with flags for used material types |
anmq[i] = 1 => qunatity type nonmechquant(i+1) is required |
anmq[i] = 0 => qunatity type nonmechquant(i+1) is not required |
@return The function does not return anything, but it may change content of anmq array. |
Created by Tomas Koudelka, 1.10.2015 |
*/ |
void hypoplast_unsat_exp_therm::give_reqnmq(long *anmq) |
{ |
// anmq[saturation_degree-1] = 1; |
if (pr_suc_fl == no) |
anmq[suction-1] = 1; |
if (pr_tempr_fl == no) |
anmq[temperature-1] = 1; |
} |
/** |
The function returns the number of eqother array componets of the material model. |
@param ipp - integration point number in the mechmat ip array. |
@retval The function returns value of |
Created by Tomas Koudelka, 4.3.2019 |
*/ |
long hypoplast_unsat_exp_therm::givencompeqother(long ipp) |
{ |
long ncompstr = Mm->ip[ipp].ncompstr; |
return 2*ncompstr+3+nstatev+12+ngstress*ngstrain; |
} |
/** |
The function extracts actual degree of saturation for the actual attained state. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
@retval The function returns value of actual degree of saturation Sr. |
Created by Tomas Koudelka, 25.5.2016 |
*/ |
double hypoplast_unsat_exp_therm::give_sr(long ipp, long ido) |
{ |
long ncompstr = Mm->ip[ipp].ncompstr; |
return Mm->ip[ipp].other[ido+2*ncompstr+3+2]; |
} |
/** |
The function computes actual derivative of degree of saturation with respect to suction |
for the actual attained state. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
@retval The function returns value of derivative of actual degree of saturation with respect to suction dSr/ds. |
Created by Tomas Koudelka, 25.5.2016 |
*/ |
double hypoplast_unsat_exp_therm::give_dsr_ds(long ipp, long ido) |
{ |
long ncomp = Mm->ip[ipp].ncompstr; |
double dsr = Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+8]; |
return dsr; |
} |
/** |
The function computes actual derivative of degree of saturation with respect to temperature |
for the actual attained state. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
@retval The function returns value of derivative of actual degree of saturation with respect to suction dSr/ds. |
Created by Tomas Koudelka, 29.6.2017 |
*/ |
double hypoplast_unsat_exp_therm::give_dsr_dtemp(long ipp, long ido) |
{ |
long ncomp = Mm->ip[ipp].ncompstr; |
double dsr = Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+9]; |
return dsr; |
} |
/** |
The function computes actual derivative of degree of saturation with respect to volumetric strain |
for the attained equilibrium state. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
@retval The function returns value of derivative of actual degree of saturation with respect to suction dSr/ds. |
Created by Tomas Koudelka, 29.6.2018 |
*/ |
double hypoplast_unsat_exp_therm::give_dsr_depsv(long ipp, long ido) |
{ |
long ncomp = Mm->ip[ipp].ncompstr; |
double dsr = Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+11]; |
return dsr; |
} |
/** |
The function extracts actual porosity for the actual attained state. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
@retval The function returns value of actual porosity. |
Created by Tomas Koudelka, 25.5.2016 |
*/ |
double hypoplast_unsat_exp_therm::give_porosity(long ipp, long ido) |
{ |
long ncompstr = Mm->ip[ipp].ncompstr; |
double e = Mm->ip[ipp].other[ido+2*ncompstr+3]; // actual void ratio |
return (e/(1.0+e)); |
} |
/** |
The function extracts actual void ratio for the actual attained state. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
@retval The function returns value of actual porosity e. |
Created by Tomas Koudelka, 25.5.2016 |
*/ |
double hypoplast_unsat_exp_therm::give_void_ratio(long ipp, long ido) |
{ |
long ncompstr = Mm->ip[ipp].ncompstr; |
return Mm->ip[ipp].other[ido+2*ncompstr+3]; |
} |
/** |
The function returns rate of the volumetric strain at the given integration point. |
@param ipp - integration point number in the mechmat ip array. |
@param ido - index of internal variables for given material in the ipp other array |
@return The function returns rate of the volumetric strain. |
Created by Tomas Koudelka 05.2018 |
*/ |
double hypoplast_unsat_exp_therm::give_strain_vol_rate(long ipp, long ido) |
{ |
long ncomp = Mm->ip[ipp].ncompstr; |
return Mm->ip[ipp].other[ido+2*ncomp+3+nstatev+10]; |
} |
/** |
The function changes material parameters for stochastic analysis. |
@param atm - selected material parameters (parameters which are changed) |
@param val - array containing new values of parameters |
@return The function does not return anything. |
Created by Tomas Koudelka, 30.1.2014 |
*/ |
void hypoplast_unsat_exp_therm::changeparam (atsel &atm,vector &val) |
{ |
long i; |
for (i=0;i<atm.num;i++){ |
switch (atm.atrib[i]){ |
case 0:{ |
phideg=val[i]; |
break; |
} |
case 1:{ |
lam_star=val[i]; |
break; |
} |
case 2:{ |
kap_star=val[i]; |
break; |
} |
case 3:{ |
n_star=val[i]; |
break; |
} |
case 4:{ |
nu=val[i]; |
break; |
} |
case 5:{ |
n=val[i]; |
break; |
} |
case 6:{ |
l=val[i]; |
break; |
} |
case 7:{ |
nt=val[i]; |
break; |
} |
case 8:{ |
lt=val[i]; |
break; |
} |
case 9:{ |
m=val[i]; |
break; |
} |
case 10:{ |
alpha_s=val[i]; |
break; |
} |
case 11:{ |
kap_m=val[i]; |
break; |
} |
case 12:{ |
sm_star=val[i]; |
break; |
} |
case 13:{ |
em_star=val[i]; |
break; |
} |
case 14:{ |
s_airentry0=val[i]; |
break; |
} |
case 15:{ |
em0=val[i]; |
break; |
} |
case 16:{ |
tr=val[i]; |
break; |
} |
case 17:{ |
at=val[i]; |
break; |
} |
case 18:{ |
bt=val[i]; |
break; |
} |
case 19:{ |
aer=val[i]; |
break; |
} |
case 20:{ |
p_t=val[i]; |
break; |
} |
default:{ |
fprintf (stderr,"\n\n wrong number of atribute in function changeparam (file %s, line %d).\n",__FILE__,__LINE__); |
} |
} |
} |
} |
/trunk/SIFEL/MEFEL/SRC/mechmat.cpp |
---|
27,6 → 27,7 |
#include "camclay.h" |
#include "camclaycoup.h" |
#include "bbm.cpp" |
#include "dsm.cpp" |
#include "shefplast.h" |
#include "hissplas.h" |
#include "glasgmech.h" |
1350,6 → 1351,18 |
} |
break; |
} |
case doublestructuremat:{ |
if (Mespr==1) fprintf (stdout,"\n number of double structure materials for clays %ld",numt); |
dsm = new dsmmat [numt]; |
for (j=0;j<numt;j++){ |
k=numt+1; |
xfscanf (in,"%ld",&k); |
if (k>numt || k<1) |
print_err("wrong number of double structure materials for clays",__FILE__,__LINE__,__func__); |
dsm[k-1].read (in); |
} |
break; |
} |
case hypoplastmat:{ |
if (Mespr==1) fprintf (stdout,"\n number of hypoplast materials for coupling %ld",numt); |
hypopl = new hypoplast [numt]; |
2674,8 → 2687,16 |
compute_ipstrains(lcid); |
Mp->strainstate = 1; |
} |
bbm[ip[ipp].idm[im]].initval(ipp, ido); |
bbm[ip[ipp].idm[im]].initval(ipp, im, ido); |
break; |
case doublestructuremat: |
if (Mp->strainstate == 0) |
{ |
compute_ipstrains(lcid); |
Mp->strainstate = 1; |
} |
dsm[ip[ipp].idm[im]].initval(ipp, im, ido); |
break; |
case hypoplastmat: |
if (Mp->strainstate == 0) |
{ |
3606,6 → 3627,7 |
case modcamclaymat: |
case modcamclaycoupmat: |
case bbmcoupmat: |
case doublestructuremat: |
case hypoplastmat: |
case hypoplastusatthermat: |
case shefpl: |
3797,9 → 3819,13 |
ncompo += givencompeqother (ipp, im+1); |
break; |
case bbmcoupmat: |
ncompo=ncompstr+13; |
ncompo=ncompstr+15+ncompstr*ncompstr+ncompstr; |
ncompo += givencompeqother (ipp, im+1); |
break; |
case doublestructuremat: |
ncompo=ncompstr+15+ncompstr*ncompstr+1+ncompstr; |
ncompo += givencompeqother (ipp, im+1); |
break; |
case homomatm: |
break; |
case hypoplastmat: |
4093,7 → 4119,7 |
double e = 0.0; |
switch (ip[ipp].tm[im]) |
{ |
{ |
case elisomat: |
e = eliso[ip[ipp].idm[im]].e; |
break; |
4107,6 → 4133,15 |
e = cclayc[ip[ipp].idm[im]].give_actual_ym(ipp,im,ido); |
break; |
} |
case bbmcoupmat:{ |
e = bbm[ip[ipp].idm[im]].give_actual_ym(ipp,im,ido); |
break; |
} |
case doublestructuremat: |
{ |
e = dsm[ip[ipp].idm[im]].give_actual_ym(ipp,im,ido); |
break; |
} |
case creepeffym: |
e = creffym[ip[ipp].idm[im]].give_actual_ym(); |
break; |
4158,11 → 4193,16 |
case nonlocplastmat: |
case nonlocdamgmat: |
case nonlocalmicroM4: |
case creep_damage: |
ncompo = givencompeqother(ipp, im); |
ncompo -= givencompeqother(ipp, im+1); |
e = give_actual_ym(ipp, im+1, ido+ncompo); // these artificial materials sould not have internal variables, i.e. ncompo=0 -> no ido index shift |
break; |
case creep_damage: |
ncompo = givencompeqother(ipp, im); |
ncompo -= givencompeqother(ipp, im+1); // number of other components of creep material model |
ncompo -= givencompeqother(ipp, im+2); // number of other components of damage material model |
e = give_actual_ym(ipp, im+1, ido+ncompo); // these artificial materials sould not have internal variables, i.e. ncompo=0 -> no ido index shift |
break; |
case shrinkagemat: |
ncompo = givencompeqother(ipp, im); |
ncompo -= givencompeqother(ipp, im+1); // ido index shift due to the shrinkage material |
4247,7 → 4287,15 |
e = cclayc[ip[ipp].idm[im]].give_actual_ym(ipp,im,ido); |
break; |
} |
case bbmcoupmat: |
case bbmcoupmat:{ |
e = bbm[ip[ipp].idm[im]].give_actual_ym(ipp,im,ido); |
break; |
} |
case doublestructuremat: |
{ |
e = dsm[ip[ipp].idm[im]].give_actual_ym(ipp,im,ido); |
break; |
} |
case shefpl: |
case glasgowmechmat: |
case glasgowdamage: |
4280,9 → 4328,14 |
case nonlocplastmat: |
case nonlocdamgmat: |
case nonlocalmicroM4: |
ncompo = givencompeqother(ipp, im); |
ncompo -= givencompeqother(ipp, im+1); |
e = give_initial_ym(ipp, im+1, ido+ncompo); // these artificial materials should have no internal variables (ncompo=0) -> no ido index shift |
break; |
case creep_damage: |
ncompo = givencompeqother(ipp, im); |
ncompo -= givencompeqother(ipp, im+1); |
ncompo -= givencompeqother(ipp, im+2); |
e = give_initial_ym(ipp, im+1, ido+ncompo); // these artificial materials should have no internal variables (ncompo=0) -> no ido index shift |
break; |
case effective_stress: |
4329,7 → 4382,7 |
double nu = 0.0; |
switch (ip[ipp].tm[im]) |
{ |
{ |
case elisomat: |
nu = eliso[ip[ipp].idm[im]].nu; |
break; |
4343,6 → 4396,14 |
nu = cclayc[ip[ipp].idm[im]].give_actual_nu(ipp, im, ido); |
break; |
} |
case bbmcoupmat:{ |
nu = bbm[ip[ipp].idm[im]].give_actual_nu(ipp, im, ido); |
break; |
} |
case doublestructuremat:{ |
nu = dsm[ip[ipp].idm[im]].give_actual_nu(ipp, im, ido); |
break; |
} |
case creepeffym: |
nu = creffym[ip[ipp].idm[im]].give_actual_nu(); |
break; |
4445,7 → 4506,7 |
double nu = 0.0; |
switch (ip[ipp].tm[im]) |
{ |
{ |
case elisomat: |
nu = eliso[ip[ipp].idm[im]].nu; |
break; |
4474,6 → 4535,7 |
case modcamclaymat: |
case modcamclaycoupmat: |
case bbmcoupmat: |
case doublestructuremat: |
case shefpl: |
case glasgowmechmat: |
case glasgowdamage: |
4828,6 → 4890,10 |
s = bbm[i].give_saturation_degree(ipp,ido); |
break; |
} |
case doublestructuremat:{ |
s = dsm[i].give_saturation_degree(ipp,ido); |
break; |
} |
case hypoplastusatthermat:{ |
s = hypoplustherm[i].give_sr(ipp,ido); |
break; |
5000,6 → 5066,10 |
pc = bbm[i].give_preconspress(ipp,ido); |
break; |
} |
case doublestructuremat:{ |
pc = dsm[i].give_preconspress(ipp,ido); |
break; |
} |
case effective_stress: |
ncompo = givencompeqother(ipp, im); |
ncompo -= givencompeqother(ipp, im+1); |
5052,6 → 5122,10 |
e_lambda1 = bbm[i].give_virgporosity(ipp,ido); |
break; |
} |
case doublestructuremat:{ |
e_lambda1 = dsm[i].give_virgporosity(ipp,ido); |
break; |
} |
case hypoplastmat:{ |
e_lambda1 = hypopl[i].give_virgporosity(ipp,ido); |
break; |
5108,6 → 5182,10 |
n_ini = bbm[i].give_iniporosity(ipp,ido); |
break; |
} |
case doublestructuremat:{ |
n_ini = dsm[i].give_iniporosity(ipp,ido); |
break; |
} |
case hypoplastmat:{ |
n_ini = hypopl[i].give_iniporosity(ipp,ido); |
break; |
5172,6 → 5250,10 |
n = bbm[i].give_porosity(ipp, ido); |
break; |
} |
case doublestructuremat:{ |
n = dsm[i].give_porosity(ipp, ido); |
break; |
} |
case hypoplastusatthermat:{ |
n = hypoplustherm[i].give_porosity(ipp,ido); |
break; |
5261,6 → 5343,10 |
epsvr = bbm[i].give_strain_vol_rate(ipp, ido); |
break; |
} |
case doublestructuremat:{ |
epsvr = dsm[i].give_strain_vol_rate(ipp, ido); |
break; |
} |
case hypoplastusatthermat:{ |
epsvr = hypoplustherm[i].give_strain_vol_rate(ipp,ido); |
break; |
5337,6 → 5423,10 |
cp = bbm[i].give_consparam (ipp,ido); |
break; |
} |
case doublestructuremat:{ |
cp = dsm[i].give_consparam (ipp,ido); |
break; |
} |
case hissplasmat:{ |
cp = hisspl[i].give_consparam (ipp,ido); |
break; |
5638,6 → 5728,10 |
bbm[ip[ipp].idm[im]].giveirrstrains(ipp, ido, epsirr); |
break; |
} |
case doublestructuremat:{ |
dsm[ip[ipp].idm[im]].giveirrstrains(ipp, ido, epsirr); |
break; |
} |
case hissplasmat:{ |
hisspl[ip[ipp].idm[im]].giveirrstrains(ipp, ido, epsirr); |
break; |
5841,6 → 5935,9 |
case bbmcoupmat: |
bbm[im].give_reqnmq(anmq); |
break; |
case doublestructuremat: |
dsm[im].give_reqnmq(anmq); |
break; |
case hypoplastmat: |
hypopl[im].give_reqnmq(anmq); |
break; |
6090,6 → 6187,11 |
bbm[i].matstiff (d,ipp,ido); |
break; |
} |
case doublestructuremat:{ |
i=ip[ipp].idm[im]; |
dsm[i].matstiff (d,ipp,ido); |
break; |
} |
case homomatm:{ |
i=ip[ipp].idm[im]; |
hommatm[i].matstiff (d,ip[ipp].ssst); |
6674,6 → 6776,10 |
bbm[ip[ipp].idm[im]].nlstresses (ipp,im,ido); |
break; |
} |
case doublestructuremat:{ |
dsm[ip[ipp].idm[im]].nlstresses (ipp,im,ido); |
break; |
} |
case homomatm:{ |
hommatm[ip[ipp].idm[im]].nlstresses (ipp,im,ido); |
break; |
6879,8 → 6985,9 |
*/ |
void mechmat::computenlstressesincr (long ipp,long im,long ido) |
{ |
switch (ip[ipp].tm[im]){ |
long ncompo; |
switch (ip[ipp].tm[im]){ |
case creep_damage:{ |
crdam[ip[ipp].idm[im]].nlstressesincr (ipp, im, ido); |
break; |
6903,20 → 7010,26 |
creffym[ip[ipp].idm[im]].nlstressesincr(ipp,im,ido); |
break; |
} |
/* |
case lemaitr:{ |
lmtr[ip[ipp].idm[im]].nlstresses (ipp,ido); |
break; |
} |
case creepbaz:{ |
crbaz[ip[ipp].idm[im]].nlstresses (ipp,im,ido); |
break; |
} |
*/ |
/* |
case lemaitr:{ |
lmtr[ip[ipp].idm[im]].nlstresses (ipp,ido); |
break; |
} |
case creepbaz:{ |
crbaz[ip[ipp].idm[im]].nlstresses (ipp,im,ido); |
break; |
} |
*/ |
case consolidation:{ |
csol[ip[ipp].idm[im]].nlstressesincr (ipp); |
break; |
} |
case effective_stress:{ |
ncompo = givencompeqother(ipp, im); |
ncompo -= givencompeqother(ipp, im+1); // ido index shift due to the effective stress material |
computenlstressesincr (ipp,im+1,ido+ncompo); |
break; |
} |
case viscoplasticity:{ |
visplas[ip[ipp].idm[im]].nlstressesincr (ipp,im,ido); |
break; |
6925,6 → 7038,14 |
hypoplustherm[ip[ipp].idm[im]].nlstressesincr(ipp,im,ido); |
break; |
} |
case bbmcoupmat:{ |
bbm[ip[ipp].idm[im]].nlstressesincr(ipp,im,ido); |
break; |
} |
case doublestructuremat:{ |
dsm[ip[ipp].idm[im]].nlstressesincr(ipp,im,ido); |
break; |
} |
case elisomat: |
case homomatm: |
case simplas1d: |
6941,9 → 7062,7 |
case chenplast: |
case modcamclaymat: |
case modcamclaycoupmat: |
case bbmcoupmat: |
case shefpl: |
case effective_stress: |
case glasgowmechmat: |
case glasgowdamage: |
case scaldamage: |
7929,9 → 8048,13 |
break; |
} |
case bbmcoupmat:{ |
bbm[ip[ipp].idm[im]].updateval (ipp,ido); |
bbm[ip[ipp].idm[im]].updateval (ipp,im, ido); |
break; |
} |
case doublestructuremat:{ |
dsm[ip[ipp].idm[im]].updateval (ipp,im, ido); |
break; |
} |
case hypoplastmat:{ |
hypopl[ip[ipp].idm[im]].updateval (ipp,im,ido); |
break; |
8164,6 → 8287,7 |
case modcamclaymat: |
case modcamclaycoupmat: |
case bbmcoupmat: |
case doublestructuremat: |
case hypoplastmat: |
case hypoplastusatthermat: |
case hissplasmat: |
8418,7 → 8542,6 |
case druckerprager2: |
case chenplast: |
case modcamclaymat: |
case bbmcoupmat: |
case hissplasmat: |
case microplaneM4: |
case microsimp: |
8471,6 → 8594,12 |
case modcamclaycoupmat: |
cclayc[ip[ipp].idm[im]].dstep_red(ipp, im, ido); |
break; |
case bbmcoupmat: |
bbm[ip[ipp].idm[im]].dstep_red(ipp, im, ido); |
break; |
case doublestructuremat: |
dsm[ip[ipp].idm[im]].dstep_red(ipp, im, ido); |
break; |
case hypoplastmat: |
ret = hypopl[ip[ipp].idm[im]].dstep_red(ipp,im,ido); |
break; |
8558,6 → 8687,10 |
f = bbm[ip[ipp].idm[idpm]].yieldfunction (sig,q); |
break; |
} |
case doublestructuremat:{ |
f = dsm[ip[ipp].idm[idpm]].yieldfunction (sig,q); |
break; |
} |
case hissplasmat:{ |
f = hisspl[ip[ipp].idm[idpm]].yieldfunction (sig,q); |
break; |
8632,6 → 8765,10 |
bbm[ip[ipp].idm[idpm]].deryieldfsigma (sig, q, dfdst); |
break; |
} |
case doublestructuremat:{ |
dsm[ip[ipp].idm[idpm]].deryieldfsigma (sig, q, dfdst); |
break; |
} |
default: |
print_err("unknown plasticity model is required",__FILE__,__LINE__,__func__); |
8704,6 → 8841,10 |
bbm[ip[ipp].idm[idpm]].deryieldfsigma (sig, q, dgdst); |
break; |
} |
case doublestructuremat:{ |
dsm[ip[ipp].idm[idpm]].deryieldfsigma (sig, q, dgdst); |
break; |
} |
default: |
print_err("unknown plasticity model is required",__FILE__,__LINE__,__func__); |
8760,10 → 8901,14 |
case modcamclaycoupmat:{ |
cclayc[ip[ipp].idm[idpm]].deryieldfq (sig, q, dq); |
break; |
} |
case bbmcoupmat:{ |
bbm[ip[ipp].idm[idpm]].deryieldfq (sig, q, dq); |
break; |
} |
case doublestructuremat:{ |
dsm[ip[ipp].idm[idpm]].deryieldfq (sig, q, dq); |
break; |
} |
case chenplast:{ |
chplast[ip[ipp].idm[idpm]].deryieldfdq (sig,q,dq); |
8816,6 → 8961,10 |
bbm[ip[ipp].idm[idpm]].dderyieldfsigma (dfdsdst); |
break; |
} |
case doublestructuremat:{ |
dsm[ip[ipp].idm[idpm]].dderyieldfsigma (dfdsdst); |
break; |
} |
case chenplast:{ |
chplast[ip[ipp].idm[idpm]].deryieldfdsigmadsigma (sig,dfdsdst); |
break; |
8875,6 → 9024,10 |
bbm[ip[ipp].idm[idpm]].dderyieldfsigma (dgdsdst); |
break; |
} |
case doublestructuremat:{ |
dsm[ip[ipp].idm[idpm]].dderyieldfsigma (dgdsdst); |
break; |
} |
case chenplast:{ |
chplast[ip[ipp].idm[idpm]].deryieldfdsigmadsigma (sig, dgdsdst); |
break; |
8935,6 → 9088,10 |
bbm[ip[ipp].idm[idpm]].deryieldfdsdq (dfdsdqt); |
break; |
} |
case doublestructuremat:{ |
dsm[ip[ipp].idm[idpm]].deryieldfdsdq (dfdsdqt); |
break; |
} |
case chenplast:{ |
chplast[ip[ipp].idm[idpm]].deryieldfdsigmadq (sig,q,dfdsdqt); |
break; |
8990,6 → 9147,10 |
bbm[ip[ipp].idm[idpm]].deryieldfdsdq (dgdsdqt); |
break; |
} |
case doublestructuremat:{ |
dsm[ip[ipp].idm[idpm]].deryieldfdsdq (dgdsdqt); |
break; |
} |
case chenplast:{ |
chplast[ip[ipp].idm[idpm]].deryieldfdsigmadq (sig,q,dgdsdqt); |
break; |
9039,6 → 9200,14 |
cclayc[ip[ipp].idm[idpm]].der_q_gamma(ipp, ido, sig, q, epsp, dqdg); |
break; |
} |
case bbmcoupmat:{ |
bbm[ip[ipp].idm[idpm]].der_q_gamma(ipp, ido, sig, q, epsp, dqdg); |
break; |
} |
case doublestructuremat:{ |
dsm[ip[ipp].idm[idpm]].der_q_gamma(ipp, ido, sig, q, epsp, dqdg); |
break; |
} |
default: |
print_err("unknown plasticity model is required",__FILE__,__LINE__,__func__); |
} |
9079,6 → 9248,14 |
cclayc[ip[ipp].idm[idpm]].dqpardgammadsigma(ipp, ido, sig, q, epsp, dqdgdst); |
break; |
} |
case bbmcoupmat:{ |
bbm[ip[ipp].idm[idpm]].dqpardgammadsigma(ipp, ido, sig, q, epsp, dqdgdst); |
break; |
} |
case doublestructuremat:{ |
dsm[ip[ipp].idm[idpm]].dqpardgammadsigma(ipp, ido, sig, q, epsp, dqdgdst); |
break; |
} |
default: |
print_err("unknown plasticity model is required",__FILE__,__LINE__,__func__); |
9117,6 → 9294,14 |
cclayc[ip[ipp].idm[idpm]].dqpardgammadqpar(ipp, ido, sig, q, epsp, dqdgdq); |
break; |
} |
case bbmcoupmat:{ |
bbm[ip[ipp].idm[idpm]].dqpardgammadqpar(ipp, ido, sig, q, epsp, dqdgdq); |
break; |
} |
case doublestructuremat:{ |
dsm[ip[ipp].idm[idpm]].dqpardgammadqpar(ipp, ido, sig, q, epsp, dqdgdq); |
break; |
} |
default: |
print_err("unknown plasticity model is required",__FILE__,__LINE__,__func__); |
9176,6 → 9361,10 |
bbm[ip[ipp].idm[idpm]].deryieldfq (sig, q, dq); |
break; |
} |
case doublestructuremat:{ |
dsm[ip[ipp].idm[idpm]].deryieldfq (sig, q, dq); |
break; |
} |
case chenplast:{ |
chplast[ip[ipp].idm[idpm]].deryieldfdq (sig,q,dq); |
break; |
9486,9 → 9675,13 |
break; |
} |
case bbmcoupmat:{ |
ret = bbm[ip[ipp].idm[idpm]].plasmodscalar(ipp, ido, sig, qtr); |
ret = bbm[ip[ipp].idm[idpm]].plasmodscalar(ipp, ido, sig, qtr, epsp); |
break; |
} |
case doublestructuremat:{ |
ret = dsm[ip[ipp].idm[idpm]].plasmodscalar(ipp, ido, sig, qtr, epsp); |
break; |
} |
default: |
print_err("unknown plasticity model is required",__FILE__,__LINE__,__func__); |
9540,7 → 9733,8 |
case modcamclaycoupmat:{ |
break; |
} |
case bbmcoupmat:{ |
case bbmcoupmat: |
case doublestructuremat:{ |
break; |
} |
default: |
9594,7 → 9788,8 |
case modcamclaycoupmat:{ |
break; |
} |
case bbmcoupmat:{ |
case bbmcoupmat: |
case doublestructuremat:{ |
break; |
} |
/* |
9673,6 → 9868,10 |
bbm[ip[ipp].idm[idpm]].updateq(ipp, ido, eps, epsp, sig, q); |
break; |
} |
case doublestructuremat:{ |
dsm[ip[ipp].idm[idpm]].updateq(ipp, ido, eps, epsp, sig, q); |
break; |
} |
default: |
print_err("unknown plasticity model is required",__FILE__,__LINE__,__func__); |
11668,6 → 11867,7 |
case creep_damage:{ |
ncompo = givencompeqother(ipp, im); |
ncompo -= givencompeqother(ipp, im+1); |
ncompo -= givencompeqother(ipp, im+2); |
givestressincr (lcid, ipp, im+1, ido+ncompo, fi, sig); |
break; |
} |
11696,6 → 11896,14 |
hypoplustherm[i].givestressincr(lcid, ipp, im, ido, fi, sig); |
break; |
} |
case bbmcoupmat:{ |
i=ip[ipp].idm[im]; |
bbm[i].givestressincr(lcid, ipp, im, ido, fi, sig); |
} |
case doublestructuremat:{ |
i=ip[ipp].idm[im]; |
dsm[i].givestressincr(lcid, ipp, im, ido, fi, sig); |
} |
/* |
case consolidation:{ |
csol[ip[ipp].idm[im]].give_dstresses_eqother (ipp,ido,sig); |
11728,7 → 11936,6 |
case chenplast: |
case modcamclaymat: |
case modcamclaycoupmat: |
case bbmcoupmat: |
case shefpl: |
case glasgowmechmat: |
case glasgowdamage: |
/trunk/SIFEL/MEFEL/SRC/mechmat.h |
---|
27,6 → 27,7 |
class doubdp; |
class drprag2; |
class bbmmat; |
class dsmmat; |
class camclay; |
class camclaycoup; |
class shefplast; |
869,6 → 870,8 |
doubdp *ddpm; |
/// Drucker-Prager model of plasticity prepare by Standa Sysala from IGN |
drprag2 *drprm2; |
/// double structure model |
dsmmat *dsm; |
/// modified barcelona basic model |
bbmmat *bbm; |
/// modified cam-clay model |
/trunk/SIFEL/MEFEL/SRC/mtsolver.cpp |
---|
778,9 → 778,9 |
if (Mespr==1) fprintf (stdout,"\n MEFEL Time step = %ld, Time %e, Time increment = %e",istep,Mp->time,dt); |
if (Mespr==1) fprintf (stdout,"\n ------------------------------------------------------------------------\n"); |
//if (Mespr==1) fprintf (Out,"\n\n ------------------------------------------------------------------------"); |
//if (Mespr==1) fprintf (Out,"\n MEFEL Time step = %ld, Time %e, Time increment = %e",istep,Mp->time,dt); |
//if (Mespr==1) fprintf (Out,"\n ------------------------------------------------------------------------\n"); |
if (Mespr==1) fprintf (Out,"\n\n ------------------------------------------------------------------------"); |
if (Mespr==1) fprintf (Out,"\n MEFEL Time step = %ld, Time %e, Time increment = %e",istep,Mp->time,dt); |
if (Mespr==1) fprintf (Out,"\n ------------------------------------------------------------------------\n"); |
// assembling of vectors of prescribed nodal forces |
mefel_right_hand_side (lcid,f,fl); |
793,7 → 793,19 |
// istep, Mp->time, Mp->time/86400, Mb->sumcomp[0], Mb->sumcomp[1], Mb->sumcomp[2]); |
//fflush(Out); |
//debug??!! |
//long i; |
//fprintf(Out,"\n\n"); |
//for(i=0; i<n; i++) |
//fprintf(Out,"\n f[%ld] = %e",i,f[i]); |
//fflush(Out); |
//fprintf(Out,"\n\n"); |
//for(i=0; i<n; i++) |
//fprintf(Out,"\n fl[%ld] = %e",i,fl[i]); |
//fflush(Out); |
// assemble force vector due to removed elements and apply it gradually if required |
if (Mp->tprob == growing_mech_structure) |
{ |
803,6 → 815,12 |
// increments of prescribed internal forces |
incr_internal_forces (lcid,fi); |
//debug??!! |
//fprintf(Out,"\n\n"); |
//for(i=0; i<n; i++) |
//fprintf(Out,"\n fi[%ld] = %e",i,fi[i]); |
//fflush(Out); |
// assembling of right hand side |
// fb[j]=f[j]-fp[j]+fi[j] |
subv(f, fp, fb, n); |
/trunk/SIFEL/MEFEL/SRC/newtonraph.cpp |
---|
706,7 → 706,8 |
double gnewton_raphson_one_step(long lcid, nonlinman *nlman, double *fa, double *ra, double *fb, double *dr, double *fi, |
double &dtr, long istep, long &j, long li, answertype fusm) |
{ |
long i,n = Ndofm; // number of rows of the matrix or vectors |
long i; |
long n = Ndofm; // number of rows of the matrix or vectors |
long ini; // maximum number of inner iterations |
double ierr; // required error of the residual vector |
double norf; // norm of residual vector (vector of unbalanced forces) |
740,11 → 741,13 |
// solution of K(r).\Delta r=\Delta F |
Mp->ssle->solve_system (Gtm,Smat,dr,fb,Out); |
/* if (Mp->time >= 5.375400e+05 && Mp->time<= 5.385400e+05){ |
for (i=0;i<n;i++) |
fprintf (Out,"\%le\n",dr[i]); |
} |
*/ |
// if (Mp->time >= 5.375400e+05 && Mp->time<= 5.385400e+05){ |
//fprintf (Out,"\n istep = %ld j = %ld \n",istep,j); |
//for (i=0;i<n;i++) |
// fprintf (Out,"% .15le\n",dr[i]); |
//fflush(Out); |
//} |
// update total displacement vector |
// ra[j]+=dr[j]; |
777,7 → 780,7 |
//fprintf(Outdm->outf, "\n****** Load step %ld, norf=%le:\n\n", istep+1, norf); |
//Outdm->eo.print_out(Outdm->outf, lcid); |
fprintf (stdout,"\n Initial residual norm norf=%le, norm of load vector norfa=%le",norf,norfa); |
fprintf (stdout,"\n Initial residual norm norf=%.15le, norm of load vector norfa=%.15le",norf,norfa); |
//fprintf (Out,"\n norf=%e\n",norf); |
if (norf<ierr) |
803,6 → 806,12 |
// solution of K(r).v=F |
Mp->ssle->solve_system(Gtm,Smat,dr,fb,Out); |
//fprintf (Out,"Inner loop \n istep = %ld j = %ld \n",istep,j); |
//for (i=0;i<n;i++) |
// fprintf (Out,"% .15le\n",dr[i]); |
//fflush(Out); |
// ra[k]+=dr[k]; |
addv(ra, dr, n); |
831,7 → 840,7 |
//fprintf(Outdm->outf, "\n****** Internal loop %ld, norf=%le:\n\n", j+1, norf); |
//Outdm->eo.print_out(Outdm->outf, lcid); |
fprintf (stdout,"\n increment %ld inner loop j %ld norm %le, norfa %le", istep, j, norf, norfa); |
fprintf (stdout,"\n increment %ld inner loop j %ld norm %.15le, norfa %.15le", istep, j, norf, norfa); |
//fprintf (Out,"\n j=%ld norf=%e",j,norf); |
/* |
vector pe(ASTCKVEC(1)); |
/trunk/SIFEL/METR/SRC/bentonitemat.cpp |
---|
353,7 → 353,7 |
long i,j; |
// pocet slozek strainu |
long ncomp = Cm->ip[ipp].ncompstr; |
strastrestate ssst = Cm->ip[ipp].ssst; |
//strastrestate ssst = Cm->ip[ipp].ssst; |
double aux; |
matrix dd_gen(ASTCKMAT(ngstress,ngstrain)), dd(ASTCKMAT(6,6)), ddd(ASTCKMAT(ngstress,ngstrain)); |
vector statev(ASTCKVEC(nstatev)); |
/trunk/SIFEL/METR/SRC/consol_hawf3c.cpp |
---|
1245,7 → 1245,8 |
double con_hawf3matc::get_capwu(double pw, double pg, double t,long ipp) |
{ |
double capwu; |
double sw,sg,alpha,rhow,rhogw,n,dsr_depsv; |
double sw,sg,alpha,rhow,rhogw; |
//double n,dsr_depsv; |
sw = get_sw(pw,pg,t,ipp); |
alpha = get_alpha(pw,pg,t,ipp); |
1310,7 → 1311,8 |
double con_hawf3matc::get_capgu(double pw, double pg, double t,long ipp) |
{ |
double capgu; |
double sg,sw,alpha,rhoga,n,dsr_depsv; |
double sg,sw,alpha,rhoga; |
//double n,dsr_depsv; |
sw = get_sw(pw,pg,t,ipp); |
alpha = get_alpha(pw,pg,t,ipp); |
1427,7 → 1429,8 |
double con_hawf3matc::get_captu(double pw,double pg,double t,long ipp) |
{ |
double captu; |
double dhvap,sw,rhow,alpha,n,dsr_depsv; |
double dhvap,sw,rhow,alpha; |
//double n,dsr_depsv; |
dhvap = get_dhvap(t); |
sw = get_sw(pw,pg,t,ipp); |
/trunk/SIFEL/METR/SRC/globmatc.cpp |
---|
654,13 → 654,14 |
@param rhs - right hand side |
21.3.2004, JK+TKr |
09/11/2012 corrected by TKr |
09/11/2012 corrected by TKr, |
20/04/2023 another correction by TKr |
*/ |
void assemble_init_coup (double *rhs) |
{ |
long i,j,mndofe,tndofe,lcid=0; |
double dt; |
ivector rcn; |
ivector rcn,ccn; |
vector r,f,pr; |
matrix km,cm; |
674,12 → 675,14 |
reallocv (RSTCKVEC(tndofe,pr)); |
reallocm (RSTCKMAT(mndofe,tndofe,km)); |
reallocv (RSTCKIVEC(mndofe, rcn)); |
reallocv (RSTCKIVEC(tndofe, ccn)); |
upper_cond_coupl_mat (i,lcid,km); |
Gtm->give_code_numbers (i,rcn.a); |
Gtt->give_code_numbers (i,ccn.a); |
//elemvalues (i, r); |
prescvalues (r.a,rcn.a,mndofe); //old wrong: prescvalues (r.a,rcn.a,tndofe); |
// prescribed values from TRFEL |
prescvalues (r.a,ccn.a,tndofe); |
mxv (km,r,f); |
cmulv (-1.0,f); |
688,7 → 691,7 |
// contribution from time derivative of prescribed values on boundaries |
// prescribed values from the previous time step |
prevprescvalues (pr.a,rcn.a,mndofe);//old: prevprescvalues (pr.a,rcn.a,tndofe); |
prevprescvalues (pr.a,rcn.a,tndofe); |
// the length of time step |
dt=Tp->timecont.forwarddt; |
// computation of the time derivative of |
715,13 → 718,16 |
reallocv (RSTCKVEC(mndofe,pr)); |
reallocm (RSTCKMAT(tndofe,mndofe,km)); |
reallocv (RSTCKIVEC(tndofe, rcn)); |
reallocv (RSTCKIVEC(mndofe, ccn)); |
lower_cond_coupl_mat (i,lcid,km); |
Gtt->give_code_numbers (i,rcn.a);//old:Gtm->give_code_numbers (i,rcn.a); |
Gtt->give_code_numbers (i,rcn.a); |
Gtm->give_code_numbers (i,ccn.a); |
//elemvalues (i, r); |
prescvalues (r.a,rcn.a,tndofe);//old: prescvalues (r.a,rcn.a,mndofe); |
// prescribed values (displacements) from MEFEL |
// prescdispl (r.a,ccn.a,mndofe); // not implemented in MEFEL |
elprdispl (lcid,i,r.a); |
mxv (km,r,f); |
cmulv (-1.0,f); |
728,9 → 734,9 |
locglob (rhs,f.a,rcn.a,tndofe); |
// contribution from time derivative of prescribed values on boundaries |
// prescribed values from the previous time step |
prevprescvalues (pr.a,rcn.a,tndofe);//old: prevprescvalues (pr.a,rcn.a,mndofe); |
// contribution from time derivative of prescribed values on boundaries - displacements |
// prevprescdislp (pr.a,rcn.a,mndofe); // not implemented in MEFEL |
elprevprdispl (lcid,i,pr.a); |
// the length of time step |
dt=Tp->timecont.forwarddt; |
// computation of the time derivative of |
747,7 → 753,7 |
cmulv (-1.0,f); |
// localization of nodal values |
locglob (rhs,f.a,rcn.a,tndofe); |
locglob (rhs,f.a,ccn.a,tndofe); |
} |
} |
2156,8 → 2162,23 |
char *ips = new char[tnipt]; |
memset(ips, 0, sizeof(*ips)*tnipt); |
if (Mesprc == 1) |
fprintf(stdout, "\nCalculation of auxiliary int. points TRFEL->MEFEL:\n"); |
if (Tm->nntq == 0){ |
fprintf(stdout, "No mechanical quantities are required in TRFEL => no auxiliary points are calculated\n"); |
for(j=0; j<tnipt; j++){ |
TMipmap[j].cerr = err*err/10.0; |
TMipmap[j].ipp = 0; |
TMipmap[j].eid = 0; |
} |
return; |
} |
for(i=0; i<nem; i++) |
{ |
if ((Mesprc == 1) && ((i%1000 == 0) || (i == nem-1))){ |
fprintf(stdout, "Searching aux. points on %ld. element\r", i+1); |
fflush(stdout); |
} |
if(Gtm->leso[i]) |
{ |
centroid(i, cg); |
2230,6 → 2251,7 |
} |
} |
} |
fprintf(stdout, "\n"); |
delete [] ips; |
} |
2268,8 → 2290,24 |
char *ips = new char[tnipm]; |
memset(ips, 0, sizeof(*ips)*tnipm); |
if (Mesprc == 1) |
fprintf(stdout, "\nCalculation of auxiliary int. points MEFEL->TRFEL:\n"); |
if (Mm->nnmq == 0){ |
fprintf(stdout, "No transport quantities are required in MEFEL => no auxiliary points are calculated\n"); |
for(j=0; j<tnipm; j++){ |
MTipmap[j].cerr = err*err/10.0; |
MTipmap[j].ipp = 0; |
MTipmap[j].eid = 0; |
} |
return; |
} |
for(i=0; i<net; i++) |
{ |
if ((Mesprc == 1) && ((i%1000 == 0) || (i == net-1))){ |
fprintf(stdout, "Searching aux. points on %ld. element\r", i+1); |
fflush(stdout); |
} |
if(Gtt->leso[i]) |
{ |
centroidt(i, cg); |
2342,6 → 2380,7 |
} |
} |
} |
fprintf(stdout, "\n"); |
delete [] ips; |
} |
/trunk/SIFEL/METR/SRC/metrinit.cpp |
---|
612,7 → 612,9 |
if (Cp->tprob!=fully_coupled_material){ |
switch (Cp->dpt){ |
case pass_by_closest_ip: |
//data are copied directly between int. points, the SAME int. point must be used on both meshes for the first Tt->ne elements |
// data are copied directly between nodes, |
// the first n-th elements must be defined on both meshes with the SAME node numbers, MEFEL elements may use higher number of nodes, |
// but first m nodes on elements must be the SAME |
// |
// create mapping between TRFEL and MEFEL nodes |
TM_nod_map = new long[Tt->nn]; |
/trunk/SIFEL/METR/SRC/probdescc.cpp |
---|
46,7 → 46,7 |
// the maximum number of itartions in the computation of auxiliary int. point coordinates |
aip_ni = 100; |
// the maximum distance of two points at which they may be assumed to be identical in the computation of auxiliary int. point coordinates |
aip_err = 1.0e-6; |
aip_err = 1.0e-5; |
incr_step=0; |
inner_step=0; |
/trunk/SIFEL/TRFEL/SRC/C30bazant.cpp |
---|
13,6 → 13,7 |
#include "constrel.h" |
#include "C30bazant.h" |
#include "globalt.h" |
#include "globmatt.h" |
C30bazmat::C30bazmat() |
{ |
754,3 → 755,27 |
*/ |
void C30bazmat::print(FILE *out) |
{} |
/** |
The function returns ordered dof names of primary unknowns |
required by the model. |
@param dofname - array of uknown name for particular nodal dofs (output) |
dofname[i] = name of i-th nodal unknown (for names see aliast.h - enum namevart) |
@param ntm - number of transported media = number of nodal dof = length of array dofname |
Created by Tomas Krejci according to Tomas Koudelka, 11/01/2023 |
*/ |
void C30bazmat::give_dof_names(namevart *dofname, long ntm) |
{ |
if (ntm < 1) |
{ |
print_err("the model defines %ld unknowns but number of transported media is %ld", |
__FILE__, __LINE__, __func__, 1, ntm); |
abort(); |
} |
dofname[0] = trf_capillary_press; |
dofname[1] = trf_gas_press; |
dofname[2] = trf_temperature; |
} |
/trunk/SIFEL/TRFEL/SRC/C30bazant.h |
---|
1,6 → 1,7 |
#ifndef C30_BAZANT_H |
#define C30_BAZANT_H |
#include "aliast.h" |
#include "genfile.h" |
class C30bazmat |
43,6 → 44,8 |
void read(XFILE *in); |
void print(FILE *out); |
void give_dof_names(namevart *dofname, long ntm); |
private: |
double mw; |
double ma; |
/trunk/SIFEL/TRFEL/SRC/C60bazant.h |
---|
1,6 → 1,7 |
#ifndef C60_BAZANT_H |
#define C60_BAZANT_H |
#include "aliast.h" |
#include "genfile.h" |
class C60bazmat |
/trunk/SIFEL/TRFEL/SRC/Makefile |
---|
39,7 → 39,7 |
SRCS += glasgowmat.cpp globalt.cpp globmatt.cpp gmultiphase.cpp grunewaldmat.cpp homogt.cpp homogmat.cpp homogtrans.cpp hydrationheat.cpp |
SRCS += interfacematt.cpp interfacequadrilat.cpp intpointst.cpp isotherm.cpp isotrmat.cpp |
SRCS += kunzel.cpp kunzel2.cpp lhsrhst.cpp lewis_schrefler.cpp linbart.cpp linbart3d.cpp linbartax.cpp lincoupmat.cpp linhext.cpp lintett.cpp |
SRCS += loadcaset.cpp loadelt.cpp millymat.cpp moistheat.cpp multiphase.cpp nlisotrmat.cpp npglvec.cpp nnpsolvert.cpp nodet.cpp nonlinmant.cpp |
SRCS += loadcaset.cpp loadelt.cpp masin_reten.cpp millymat.cpp moistheat.cpp multiphase.cpp nlisotrmat.cpp npglvec.cpp nnpsolvert.cpp nodet.cpp nonlinmant.cpp |
SRCS += npsolvert.cpp nspsolvert.cpp onemedium.cpp outdiagt.cpp outdrivert.cpp o30bazant.cpp pedersen.cpp |
SRCS += probdesct.cpp pvalt.cpp potts.cpp quadbart.cpp quadbartax.cpp quadhext.cpp quadlinaxisym.cpp quadlineart.cpp |
SRCS += quadquadrilatt.cpp quadquadrilattax.cpp radiationmat.cpp richards.cpp richardscontam.cpp saltmat1.cpp saltmat2.cpp saltmat3.cpp saltmat4.cpp seebeckheat.cpp |
/trunk/SIFEL/TRFEL/SRC/aliast.h |
---|
118,8 → 118,8 |
// aliases for boundary conditions |
enum bocontypet {no_bc=0, presc_comp=1, presc_flux=2, det_climcond=3, gen_climcond=5, presc_trmiss=30, presc_trmiss_spec=31,presc_trmiss_isoheat=32,presc_trmiss_computed=50,presc_trmiss_radiation=90, presc_trmiss_free_surface=40,}; |
const enumstr bocontypetstr[] = {{"no_bc",0}, {"presc_comp",1}, {"presc_flux",2}, {"det_climcond",3}, {"gen_climcond",5}, {"presc_trmiss",30}, {"presc_trmiss_spec",31},{"presc_trmiss_isoheat",32},{"presc_trmiss_computed",50},{"presc_trmiss_radiation",90},{"presc_trmiss_free_surface",40}}; |
enum bocontypet {no_bc=0, presc_comp=1, presc_flux=2, det_climcond=3, gen_climcond=5, presc_trmiss=30, presc_trmiss_spec=31,presc_trmiss_isoheat=32,presc_trmiss_computed=50,presc_trmiss_salt=51,presc_trmiss_radiation=90, presc_trmiss_free_surface=40,}; |
const enumstr bocontypetstr[] = {{"no_bc",0}, {"presc_comp",1}, {"presc_flux",2}, {"det_climcond",3}, {"gen_climcond",5}, {"presc_trmiss",30}, {"presc_trmiss_spec",31},{"presc_trmiss_isoheat",32},{"presc_trmiss_computed",50},{"presc_trmiss_salt",51},{"presc_trmiss_radiation",90},{"presc_trmiss_free_surface",40}}; |
const kwdset bocontype_kwdset(sizeof(bocontypetstr)/sizeof(*bocontypetstr), bocontypetstr); |
188,11 → 188,16 |
enum sourceloc {nod=1,elem=2}; |
// aliases for models of retention curve type |
enum sr_type {lewis_and_schrefler_sr=1,gardner_exponential_sr=2,potts_log_linear_sr=3,van_genuchten_sr=4,van_genuchten2_sr=5,mefel_sr=7,table_sr=8,bazant_sr=9,baroghel_sr=10}; |
enum sr_type {lewis_and_schrefler_sr=1,gardner_exponential_sr=2,potts_log_linear_sr=3,van_genuchten_sr=4,van_genuchten2_sr=5,mefel_sr=7,table_sr=8,bazant_sr=9,baroghel_sr=10,masin_sr=11}; |
const enumstr sr_typestr[] = {{"lewis_and_schrefler_sr",1}, {"gardner_exponential_sr",2}, {"potts_log_linear_sr",3}, {"van_genuchten_sr",4}, |
{"mefel_sr",7},{"table_sr",8},{"bazant_sr",9},{"baroghel_sr",10}}; |
{"mefel_sr",7},{"table_sr",8},{"bazant_sr",9},{"baroghel_sr",10},{"masin_sr",11}}; |
const kwdset sr_type_kwdset(sizeof(sr_typestr)/sizeof(*sr_typestr),sr_typestr); |
// aliases for models of effective stress factor (parameter) type |
enum xi_type {biot_xi=1,masin_xi=2,biot_reduced_xi=3,biot_masin_xi=4}; |
const enumstr xi_typestr[] = {{"biot_xi",1}, {"masin_xi",2},{"biot_reduced_xi",3},{"biot_masin_xi",4}}; |
const kwdset xi_type_kwdset(sizeof(xi_typestr)/sizeof(*xi_typestr),xi_typestr); |
#endif |
/trunk/SIFEL/TRFEL/SRC/baroghelB.h |
---|
1,6 → 1,7 |
#ifndef BAROGHELB_H |
#define BAROGHELB_H |
#include "aliast.h" |
#include "genfile.h" |
class baroghelmat |
/trunk/SIFEL/TRFEL/SRC/consol_hawf3.cpp |
---|
33,11 → 33,13 |
con_hawf3mat::con_hawf3mat() |
{ |
compress = 0; //compressible grains: 0=no; 1=yes |
por_type = 0; //porosity calculation type |
kintr_type = 0; //intrinsic permability calculation type |
krw_type = 0; //relative permeability calculation type |
krg_type = 0; //relative permability calculation type |
deff_type = 0; // diffusion calculation type |
sr_type = 1; //retention curve calculation type |
xi_type = 1; //effective stress parameter type |
lambda_type =0; //heat conduction calculation type |
cps_type = 0; //specific heat calculation type |
betas_type = 0; //thermal expansion calculation type |
126,9 → 128,13 |
sr_dry = 0.0; |
sr_wet = 0.0; |
tau0 = 0.0; |
sirr = 0.0; |
ssat = 1.0; |
lambda_krw = 1.9; //parameter for exponential function of relative permeability |
beta_krw = 0.0; //parameter for power function of relative permeability |
bb1 = 0.0; |
phi01 = 0.0; |
160,7 → 166,7 |
xfscanf (in,"%d", &compress); |
// common material parameters |
xfscanf (in,"%le %le %le %le %le %le %le %d %d %d %d %d %d %d %d", &alpha0, &ks0, &phi0, &rhos0, &pw_bc, &tau0, &kintr0, &kintr_type, &krw_type, &krg_type, &deff_type, &sr_type, &lambda_type, &cps_type, &betas_type); |
xfscanf (in,"%le %le %le %le %le %le %d %d %d %d %d %d %d %d %d %d", &alpha0, &ks0, &rhos0, &pw_bc, &tau0, &kintr0, &por_type, &kintr_type, &krw_type, &krg_type, &deff_type, &sr_type, &xi_type, &lambda_type, &cps_type, &betas_type); |
switch (model_type){ |
case artificial3:{//artificial isotropic material for non-isotherma air-water flow |
181,6 → 187,21 |
} |
if(model_type != artificial3){ |
//porosity calculation: |
switch (por_type){ |
case 0:{//constant |
xfscanf (in,"%le",&phi0); |
break; |
} |
case 1:{//dependent on mefel calculation |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
} |
} |
//intrinsic permebility calculation: |
switch (kintr_type){ |
case 0:{//constant |
190,6 → 211,10 |
xfscanf (in,"%le %le", &bb1, &phi01); |
break; |
} |
case 2:{//dependent on porosity - cubic and quadratic |
xfscanf (in,"%le", &phi01); |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
210,6 → 235,14 |
xfscanf (in,"%le", &lambda_krw); |
break; |
} |
case 4:{//liakopoulos |
break; |
} |
case 5:{//double exponential |
xfscanf (in,"%le %le", &sirr, &ssat); |
xfscanf (in,"%le", &beta_krw); |
break; |
} |
case 9:{//bazant |
break; |
} |
268,6 → 301,10 |
data.read (in); |
break; |
} |
case masin_sr:{//extended formulation from Brooks and Correy according to Masin |
masin_ret.read(in); |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
274,6 → 311,22 |
} |
} |
switch (xi_type){ |
case biot_xi: |
break; |
case biot_reduced_xi:{//coefficient for effective stress factor reduction |
xfscanf (in,"%le %le", &gamma,&lambda0); |
break; |
} |
case masin_xi: |
break; |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
} |
} |
//conductivity calculation: |
switch (lambda_type){ |
case 0:{//constant |
525,7 → 578,63 |
return(deff); |
} |
/** |
function computes effective stress factor xi |
@param pw - water pressure |
@param t - temperature |
@retval xi - factor xi |
04/04/2023, TKr |
*/ |
double con_hawf3mat::get_xi(double pw, double pg, double t, long ipp) |
{ |
double sw=0.0,xi=0.0; |
switch (xi_type){ |
case biot_xi: |
sw = get_sw(pw,pg,t,ipp); |
break; |
case biot_reduced_xi: |
//xi = gamma*get_sw(pw,pg,t,ipp); |
sw = get_sw(pw,pg,t,ipp); |
//xi = pow(sr,(gamma/lambda0)); |
xi = pow(sw,gamma); |
xi = (1-gamma)*xi; |
break; |
case masin_xi:{ |
double e=0.0,dpw=0.0,dpg=0.0,dpc=0.0,pc=0.0,por=0.0; |
if(Tm->nontransq != NULL){ |
por = Tm->givenontransq(porosity, ipp);// from mefel |
e = por/(1-por); |
} |
else{ |
e = phi0/(1-phi0); |
} |
dpw = Tm->ip[ipp].av[0]-Tm->ip[ipp].pv[0]; |
dpg = Tm->ip[ipp].av[1]-Tm->ip[ipp].pv[1]; |
dpc = dpg - dpw; |
pg = pg - p0;//pore gas pressure without atmospheric pressure |
pc = pg - pw; |
xi = masin_ret.psi(pc,dpc,e,t);//positive value of suction |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
} |
} |
return(xi); |
} |
/** |
function computes degree of saturation(sorption curve) |
@param pw - water pressure |
@param pg - air pressure |
579,6 → 688,20 |
//sw = van_genuchten_ret.sw2(pw); |
break; |
} |
case masin_sr:{//extended formulation from Brooks and Correy according to Masin |
double e=0.0,dpw=0.0,por=0.0; |
if(Tm->nontransq != NULL){ |
por = Tm->givenontransq(porosity, ipp);// from mefel |
e = por/(1-por); |
} |
else{ |
e = phi0/(1-phi0); |
} |
dpw = Tm->ip[ipp].av[0]-Tm->ip[ipp].pv[0]; |
sw = masin_ret.sw(-pw,-dpw,e,t);//positive value of suction |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
634,6 → 757,25 |
//dsw_dpc = -van_genuchten_ret.dsw_dpw2(pw); |
break; |
} |
case masin_sr:{//extended formulation from Brooks and Correy according to Masin |
double e=0.0,dpw=0.0,dpg=0.0,dpc=0.0,pc=0.0,por=0.0; |
if(Tm->nontransq != NULL){ |
por = Tm->givenontransq(porosity, ipp);// from mefel |
e = por/(1-por); |
} |
else{ |
e = phi0/(1-phi0); |
} |
dpw = Tm->ip[ipp].av[0]-Tm->ip[ipp].pv[0]; |
dpg = Tm->ip[ipp].av[1]-Tm->ip[ipp].pv[1]; |
dpc = dpg - dpw; |
pg = pg - p0;//pore gas pressure without atmospheric pressure |
pc = pg - pw; |
dsw_dpc = masin_ret.dsw_dpw(pc,dpc,e,t);//positive value of suction |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
688,6 → 830,25 |
//dsw_dt = van_genuchten_ret.dsw_dt2(pw); |
break; |
} |
case masin_sr:{//extended formulation from Brooks and Correy according to Masin |
double e=0.0,dpw=0.0,dpg=0.0,dpc=0.0,pc=0.0,por=0.0; |
if(Tm->nontransq != NULL){ |
por = Tm->givenontransq(porosity, ipp);// from mefel |
e = por/(1-por); |
} |
else{ |
e = phi0/(1-phi0); |
} |
dpw = Tm->ip[ipp].av[0]-Tm->ip[ipp].pv[0]; |
dpg = Tm->ip[ipp].av[1]-Tm->ip[ipp].pv[1]; |
dpc = dpg - dpw; |
pg = pg - p0;//pore gas pressure without atmospheric pressure |
pc = pg - pw; |
dsw_dt = masin_ret.dsw_dt(pc,dpc,e,t);//positive value of suction |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
703,28 → 864,31 |
@retval phi - porosity |
15/04/2021, TKr |
04/04/2023, TKr |
*/ |
double con_hawf3mat::give_porosity(long ipp) |
{ |
double por; |
switch (model_type){ |
case lewis_and_schrefler:{//Lewis and Schrefler's book |
por = phi0; //constant value |
//porosity calculation: |
switch (por_type){ |
case 0:{//constant |
por = phi0; |
break; |
} |
case lewis_and_schrefler_mefel:{//Lewis and Schrefler's book |
por = Tm->givenontransq(porosity, ipp);// from mefel |
case 1:{//dependent on mefel calculation |
if(Tm->nontransq != NULL){ |
por = Tm->givenontransq(porosity, ipp);// from mefel |
} |
else |
por = phi0;//for testing |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
} |
} |
return(por); |
} |
756,14 → 920,12 |
kintr = kintr0*exp(bb1*(phi - phi01)); |
break; |
} |
case 2:{//not finished |
case 2:{//dependent on porosity - cubic and quadratic |
//Kozeny's approach for bentonite: |
//phi = get_porosity(pw,pg,t,ipp); |
//kintr = kintr0*(phi*phi*phi)/(1 - phi)/(1 - phi)*(1 - phi0)*(1 - phi0)/phi0/phi0/phi0; |
phi = give_porosity(ipp); |
kintr = kintr0*phi*phi*phi/(1 - phi01)*(1 - phi01)*(1 - phi)*(1 - phi)/(phi01*phi01*phi01); |
break; |
} |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
785,7 → 947,7 |
*/ |
double con_hawf3mat::get_krw(double pw, double pg, double t, long ipp) |
{ |
double sw,krw; |
double sw,sef,krw; |
krw = 1.0; |
switch (krw_type){ |
808,6 → 970,20 |
krw = pow(sw,lambda_krw); |
break; |
} |
case 4:{//liakopoulos |
sw = get_sw(pw,pg,t,ipp); |
krw = 1.0-2.207*pow((1.0-sw),1.0121); |
break; |
} |
case 5:{//double exponential |
sw = get_sw(pw,pg,t,ipp); |
sef = (sw-sirr)/(ssat-sirr); //effective saturation degree |
krw = pow(sef,(1.0/beta_krw)); |
krw = pow((1.0-krw),beta_krw); |
krw = pow((1.0-krw),2.0); |
krw = pow(sef,0.5)*krw; |
break; |
} |
case 9:{//bazant |
sw = get_sw(pw,pg,t,ipp); |
krw = exp(10.0*log(sw)); |
1811,14 → 1987,12 |
if((ri == 2) && (ci == 2)) |
k = get_ktt1(pw,pg,t,ipp);// *scale_t;//scaling |
//if(Tp->time >= 4.345400e+05) |
//fprintf(Outt,"matcond k = %e, ri = %ld, ci = %ld, ipp = %ld\n",k,ri,ci,ipp); |
//fflush(Outt); |
fillm(0.0,d); |
d[0][0] = k; d[0][1] = 0.0; |
d[1][0] = 0.0; d[1][1] = k; |
check_math_errel(ipp); |
} |
/** |
1907,10 → 2081,6 |
if((ri == 2) && (ci == 2)) |
c = get_captt(pw,pg,t,ipp);// *scale_t;//scaling |
//if(Tp->time >= 4.345400e+05) |
//fprintf(Outt,"matcap c = %e, ri = %ld, ci = %ld, ipp = %ld, pw = %e, pg = %e, t = %e\n",c,ri,ci,ipp,pw,pg,t); |
//fflush(Outt); |
check_math_errel(ipp); |
} |
2260,22 → 2430,76 |
double con_hawf3mat::get_fwu(double pw, double pg, double t, long ipp) |
{ |
double depsv_r,sw,fwu,dsr_depsv,n,sg,rhow,rhogw,alpha; |
fwu = 0.0; |
switch (model_type){ |
case artificial3: |
case lewis_and_schrefler3: |
case lewis_and_schrefler3:{ |
break; |
} |
case lewis_and_schrefler3_mefel:{//Lewis and Schrefler's book |
if(vol_strain_effect == 1){ |
n = get_porosity(pw,pg,t,ipp); |
n = give_porosity(ipp); |
depsv_r = Tm->givenontransq(strain_vol_rate, ipp); //actual rate of volumetric strain from MEFEL |
Tm->ip[ipp].eqother[0] = depsv_r; |
if (sr_type == mefel_sr){ |
Tm->ip[ipp].eqother[0] = depsv_r; //this is not necessary |
/* |
if (sr_type == mefel_sr){ |
dsr_depsv = Tm->givenontransq(der_saturation_deg_depsv, ipp); //actual derivative of saturation degree with respect to volumetric strain |
Tm->ip[ipp].eqother[1] = dsr_depsv; |
Tm->ip[ipp].eqother[1] = dsr_depsv; //this is not necessary |
} |
*/ |
switch (sr_type){ |
case lewis_and_schrefler_sr:{//Lewis and Schrefler's book |
dsr_depsv = 0.0; |
break; |
} |
case gardner_exponential_sr:{//dependent on saturation degree: |
dsr_depsv = 0.0; |
break; |
} |
case potts_log_linear_sr:{//exponential |
dsr_depsv = 0.0; |
break; |
} |
case van_genuchten_sr:{//partially saturated medium =Van Genuchten model |
dsr_depsv = 0.0; |
break; |
} |
case van_genuchten2_sr:{//partially saturated medium =Van Genuchten model |
dsr_depsv = 0.0; |
break; |
} |
case mefel_sr:{//from MEFEL |
dsr_depsv = Tm->givenontransq(der_saturation_deg_depsv, ipp); //actual derivative of saturation degree with respect to volumetric strain |
break; |
} |
case table_sr:{//from table |
dsr_depsv = 0.0; |
break; |
} |
case masin_sr:{//extended formulation from Brooks and Correy according to Masin |
double e=0.0,dpw=0.0,por=0.0; |
if(Tm->nontransq != NULL){ |
por = Tm->givenontransq(porosity, ipp);// from mefel |
e = por/(1-por); |
} |
else{ |
e = phi0/(1-phi0); |
} |
dpw = Tm->ip[ipp].av[0]-Tm->ip[ipp].pv[0]; |
dsr_depsv = masin_ret.dsw_depsv(-pw,-dpw,e,t);//positive value of suction |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
} |
} |
sw = get_sw(pw,pg,t,ipp); |
sg = 1.0 - sw; |
2285,9 → 2509,7 |
fwu = -1.0*(sg*rhogw + sw*rhow)*alpha*depsv_r;//volumetric strain effect |
if (sr_type == mefel_sr){ |
fwu = -n*(rhow - rhogw)*dsr_depsv*depsv_r;//volumetric strain effect |
} |
fwu = fwu - n*(rhow - rhogw)*dsr_depsv*depsv_r;//volumetric strain effect |
} |
break; |
} |
2320,17 → 2542,71 |
switch (model_type){ |
case artificial3: |
case lewis_and_schrefler3: |
case lewis_and_schrefler3:{ |
break; |
} |
case lewis_and_schrefler3_mefel:{//Lewis and Schrefler's book |
if(vol_strain_effect == 1){ |
n = give_porosity(ipp); |
depsv_r = Tm->givenontransq(strain_vol_rate, ipp); //actual rate of volumetric strain from MEFEL |
Tm->ip[ipp].eqother[0] = depsv_r; //this is not necessary |
if (sr_type == mefel_sr){ |
/* |
if (sr_type == mefel_sr){ |
dsr_depsv = Tm->givenontransq(der_saturation_deg_depsv, ipp); //actual derivative of saturation degree with respect to volumetric strain |
Tm->ip[ipp].eqother[1] = dsr_depsv; //this is not necessary |
} |
*/ |
switch (sr_type){ |
case lewis_and_schrefler_sr:{//Lewis and Schrefler's book |
dsr_depsv = 0.0; |
break; |
} |
n = get_porosity(pw,pg,t,ipp); |
case gardner_exponential_sr:{//dependent on saturation degree: |
dsr_depsv = 0.0; |
break; |
} |
case potts_log_linear_sr:{//exponential |
dsr_depsv = 0.0; |
break; |
} |
case van_genuchten_sr:{//partially saturated medium =Van Genuchten model |
dsr_depsv = 0.0; |
break; |
} |
case van_genuchten2_sr:{//partially saturated medium =Van Genuchten model |
dsr_depsv = 0.0; |
break; |
} |
case mefel_sr:{//from MEFEL |
dsr_depsv = Tm->givenontransq(der_saturation_deg_depsv, ipp); //actual derivative of saturation degree with respect to volumetric strain |
break; |
} |
case table_sr:{//from table |
dsr_depsv = 0.0; |
break; |
} |
case masin_sr:{//extended formulation from Brooks and Correy according to Masin |
double e=0.0,dpw=0.0,por=0.0; |
if(Tm->nontransq != NULL){ |
por = Tm->givenontransq(porosity, ipp);// from mefel |
e = por/(1-por); |
} |
else{ |
e = phi0/(1-phi0); |
} |
dpw = Tm->ip[ipp].av[0]-Tm->ip[ipp].pv[0]; |
dsr_depsv = masin_ret.dsw_depsv(-pw,-dpw,e,t);//positive value of suction |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
} |
} |
sw = get_sw(pw,pg,t,ipp); |
sg = 1.0 - sw; |
rhoga = get_rhoga(pw,pg,t); |
2337,9 → 2613,7 |
alpha = get_alpha(pw,pg,t,ipp); |
fgu = -alpha*sg*rhoga*depsv_r; |
if (sr_type == mefel_sr){ |
fgu = fgu + n*rhoga*dsr_depsv*depsv_r;//volumetric strain rate effect |
} |
fgu = fgu + n*rhoga*dsr_depsv*depsv_r;//volumetric strain rate effect |
} |
break; |
} |
2370,17 → 2644,74 |
ftu = 0.0; |
switch (model_type){ |
case artificial3: |
case lewis_and_schrefler3: |
case lewis_and_schrefler3:{ |
break; |
} |
case lewis_and_schrefler3_mefel:{//Lewis and Schrefler's book |
if(vol_strain_effect == 1){ |
n = give_porosity(ipp); |
depsv_r = Tm->givenontransq(strain_vol_rate, ipp); //actual rate of volumetric strain from MEFEL |
if (sr_type == mefel_sr){ |
Tm->ip[ipp].eqother[0] = depsv_r; //this is not necessary |
/* |
if (sr_type == mefel_sr){ |
dsr_depsv = Tm->givenontransq(der_saturation_deg_depsv, ipp); //actual derivative of saturation degree with respect to volumetric strain |
Tm->ip[ipp].eqother[1] = dsr_depsv; //this is not necessary |
} |
*/ |
switch (sr_type){ |
case lewis_and_schrefler_sr:{//Lewis and Schrefler's book |
dsr_depsv = 0.0; |
break; |
} |
n = get_porosity(pw,pg,t,ipp); |
case gardner_exponential_sr:{//dependent on saturation degree: |
dsr_depsv = 0.0; |
break; |
} |
case potts_log_linear_sr:{//exponential |
dsr_depsv = 0.0; |
break; |
} |
case van_genuchten_sr:{//partially saturated medium =Van Genuchten model |
dsr_depsv = 0.0; |
break; |
} |
case van_genuchten2_sr:{//partially saturated medium =Van Genuchten model |
dsr_depsv = 0.0; |
break; |
} |
case mefel_sr:{//from MEFEL |
dsr_depsv = Tm->givenontransq(der_saturation_deg_depsv, ipp); //actual derivative of saturation degree with respect to volumetric strain |
break; |
} |
case table_sr:{//from table |
dsr_depsv = 0.0; |
break; |
} |
case masin_sr:{//extended formulation from Brooks and Correy according to Masin |
double e=0.0,dpw=0.0,por=0.0; |
if(Tm->nontransq != NULL){ |
por = Tm->givenontransq(porosity, ipp);// from mefel |
e = por/(1-por); |
} |
else{ |
e = phi0/(1-phi0); |
} |
dpw = Tm->ip[ipp].av[0]-Tm->ip[ipp].pv[0]; |
dsr_depsv = masin_ret.dsw_depsv(-pw,-dpw,e,t);//positive value of suction |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
} |
} |
sw = get_sw(pw,pg,t,ipp); |
rhow = get_rhow(t); |
dhvap = get_dhvap(t); |
2388,9 → 2719,7 |
ftu = dhvap*sw*rhow*alpha*depsv_r; |
if (sr_type == mefel_sr){ |
ftu = ftu + dhvap*rhow*n*dsr_depsv*depsv_r;//volumetric strain rate effect |
} |
ftu = ftu + dhvap*rhow*n*dsr_depsv*depsv_r;//volumetric strain rate effect |
} |
break; |
} |
4162,7 → 4491,6 |
/** |
This function initializes material model data |
with respect of consistency parameter gamma. |
@param ipp - integration point number |
4218,6 → 4546,53 |
/** |
function returns effective pore pressure (pressure has negative sign - mechanical convention) |
@param ipp - integration point number |
@retval pw - pore water pressure |
*/ |
double con_hawf3mat::give_effective_pore_pressure(long ipp) |
{ |
double ps,pw,pg,t,xi=1.0; |
pw = Tm->ip[ipp].av[0]; |
pg = Tm->ip[ipp].av[1]; |
t = Tm->ip[ipp].av[2]; |
//needs to be corrected??!! |
switch (model_type){ |
case lewis_and_schrefler3:{//Lewis and Schrefler's book |
xi = get_xi(pw,pg,t,ipp);//effective stress factor |
pg = pg - p0;//pore gas pressure without atmospheric pressure |
ps = xi*pw + (1.0 - xi)*pg; |
ps = -ps;//returns effective pore pressure |
break; |
} |
case lewis_and_schrefler3_mefel:{//Lewis and Schrefler's book, saturation degree ind its derivative are obtained from mefel; |
xi = get_xi(pw,pg,t,ipp); //effective stress factor |
pg = pg - p0;//pore gas pressure without atmospheric pressure |
ps = xi*pw + (1.0 - xi)*pg; |
ps = -ps/mefel_units;//returns effective pore pressure //corrected units for mefel //basic units = Pa |
//debug???!!! |
//pw = -pw/mefel_units;//returns effective pore pressure //corrected units for mefel //basic units = Pa |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
} |
} |
return(ps); |
} |
/** |
function returns water pressure |
@param ipp - integration point number |
4431,21 → 4806,18 |
case lewis_and_schrefler3:{//Lewis and Schrefler's book |
break; |
} |
case van_genuchten3:{//partially saturated medium = Van Genuchten model |
break; |
} |
case lewis_and_schrefler3_mefel:{//Lewis and Schrefler's book, saturation degree ind its derivative are obtained from mefel; |
antq[saturation_deg-1] = 1; |
antq[der_saturation_deg-1] = 1; |
antq[der_saturation_deg_depsv-1] = 1; |
antq[porosity-1] = 1; |
antq[der_saturation_deg_dtemp-1] = 1; |
antq[strain_vol_rate-1] = 1; |
if (sr_type == mefel_sr){ |
antq[saturation_deg-1] = 1; |
antq[der_saturation_deg-1] = 1; |
antq[der_saturation_deg_depsv-1] = 1; |
antq[der_saturation_deg_dtemp-1] = 1; |
} |
if(vol_strain_effect == 1) |
antq[strain_vol_rate-1] = 1; |
break; |
} |
case lewis_and_schrefler3_2:{//Lewis and Schrefler's book p. 381 |
break; |
} |
default:{ |
print_err("unknown model type is required", __FILE__, __LINE__, __func__); |
} |
/trunk/SIFEL/TRFEL/SRC/consol_hawf3.h |
---|
7,6 → 7,7 |
#include "bazant_reten.h" |
#include "lewis_schrefler.h" |
#include "van_genuchten.h" |
#include "masin_reten.h" |
class con_hawf3mat |
{ |
22,6 → 23,7 |
double get_rhos(double t); |
double get_cdiff(double pw,double pg,double t); |
double get_dg(double pc,double pg,double t,long ipp); |
double get_xi(double pw, double pg, double t, long ipp); |
double get_sw(double pw, double pg, double t, long ipp); |
double get_ds_dpc(double pw, double pg, double t, long ipp); |
double get_ds_dt(double pw, double pg, double t, long ipp); |
148,6 → 150,7 |
double give_temperature(long ipp); |
double give_water_pressure(long ipp); |
double give_gas_pressure(long ipp); |
double give_effective_pore_pressure(long ipp); |
double give_pore_pressure(long ipp); |
double give_suction(long ipp); |
double give_saturation_degree(long ipp); |
164,7 → 167,8 |
lewis_reten lewis_ret; |
/// van Genuchten's retention curve: |
van_genuchten_reten van_genuchten_ret; |
/// Masin's retention curve for bentonite |
masin_reten masin_ret; |
/// general function for retention curve given by set of data |
gfunct data; |
172,7 → 176,7 |
heatairwaterflowtype model_type; |
int compress; |
int vol_strain_effect,kintr_type,krw_type,krg_type,sr_type,lambda_type,cps_type,betas_type,deff_type; |
int vol_strain_effect,por_type,kintr_type,krw_type,krg_type,sr_type,xi_type,lambda_type,cps_type,betas_type,deff_type; |
double ma;//molar mass of dry air |
double mw;//molar mass of water |
double gasr;//universal gas constant |
234,12 → 238,13 |
double pw_bc; |
double scale_pw,scale_pg,scale_t; |
int rel_gas_press; //relative gas pressure according to ambient air; yes=1=relative pg, no=0=absolute pg |
double sirr,ssat,lambda_krw; |
double sirr,ssat,lambda_krw,beta_krw; |
double bb1,phi01; //permeability parameters |
//parameters for the arificial material: |
double kww0,kwg0,kwt0,kgw0,kgg0,kgt0,ktw0,ktg0,ktt0; |
double capww0,capwg0,capwt0,capgw0,capgg0,capgt0,captw0,captg0,captt0; |
double gamma; |
}; |
#endif |
/trunk/SIFEL/TRFEL/SRC/consol_hwf2.cpp |
---|
31,6 → 31,7 |
kintr_type = 0; //intrinsic permability calculation type |
krw_type = 0; //relative permeability calculation type |
sr_type = 1; //retention curve calculation type |
xi_type = 1; //effective stress parameter type |
lambda_type =0; //heat conduction calculation type |
cps_type = 0; //specific heat calculation type |
betas_type = 0; //thermal expansion calculation type |
52,8 → 53,11 |
lambda_wet = 0.0; |
sr_dry = 0.0; |
sr_wet = 0.0; |
sirr = 0.0; |
ssat = 1.0; |
lambda_krw = 1.9; //parameter for exponential function of relative permeability |
beta_krw = 0.0; //parameter for power function of relative permeability |
bb1 = 0.0; |
phi01 = 0.0; |
85,7 → 89,7 |
xfscanf (in,"%d", &compress); |
// common material parameters |
xfscanf (in,"%le %le %le %le %le %le %d %d %d %d %d %d", &alpha0, &ks0, &phi0, &rhos0, &pw_bc, &kintr0, &kintr_type, &krw_type, &sr_type, &lambda_type, &cps_type, &betas_type); |
xfscanf (in,"%le %le %le %le %le %d %d %d %d %d %d %d %d", &alpha0, &ks0, &rhos0, &pw_bc, &kintr0, &por_type, &kintr_type, &krw_type, &sr_type, &xi_type, &lambda_type, &cps_type, &betas_type); |
switch (model_type){ |
case lewis_and_schrefler2hw:{//Lewis and Schrefler's model |
101,6 → 105,23 |
} |
} |
//porosity calculation: |
switch (por_type){ |
case 0:{//constant |
xfscanf (in,"%le",&phi0); |
break; |
} |
case 1:{//dependent on mefel calculation |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
} |
} |
//intrinsic permebility calculation: |
switch (kintr_type){ |
case 0:{//constant |
110,6 → 131,10 |
xfscanf (in,"%le %le", &bb1, &phi01); |
break; |
} |
case 2:{//dependent on porosity - cubic and quadratic |
xfscanf (in,"%le", &phi01); |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
130,6 → 155,14 |
xfscanf (in,"%le", &lambda_krw); |
break; |
} |
case 4:{//liakopoulos |
break; |
} |
case 5:{//double exponential |
xfscanf (in,"%le %le", &sirr, &ssat); |
xfscanf (in,"%le", &beta_krw); |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
158,6 → 191,10 |
data.read (in); |
break; |
} |
case masin_sr:{//extended formulation from Brooks and Correy according to Masin |
masin_ret.read(in); |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
333,7 → 370,49 |
} |
/** |
function computes effective stress factor xi |
@param pw - water pressure |
@param t - temperature |
@retval xi - factor xi |
03/04/2023, TKr |
*/ |
double con_hwf2mat::get_xi(double pw, double t, long ipp) |
{ |
double xi=0.0; |
switch (xi_type){ |
case biot_xi: |
xi = get_sw(pw,t,ipp); |
break; |
case masin_xi:{ |
double e=0.0,dpw=0.0,por=0.0; |
if(Tm->nontransq != NULL){ |
por = Tm->givenontransq(porosity, ipp);// from mefel |
e = por/(1-por); |
} |
else{ |
e = phi0/(1-phi0); |
} |
dpw = Tm->ip[ipp].av[0]-Tm->ip[ipp].pv[0]; |
xi = masin_ret.psi(-pw,-dpw,e,t);//positive value of suction |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
} |
} |
return(xi); |
} |
/** |
function computes degree of saturation(sorption curve) |
@param pw - water pressure |
@param t - temperature |
388,6 → 467,20 |
//sw = van_genuchten_ret.sw2(pw); |
break; |
} |
case masin_sr:{//extended formulation from Brooks and Correy according to Masin |
double e=0.0,dpw=0.0,por=0.0; |
if(Tm->nontransq != NULL){ |
por = Tm->givenontransq(porosity, ipp);// from mefel |
e = por/(1-por); |
} |
else{ |
e = phi0/(1-phi0); |
} |
dpw = Tm->ip[ipp].av[0]-Tm->ip[ipp].pv[0]; |
sw = masin_ret.sw(-pw,-dpw,e,t);//positive value of suction |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
445,6 → 538,20 |
//dsw_dpw = van_genuchten_ret.dsw_dpw2(pw); |
break; |
} |
case masin_sr:{//extended formulation from Brooks and Correy according to Masin |
double e=0.0,dpw=0.0,por=0.0; |
if(Tm->nontransq != NULL){ |
por = Tm->givenontransq(porosity, ipp);// from mefel |
e = por/(1-por); |
} |
else{ |
e = phi0/(1-phi0); |
} |
dpw = Tm->ip[ipp].av[0]-Tm->ip[ipp].pv[0]; |
dsw_dpw = -masin_ret.dsw_dpw(-pw,-dpw,e,t);//positive value of suction |
//dsw_dpw = dsw_dpw/mefel_units; //basic units = Pa |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
502,6 → 609,19 |
//dsw_dt = van_genuchten_ret.dsw_dt2(pw); |
break; |
} |
case masin_sr:{//extended formulation from Brooks and Correy according to Masin |
double e=0.0,dpw=0.0,por=0.0; |
if(Tm->nontransq != NULL){ |
por = Tm->givenontransq(porosity, ipp);// from mefel |
e = por/(1-por); |
} |
else{ |
e = phi0/(1-phi0); |
} |
dpw = Tm->ip[ipp].av[0]-Tm->ip[ipp].pv[0]; |
dsw_dt = masin_ret.dsw_dt(-pw,-dpw,e,t);//positive value of suction |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
535,6 → 655,11 |
kintr = kintr0*exp(bb1*(phi - phi01)); |
break; |
} |
case 2:{//dependent on porosity - cubic and quadratic |
phi = give_porosity(ipp); |
kintr = kintr0*phi*phi*phi/(1 - phi01)*(1 - phi01)*(1 - phi)*(1 - phi)/(phi01*phi01*phi01); |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
555,7 → 680,7 |
*/ |
double con_hwf2mat::get_krw(double pw, double t, long ipp) |
{ |
double sw,krw; |
double sw,krw,sef=0.0; |
switch (krw_type){ |
case 0:{//constant |
582,6 → 707,15 |
krw = 1.0-2.207*pow((1.0-sw),1.0121); |
break; |
} |
case 5:{//double exponential |
sw = get_sw(pw,t,ipp); |
sef = (sw-sirr)/(ssat-sirr); //effective saturation degree |
krw = pow(sef,(1.0/beta_krw)); |
krw = pow((1.0-krw),beta_krw); |
krw = pow((1.0-krw),2.0); |
krw = pow(sef,0.5)*krw; |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
592,7 → 726,42 |
} |
/** |
function returns porosity |
@retval phi - porosity |
03/04/2023, TKr |
*/ |
double con_hwf2mat::give_porosity(long ipp) |
{ |
double por; |
//porosity calculation: |
switch (por_type){ |
case 0:{//constant |
por = phi0; |
break; |
} |
case 1:{//dependent on mefel calculation |
if(Tm->nontransq != NULL){ |
por = Tm->givenontransq(porosity, ipp);// from mefel |
} |
else |
por = phi0;//for testing |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
} |
} |
return(por); |
} |
/** |
function computes Biot's constant |
@param pw - pore water pressure |
805,6 → 974,7 |
break; |
} |
case 3:{// |
sw = get_sw(pw,t,ipp); |
lambdaeff = pow(lambda_wet,sw)*pow(lambda_dry,(1-sw)); //this is from Patek's thesis p. 18, but it seems to be strange |
break; |
} |
1773,25 → 1943,78 |
fwu = 0.0; |
switch (model_type){ |
case lewis_and_schrefler2hw:{ |
case lewis_and_schrefler:{ |
break; |
} |
case lewis_and_schrefler2hw_mefel:{//Lewis and Schrefler's book |
case lewis_and_schrefler_mefel:{//Lewis and Schrefler's book |
if(vol_strain_effect == 1){ |
n = get_porosity(pw,t,ipp); |
n = give_porosity(ipp); |
depsv_r = Tm->givenontransq(strain_vol_rate, ipp); //actual rate of volumetric strain from MEFEL |
Tm->ip[ipp].eqother[0] = depsv_r; //this is not necessary |
if (sr_type == mefel_sr){ |
/* |
if (sr_type == mefel_sr){ |
dsr_depsv = Tm->givenontransq(der_saturation_deg_depsv, ipp); //actual derivative of saturation degree with respect to volumetric strain |
Tm->ip[ipp].eqother[1] = dsr_depsv; //this is not necessary |
} |
*/ |
switch (sr_type){ |
case lewis_and_schrefler_sr:{//Lewis and Schrefler's book |
dsr_depsv = 0.0; |
break; |
} |
case gardner_exponential_sr:{//dependent on saturation degree: |
dsr_depsv = 0.0; |
break; |
} |
case potts_log_linear_sr:{//exponential |
dsr_depsv = 0.0; |
break; |
} |
case van_genuchten_sr:{//partially saturated medium =Van Genuchten model |
dsr_depsv = 0.0; |
break; |
} |
case van_genuchten2_sr:{//partially saturated medium =Van Genuchten model |
dsr_depsv = 0.0; |
break; |
} |
case mefel_sr:{//from MEFEL |
dsr_depsv = Tm->givenontransq(der_saturation_deg_depsv, ipp); //actual derivative of saturation degree with respect to volumetric strain |
break; |
} |
case table_sr:{//from table |
dsr_depsv = 0.0; |
break; |
} |
case masin_sr:{//extended formulation from Brooks and Correy according to Masin |
double e=0.0,dpw=0.0,por=0.0; |
if(Tm->nontransq != NULL){ |
por = Tm->givenontransq(porosity, ipp);// from mefel |
e = por/(1-por); |
} |
else{ |
e = phi0/(1-phi0); |
} |
dpw = Tm->ip[ipp].av[0]-Tm->ip[ipp].pv[0]; |
dsr_depsv = masin_ret.dsw_depsv(-pw,-dpw,e,t);//positive value of suction |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
} |
} |
Tm->ip[ipp].eqother[1] = dsr_depsv; //this is not necessary |
sw = get_sw(pw,t,ipp); |
rhow = get_rhow(t); |
alpha = get_alpha(pw,t,ipp); |
fwu = -alpha*sw*rhow*depsv_r;//volumetric strain effect |
if (sr_type == mefel_sr){ |
fwu = fwu - n*rhow*dsr_depsv*depsv_r;//volumetric strain effect on retention curve |
} |
fwu = fwu - n*rhow*dsr_depsv*depsv_r;//volumetric strain effect on retention curve |
} |
break; |
} |
2253,6 → 2476,61 |
/** |
function returns effective pore pressure (pressure has negative sign - mechanical convention) |
@param ipp - integration point number |
@retval pw - pore water pressure |
*/ |
double con_hwf2mat::give_effective_pore_pressure(long ipp) |
{ |
double pw,t,xi=1.0; |
switch (model_type){ |
case lewis_and_schrefler:{//Lewis and Schrefler's book |
pw = Tm->ip[ipp].av[0]; |
t = Tm->ip[ipp].av[1]; |
xi = get_xi(pw,t,ipp); |
pw = -xi*pw;//returns effective pore pressure |
break; |
} |
case lewis_and_schrefler_mefel:{//Lewis and Schrefler's book, saturation degree ind its derivative are obtained from mefel; |
//debug??!! |
/* double chi,sw,gama,lambdap,se; |
pw = Tm->ip[ipp].av[0]; |
sw = get_sw(pw,ipp); |
//lambdap = 0.2; |
gama = 0.55; |
se = -2700.0e3; |
//chi = pow(sw,(gama/lambdap)); |
if(pw > se) |
chi = 1.0; |
else |
chi = pow((se/pw),gama); |
sw = (1-gama)*chi; |
pw = -sw*pw/mefel_units;//returns effective pore pressure //corrected units for mefel //basic units = Pa |
*/ |
pw = Tm->ip[ipp].av[0]; |
t = Tm->ip[ipp].av[1]; |
xi = get_xi(pw,t,ipp); //effective stress factor |
pw = -xi*pw/mefel_units;//returns effective pore pressure //corrected units for mefel //basic units = Pa |
//debug???!!! |
//pw = -pw/mefel_units;//returns effective pore pressure //corrected units for mefel //basic units = Pa |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
} |
} |
return(pw); |
} |
/** |
function returns water pressure |
@param ipp - integration point number |
2459,19 → 2737,20 |
break; |
} |
case lewis_and_schrefler2hw_mefel:{//Lewis and Schrefler's book, saturation degree ind its derivative are obtained from mefel; |
antq[saturation_deg-1] = 1; |
antq[der_saturation_deg-1] = 1; |
antq[der_saturation_deg_depsv-1] = 1; |
antq[porosity-1] = 1; |
antq[der_saturation_deg_dtemp-1] = 1; |
antq[strain_vol_rate-1] = 1; |
if (sr_type == mefel_sr){ |
antq[saturation_deg-1] = 1; |
antq[der_saturation_deg-1] = 1; |
antq[der_saturation_deg_depsv-1] = 1; |
antq[der_saturation_deg_dtemp-1] = 1; |
} |
if(vol_strain_effect == 1) |
antq[strain_vol_rate-1] = 1; |
break; |
} |
case van_genuchten2hw:{//partially saturated medium = Van Genuchten model |
break; |
} |
default:{ |
print_err("unknown model type is required", __FILE__, __LINE__, __func__); |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
} |
} |
} |
/trunk/SIFEL/TRFEL/SRC/consol_hwf2.h |
---|
7,6 → 7,7 |
#include "gardner.h" |
#include "potts.h" |
#include "van_genuchten.h" |
#include "masin_reten.h" |
class con_hwf2mat |
{ |
19,11 → 20,13 |
double get_betas(long ipp); |
double get_cps(double pw, double t, long ipp); |
double get_rhos(double t); |
double get_xi(double pw, double t, long ipp); |
double get_sw(double pw, double t, long ipp); |
double get_dsw_dpw(double pw, double t, long ipp); |
double get_dsw_dt(double pw, double t, long ipp); |
double get_kintr(double pw, double t, long ipp); |
double get_krw(double pw, double t, long ipp); |
double give_porosity(long ipp); |
double get_alpha(double pw, double t,long ipp); |
double get_porosity(double pw,double t,long ipp); |
103,6 → 106,7 |
double give_temperature(long ipp); |
double give_water_pressure(long ipp); |
double give_effective_pore_pressure(long ipp); |
double give_pore_pressure(long ipp); |
double give_suction(long ipp); |
double give_saturation_degree(long ipp); |
120,7 → 124,8 |
potts_reten potts_ret; |
/// van Genuchten's retention curve: |
van_genuchten_reten van_genuchten_ret; |
/// Masin's retention curve for bentonite |
masin_reten masin_ret; |
/// general function for retention curve given by set of data |
gfunct data; |
128,7 → 133,7 |
heatwaterflowtype model_type; |
int compress; |
int vol_strain_effect,kintr_type,krw_type,sr_type,lambda_type,cps_type,betas_type; |
int vol_strain_effect,por_type,kintr_type,krw_type,sr_type,xi_type,lambda_type,cps_type,betas_type; |
double alpha0; //initial Boit's constant |
double ks0; //inital bulk modulus of solid phase |
152,7 → 157,7 |
double pw_bc; |
double mefel_units; //basic units for pressures = Pa (Pascals) |
double sirr,ssat,lambda_krw; |
double sirr,ssat,lambda_krw,beta_krw; |
double bb1,phi01; //permeability parameters |
}; |
/trunk/SIFEL/TRFEL/SRC/consol_wf1.cpp |
---|
22,6 → 22,7 |
krw_type = 0; //relative permeability calculation type |
kintr_type = 0; //intrinsic permability calculation type |
sr_type = 1; //retention curve calculation type |
xi_type = 1; //effective stress parameter type |
mefel_units = 1.0; //basic units for pressures = Pa (Pascals) in MEFEL part |
vol_strain_effect = 0; //volumetric strain rate influence: 0=no; 1=yes |
40,9 → 41,14 |
sirr = 0.0; //lower saturation degree |
ssat = 1.0; //fully saturation degree |
lambda_krw = 1.9; //parameter for exponential function of relative permeability |
beta_krw = 0.0; //parameter for power function of relative permeability |
b1 = 9.91; //material parameter of the intrinsic permeability |
phi01 = 0.047; //reference porosity associated with kintr0 |
gamma = 0.0; |
lambda0 = 0.0; |
s_entry = 0.0; |
} |
con_wf1mat::~con_wf1mat() |
166,6 → 172,11 |
pw = Tm->ip[ipp].av[0]; |
cc = get_capww(pw,ipp); |
//fprintf (Outt,"cc = %lf pw = %e ipp = %ld\n",cc,pw,ipp); |
//fflush(Outt); |
check_math_errel(Tm->elip[ipp]); |
} |
/** |
181,7 → 192,7 |
xfscanf (in,"%k%m","waterflowtype",&waterflowtype_kwdset, &model_type); //water flow model type |
xfscanf (in,"%d", &compress); //compressibility of grains |
// common material parameters |
xfscanf (in,"%le %le %le %le %le %d %d %d %d", &alpha, &ks, &rhos0, &pw_bc, &kintr0, &por_type, &kintr_type, &krw_type, &sr_type); |
xfscanf (in,"%le %le %le %le %le %d %d %d %d %d", &alpha, &ks, &rhos0, &pw_bc, &kintr0, &por_type, &kintr_type, &krw_type, &sr_type, &xi_type); |
switch (model_type){ |
case lewis_and_schrefler:{//Lewis and Schrefler's model approach |
222,6 → 233,10 |
xfscanf (in,"%le %le", &b1, &phi01); |
break; |
} |
case 2:{//dependent on porosity - cubic and quadratic |
xfscanf (in,"%le", &phi01); |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
245,6 → 260,11 |
case 4:{//liakopoulos |
break; |
} |
case 5:{//double exponential |
xfscanf (in,"%le %le", &sirr, &ssat); |
xfscanf (in,"%le", &beta_krw); |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
281,6 → 301,10 |
data.read (in); |
break; |
} |
case masin_sr:{//extended formulation from Brooks and Correy according to Masin |
masin_ret.read(in); |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
287,6 → 311,26 |
} |
} |
switch (xi_type){ |
case biot_xi: |
break; |
case biot_reduced_xi:{//coefficient for effective stress factor reduction |
xfscanf (in,"%le %le", &gamma,&lambda0); |
break; |
} |
case biot_masin_xi:{ |
xfscanf (in,"%le %le", &gamma,&s_entry); |
break; |
} |
case masin_xi: |
break; |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
} |
} |
} |
471,6 → 515,66 |
/** |
function computes effective stress factor xi |
@param pw - water pressure |
@retval xi - factor xi |
15/03/2023, TKr |
*/ |
double con_wf1mat::get_xi(double pw, long ipp) |
{ |
double suc=0.0,sr=0.0,xi=0.0,temp=294.0; |
switch (xi_type){ |
case biot_xi: |
xi = get_sw(pw,ipp); |
break; |
case biot_reduced_xi: |
//xi = gamma*get_sw(pw,ipp); |
sr = get_sw(pw,ipp); |
//xi = pow(sr,(gamma/lambda0)); |
xi = pow(sr,gamma); |
xi = (1-gamma)*xi; |
break; |
case biot_masin_xi:{//according to masin for testing |
sr = get_sw(pw,ipp); |
suc = -pw; |
if (suc>=s_entry) |
xi = pow((s_entry/suc),gamma); |
else |
xi = 1.0; |
if (suc>=s_entry) |
xi = (1-gamma)*xi; |
else |
xi = 1.0; |
break; |
} |
case masin_xi:{ |
double e=0.0,dpw=0.0,por=0.0; |
if(Tm->nontransq != NULL){ |
por = Tm->givenontransq(porosity, ipp);// from mefel |
e = por/(1-por); |
} |
else{ |
e = phi0/(1-phi0); |
} |
dpw = Tm->ip[ipp].av[0]-Tm->ip[ipp].pv[0]; |
xi = masin_ret.psi(-pw,-dpw,e,temp);//positive value of suction |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
} |
} |
return(xi); |
} |
/** |
function computes degree of saturation(sorption curve) |
@param pw - water pressure |
480,7 → 584,7 |
*/ |
double con_wf1mat::get_sw(double pw, long ipp) |
{ |
double sw; |
double sw,temp=294.0; |
sw = 0.0; |
switch (sr_type){ |
524,6 → 628,20 |
//sw = van_genuchten_ret.sw2(pw); |
break; |
} |
case masin_sr:{//extended formulation from Brooks and Correy according to Masin |
double e=0.0,dpw=0.0,por=0.0; |
if(Tm->nontransq != NULL){ |
por = Tm->givenontransq(porosity, ipp);// from mefel |
e = por/(1-por); |
} |
else{ |
e = phi0/(1-phi0); |
} |
dpw = Tm->ip[ipp].av[0]-Tm->ip[ipp].pv[0]; |
sw = masin_ret.sw(-pw,-dpw,e,temp);//positive value of suction |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
543,7 → 661,7 |
*/ |
double con_wf1mat::get_dsw_dpw(double pw, long ipp) |
{ |
double dsw_dpw; |
double dsw_dpw,temp=294.0; |
dsw_dpw = 0.0; |
switch (sr_type){ |
578,11 → 696,28 |
//dsw_dpw = van_genuchten_ret.dsw_dpw2(pw); |
break; |
} |
case masin_sr:{//extended formulation from Brooks and Correy according to Masin |
double e=0.0,dpw=0.0,por=0.0; |
if(Tm->nontransq != NULL){ |
por = Tm->givenontransq(porosity, ipp);// from mefel |
e = por/(1-por); |
} |
else{ |
e = phi0/(1-phi0); |
} |
dpw = Tm->ip[ipp].av[0]-Tm->ip[ipp].pv[0]; |
dsw_dpw = -masin_ret.dsw_dpw(-pw,-dpw,e,temp);//positive value of suction |
//dsw_dpw = dsw_dpw/mefel_units; //basic units = Pa |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
} |
} |
check_math_errel(Tm->elip[ipp]); |
return(dsw_dpw); |
} |
597,7 → 732,7 |
*/ |
double con_wf1mat::get_krw(double pw, long ipp) |
{ |
double sw,krw; |
double sw,krw,sef=0.0; |
switch (krw_type){ |
case 0:{//constant |
617,6 → 752,8 |
case 3:{//exponential |
sw = get_sw(pw,ipp); |
krw = pow(sw,lambda_krw); |
//sef = (sw-sirr)/(ssat-sirr); //effective saturaion degree |
//krw = pow(sef,lambda_krw); |
break; |
} |
case 4:{//liakopoulos |
624,6 → 761,15 |
krw = 1.0-2.207*pow((1.0-sw),1.0121); |
break; |
} |
case 5:{//double exponential |
sw = get_sw(pw,ipp); |
sef = (sw-sirr)/(ssat-sirr); //effective saturation degree |
krw = pow(sef,(1.0/beta_krw)); |
krw = pow((1.0-krw),beta_krw); |
krw = pow((1.0-krw),2.0); |
krw = pow(sef,0.5)*krw; |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
689,6 → 835,11 |
kintr = kintr0*exp(b1*(phi - phi01)); |
break; |
} |
case 2:{//dependent on porosity - cubic and quadratic |
phi = give_porosity(ipp); |
kintr = kintr0*phi*phi*phi/(1 - phi01)*(1 - phi01)*(1 - phi)*(1 - phi)/(phi01*phi01*phi01); |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
813,7 → 964,7 |
*/ |
double con_wf1mat::get_fwu(double pw, long ipp) |
{ |
double sw,fwu,depsv_r, dsr_depsv,n; |
double sw,fwu,depsv_r=0.0,dsr_depsv=0.0,n,temp=294.0; |
fwu = 0.0; |
826,16 → 977,70 |
n = give_porosity(ipp); |
depsv_r = Tm->givenontransq(strain_vol_rate, ipp); //actual rate of volumetric strain from MEFEL |
Tm->ip[ipp].eqother[0] = depsv_r; //this is not necessary |
if (sr_type == mefel_sr){ |
/* |
if (sr_type == mefel_sr){ |
dsr_depsv = Tm->givenontransq(der_saturation_deg_depsv, ipp); //actual derivative of saturation degree with respect to volumetric strain |
Tm->ip[ipp].eqother[1] = dsr_depsv; //this is not necessary |
} |
*/ |
switch (sr_type){ |
case lewis_and_schrefler_sr:{//Lewis and Schrefler's book |
dsr_depsv = 0.0; |
break; |
} |
case gardner_exponential_sr:{//dependent on saturation degree: |
dsr_depsv = 0.0; |
break; |
} |
case potts_log_linear_sr:{//exponential |
dsr_depsv = 0.0; |
break; |
} |
case van_genuchten_sr:{//partially saturated medium =Van Genuchten model |
dsr_depsv = 0.0; |
break; |
} |
case van_genuchten2_sr:{//partially saturated medium =Van Genuchten model |
dsr_depsv = 0.0; |
break; |
} |
case mefel_sr:{//from MEFEL |
dsr_depsv = Tm->givenontransq(der_saturation_deg_depsv, ipp); //actual derivative of saturation degree with respect to volumetric strain |
break; |
} |
case table_sr:{//from table |
dsr_depsv = 0.0; |
break; |
} |
case masin_sr:{//extended formulation from Brooks and Correy according to Masin |
double e=0.0,dpw=0.0,por=0.0; |
if(Tm->nontransq != NULL){ |
por = Tm->givenontransq(porosity, ipp);// from mefel |
e = por/(1-por); |
} |
else{ |
e = phi0/(1-phi0); |
} |
dpw = Tm->ip[ipp].av[0]-Tm->ip[ipp].pv[0]; |
dsr_depsv = masin_ret.dsw_depsv(-pw,-dpw,e,temp);//positive value of suction |
break; |
} |
default:{ |
print_err ("unknown model type is required", __FILE__, __LINE__, __func__); |
abort(); |
} |
} |
Tm->ip[ipp].eqother[1] = dsr_depsv; //this is not necessary |
sw = get_sw(pw,ipp); |
fwu = -alpha*sw*depsv_r;//volumetric strain effect |
if (sr_type == mefel_sr){ |
fwu = fwu -n*dsr_depsv*depsv_r;//volumetric strain effect on retention curve |
} |
//if (sr_type == mefel_sr){ |
fwu = fwu - n*dsr_depsv*depsv_r;//volumetric strain effect on retention curve |
//} |
} |
break; |
} |
1310,19 → 1515,39 |
*/ |
double con_wf1mat::give_effective_pore_pressure(long ipp) |
{ |
double pw,sw=1.0; |
double pw,xi=1.0; |
switch (model_type){ |
case lewis_and_schrefler:{//Lewis and Schrefler's book |
pw = Tm->ip[ipp].av[0]; |
sw = get_sw(pw,ipp); |
pw = -sw*pw;//returns effective pore pressure |
xi = get_xi(pw,ipp); |
pw = -xi*pw;//returns effective pore pressure |
break; |
} |
case lewis_and_schrefler_mefel:{//Lewis and Schrefler's book, saturation degree ind its derivative are obtained from mefel; |
//debug??!! |
/* double chi,sw,gama,lambdap,se; |
pw = Tm->ip[ipp].av[0]; |
sw = get_sw(pw,ipp); |
//lambdap = 0.2; |
gama = 0.55; |
se = -2700.0e3; |
//chi = pow(sw,(gama/lambdap)); |
if(pw > se) |
chi = 1.0; |
else |
chi = pow((se/pw),gama); |
sw = (1-gama)*chi; |
pw = -sw*pw/mefel_units;//returns effective pore pressure //corrected units for mefel //basic units = Pa |
*/ |
pw = Tm->ip[ipp].av[0]; |
sw = get_sw(pw,ipp); |
pw = -sw*pw/mefel_units;//returns effective pore pressure //corrected units for mefel //basic units = Pa |
xi = get_xi(pw,ipp); //effective stress factor |
pw = -xi*pw/mefel_units;//returns effective pore pressure //corrected units for mefel //basic units = Pa |
//debug???!!! |
//pw = -pw/mefel_units;//returns effective pore pressure //corrected units for mefel //basic units = Pa |
break; |
} |
default:{ |
/trunk/SIFEL/TRFEL/SRC/consol_wf1.h |
---|
7,8 → 7,8 |
#include "gardner.h" |
#include "potts.h" |
#include "van_genuchten.h" |
#include "masin_reten.h" |
/** |
This class defines model for water flow in soils. |
*/ |
35,6 → 35,7 |
void rhs2d1 (matrix &d,long ri,long ci,long ipp); |
void rhs3d1 (matrix &d,long ri,long ci,long ipp); |
double get_xi(double pw, long ipp); |
double get_sw(double pw, long ipp); |
double get_dsw_dpw(double pw, long ipp); |
double get_krw(double pw, long ipp); |
91,7 → 92,8 |
potts_reten potts_ret; |
/// van Genuchten's retention curve: |
van_genuchten_reten van_genuchten_ret; |
/// Masin's retention curve for bentonite |
masin_reten masin_ret; |
/// general function for retention curve given by set of data |
gfunct data; |
99,14 → 101,15 |
waterflowtype model_type; |
int compress; |
int vol_strain_effect,por_type,kintr_type,krw_type,sr_type; |
int vol_strain_effect,por_type,kintr_type,krw_type,sr_type,xi_type; |
double mefel_units; //basic units for pressures = Pa (Pascals) |
double alpha,phi0,ks; |
double kw,rhow0,muw0; |
double kintr0,rhos0; |
double sirr,ssat,lambda_krw; |
double sirr,ssat,lambda_krw,beta_krw; |
double b1,phi01; |
double pw_bc; |
double gamma,lambda0,s_entry; |
}; |
#endif |
/trunk/SIFEL/TRFEL/SRC/elementt.cpp |
---|
82,7 → 82,8 |
get=linbar; |
if (Lbt==NULL) |
Lbt = new linbart; |
Tp->gdim=1; |
if (Tp->gdim < 1) |
Tp->gdim=1; |
break; |
} |
case barlint3d:{ |
89,7 → 90,8 |
get=linbar; |
if (Lbt3d==NULL) |
Lbt3d = new linbart3d; |
Tp->gdim=1; |
if (Tp->gdim < 1) |
Tp->gdim=1; |
break; |
} |
case barlintax:{ |
96,7 → 98,8 |
get=linbar; |
if (Lbt==NULL) |
Lbat = new linbartax; |
Tp->gdim=1; |
if (Tp->gdim < 1) |
Tp->gdim=1; |
break; |
} |
case barquadt:{ |
103,7 → 106,8 |
get=quadbar; |
if (Qbt==NULL) |
Qbt = new quadbart; |
Tp->gdim=1; |
if (Tp->gdim < 1) |
Tp->gdim=1; |
break; |
} |
case barquadtax:{ |
110,7 → 114,8 |
get=quadbar; |
if (Qbat==NULL) |
Qbat = new quadbartax; |
Tp->gdim=1; |
if (Tp->gdim < 1) |
Tp->gdim=1; |
break; |
} |
case trlint:{ |
117,7 → 122,8 |
get=lintriag; |
if (Ltt==NULL) |
Ltt = new trlineart; |
Tp->gdim=2; |
if (Tp->gdim < 2) |
Tp->gdim=2; |
break; |
} |
case trlaxisym:{ |
124,7 → 130,8 |
get=lintriag; |
if (Ltat==NULL) |
Ltat = new trlinaxisym; |
Tp->gdim=2; |
if (Tp->gdim < 2) |
Tp->gdim=2; |
break; |
} |
case quadlint:{ |
131,7 → 138,8 |
get=linquad; |
if (Lqt==NULL) |
Lqt = new quadlineart; |
Tp->gdim=2; |
if (Tp->gdim < 2) |
Tp->gdim=2; |
break; |
} |
case quadquadt:{ |
138,7 → 146,8 |
get=quadquad; |
if (Qqt==NULL) |
Qqt = new quadquadrilatt; |
Tp->gdim=2; |
if (Tp->gdim < 2) |
Tp->gdim=2; |
break; |
} |
case quadquadtax:{ |
145,7 → 154,8 |
get=quadquad; |
if (Qqat==NULL) |
Qqat = new quadquadrilattax; |
Tp->gdim=2; |
if (Tp->gdim < 2) |
Tp->gdim=2; |
break; |
} |
case quadlaxisym:{ |
152,7 → 162,8 |
get=linquad; |
if (Lqat==NULL) |
Lqat = new quadlinaxisym; |
Tp->gdim=2; |
if (Tp->gdim < 2) |
Tp->gdim=2; |
break; |
} |
case ifacequadel:{ |
159,7 → 170,8 |
get=linquad; |
if (Ifcquadt==NULL) |
Ifcquadt = new interfacequadrilat; |
Tp->gdim=2; |
if (Tp->gdim < 2) |
Tp->gdim=2; |
break; |
} |
case lineartett:{ |
185,10 → 197,11 |
} |
case gen2del:{ |
get=gen2d; |
if (G2d==NULL) |
G2d = new gen2delem; |
Tp->gdim=2; |
if (Tp->gdim < 2) |
Tp->gdim=2; |
break; |
} |
default:{ |
/trunk/SIFEL/TRFEL/SRC/elemswitcht.cpp |
---|
1088,7 → 1088,7 |
#ifdef INC_OPENMP |
#pragma omp parallel num_threads(4) |
{ |
#pragma omp for nowait |
#pragma omp for |
#endif |
for (long i=0;i<ne;i++){ |
if (Gtt->leso[i]==1){ |
1233,7 → 1233,7 |
#ifdef INC_OPENMP |
#pragma omp parallel num_threads(4) |
{ |
#pragma omp for nowait |
#pragma omp for |
#endif |
// loop over all elements |
for (long i=0; i<ne; i++) |
1264,7 → 1264,7 |
#ifdef INC_OPENMP |
#pragma omp parallel num_threads(4) |
{ |
#pragma omp for nowait |
#pragma omp for |
#endif |
for (long i=0;i<ne;i++){ |
if (Gtt->leso[i]==1){ |
1296,7 → 1296,7 |
#ifdef INC_OPENMP |
#pragma omp parallel num_threads(4) |
{ |
#pragma omp for nowait |
#pragma omp for |
#endif |
for (long i=0;i<ne;i++){ |
if (Gtt->leso[i]==1){ |
2798,6 → 2798,10 |
case ifacequadel: |
Ifcquadt->transq_nodval(eid, nodval, nmq); |
break; |
case lineartett:{ |
Ltett->transq_nodval(eid, nodval, nmq); |
break; |
} |
default:{ |
print_err("unknown element type is required", __FILE__, __LINE__, __func__); |
} |
2842,6 → 2846,10 |
Lqat->transq_init_nodval(eid, nodval, nmq); |
break; |
} |
case lineartett:{ |
Ltett->transq_init_nodval(eid, nodval, nmq); |
break; |
} |
default:{ |
print_err("unknown element type is required", __FILE__, __LINE__, __func__); |
} |
2888,6 → 2896,10 |
Lqat->transq_nodval_comp (eid, nodval, ncne, nq, qt); |
break; |
} |
case lineartett:{ |
Ltett->transq_nodval_comp (eid, nodval, ncne, nq, qt); |
break; |
} |
default:{ |
print_err("unknown element type is required", __FILE__, __LINE__, __func__); |
} |
2934,6 → 2946,10 |
Lqat->transq_init_nodval_comp (eid, nodval, ncne, nq, qt); |
break; |
} |
case lineartett:{ |
Ltett->transq_init_nodval_comp (eid, nodval, ncne, nq, qt); |
break; |
} |
default:{ |
print_err("unknown element type is required", __FILE__, __LINE__, __func__); |
} |
/trunk/SIFEL/TRFEL/SRC/globmatt.cpp |
---|
1782,10 → 1782,13 |
// caused by initial conditions and prescribed values |
assemble_init (rhs); |
//if(Tp->time >= 5.342000e+04){ |
//for (long ijk=0;ijk<n;ijk++){ |
//fprintf (Outt,"\n assemble init %ld %le",ijk,rhs[ijk]); |
// fprintf (Outt,"\n assemble init %ld %le",ijk,rhs[ijk]); |
//} |
//fflush(Outt); |
//} |
//contribution of gradients for homogenization |
if(Tp->homogt == 1){ |
nullv (av,n); |
/trunk/SIFEL/TRFEL/SRC/isotrmat.cpp |
---|
205,6 → 205,10 |
new_trc=1.0; |
break; |
} |
case 51:{//heat transmission - boundary condition computed from the actual boundary flux |
new_trc=1.0; |
break; |
} |
case 90:{//radiation |
new_trc=1.0; |
break; |
256,6 → 260,14 |
new_trc=1.0; |
break; |
} |
case 51:{//heat transmission => heat flux - this boundary condition is created provisionally for salt diffusion problem |
// the flux of salt ions is calculated for inflow flux from external and interal values of concentration |
if(flag == 1)//for rhs vector |
new_trc=1.0; |
else |
new_trc=0.0;//for matrix |
break; |
} |
case 90:{//radiation |
if(flag == 1)//for rhs vector |
new_trc=1.0; |
291,7 → 303,10 |
{ |
long k; |
double dt=0.0,new_nodval=0.0,t; |
//provisionally for salt diffusion: |
double por,rhoc,rhow,ecl,c0,kcl; |
k=Gtt->give_dof(nn,0); |
if (k>0) {t = Lsrst->lhs[k-1]+Lsrst->lhsi[k-1];} |
if (k==0) {t = 0.0;} |
319,6 → 334,20 |
new_nodval=Tm->ip[ipp].av[0] + Tb->fluxes[0]*nodval*dt;//cumulated value from the first integration point of the element |
break; |
} |
case 51:{//heat transmission => heat flux - this boundary condition is created provisionally for salt diffusion problem |
// the flux of salt ions is calculated for inflow flux from external and interal values of concentration |
por = 0.122; |
rhoc = 2233.0; |
rhow = 998; |
//ecl = 1.16e-12; |
ecl = 1.0e-7; |
c0 = 0.51; |
//kcl = 1.74e-12; |
kcl = 1.5e-7; |
new_nodval = -0.035453*(ecl*(1/por*rhoc/rhow*Tm->ip[ipp].av[0] - nodval)+kcl*(1/por*rhoc/rhow*Tm->ip[ipp].av[0]/c0)* |
(1/por*rhoc/rhow*Tm->ip[ipp].av[0]/c0)*exp(-1.15/por*rhoc/rhow*Tm->ip[ipp].av[0])); |
break; |
} |
case 90:{//radiation |
//new_nodval = (nodval - t) + trc2*(nodval*nodval*nodval*nodval - t*t*t*t);//inverse eq. (trc2 = e_sigma0/trc) |
new_nodval = trc2*(nodval*nodval*nodval*nodval - t*t*t*t);//inverse eq. (trc2 = e_sigma0/trc) |
351,7 → 380,9 |
{ |
long k; |
double dt=0.0,flux=0.0,t; |
//provisionally for salt diffusion: |
double por,rhoc,rhow,ecl,c0,kcl; |
k=Gtt->give_dof(nn,0); |
if (k>0) {t = Lsrst->lhs[k-1]+Lsrst->lhsi[k-1];} |
if (k==0) {t = 0.0;} |
371,6 → 402,20 |
flux = (Tm->ip[ipp].av[0] + Tb->fluxes[0]*nodval*dt - t);//cumulated value from the first integration point of the element |
break; |
} |
case 51:{//heat transmission => heat flux - this boundary condition is created provisionally for salt diffusion problem |
// the flux of salt ions is calculated for inflow flux from external and interal values of concentration |
por = 0.122; |
rhoc = 2233.0; |
rhow = 998; |
//ecl = 1.16e-12; |
ecl = 1.0e-7; |
c0 = 0.51; |
//kcl = 1.74e-12; |
kcl = 1.5e-7; |
flux = -0.035453*(ecl*(1/por*rhoc/rhow*Tm->ip[ipp].av[0] - nodval)+kcl*(1/por*rhoc/rhow*Tm->ip[ipp].av[0]/c0)* |
(1/por*rhoc/rhow*Tm->ip[ipp].av[0]/c0)*exp(-1.15/por*rhoc/rhow*Tm->ip[ipp].av[0])); |
break; |
} |
case 90:{//radiation |
//flux = (nodval - t) + trc2*(nodval*nodval*nodval*nodval - t*t*t*t);//inverse eq. (trc2 = e_sigma0/trc) |
flux = trc2*(nodval*nodval*nodval*nodval - t*t*t*t);//inverse eq. (trc2 = e_sigma0/trc) |
/trunk/SIFEL/TRFEL/SRC/lintett.cpp |
---|
2554,3 → 2554,223 |
} |
} |
/** |
Function returns transport (non-mechanical) quantities at nodes of element. |
The values of selected quantity is copied from the closest integration points |
to element nodes. |
@param eid - element id |
@param nodval - %vector of nodal values |
@param ntq - type of non-mechanical quantity |
@return The function does not return anything. |
Created by TKo, 3.2.2014 |
*/ |
void lintett::transq_nodval (long eid,vector &nodval,nonmechquant nmq) |
{ |
long i,ipid; |
ivector ipnum(ASTCKIVEC(nne)); |
// numbers of integration points closest to nodes |
// (function is from the file GEFEL/ordering.cpp) |
ipid=Tt->elements[eid].ipp[0][0]; |
nodip_planelq (ipid,intordkm[0][0], ipnum); |
for (i=0;i<nne;i++) |
{ |
//copy transport (non-mechanical) quantity from closest int. point |
nodval[i] = Tm->givetransq(nmq, ipnum[i]); |
} |
} |
/** |
Function computes transport (non-mechanical) quantities at nodes of element. |
@param eid - element id |
@param nodval - %vector of nodal values of all required quantities, i.e., |
nodal value of i-th quantity in j-th node is given by nodval[i*ncnv+j] where ncnv |
is the number of calculated nodes on eid-th element. |
@param ncne - number of computed nodes on element (only first ncne of nodes is calculated) |
@param nq - number of required transport quantities |
@param qt - array of types of required non-mechanical, i.e. transport quantities |
@return The function does not return anything. |
Modified by TKo, 31.1.2014 |
Created by 26/09/2012 TKr |
*/ |
void lintett::transq_nodval_comp (long eid,vector &nodval, long ncne, long nq, nonmechquant *qt) |
{ |
long i,j,ipid,ncompo; |
ivector ipnum(ASTCKIVEC(nne)), enod(ASTCKIVEC(nne)); |
intpointst ipb; // backup of the first integration point of element |
vector ipav; |
// numbers of integration points closest to nodes |
// (function is from the file GEFEL/ordering.cpp) |
ipid=Tt->elements[eid].ipp[0][0]; |
// element nodes |
Tt->give_elemnodes(eid, enod); |
// numbers of integration points closest to element nodes |
// (function is from the file GEFEL/ordering.cpp) |
nodip_planelq (ipid,intordkm[0][0], ipnum); |
// store original content of the first integration point on element because |
// it becomes working int. point for nodal values calculations on the given element |
ipb.copy(Tm->ip[ipid], ntm, 1); |
// The first integration point will be used for computation of nodal values temporarily |
// then the original content of the first integration point will be restored |
for (i=0;i<ncne;i++) |
{ |
makerefv(ipav, Tm->ip[ipid].av, Tp->ntm); |
// store nodal values to the first (working) integration point |
nodalval (enod[i], ipav); |
// store gradients to the first (working) integration point |
// for(j=0; j<ntm; j++) |
// Tm->ip[ipid].storegrad(j, Tt->nodes[enod[i]].gradient[j]); |
ncompo = Tm->ip[ipnum[i]].ncompeqother; |
if (ncompo){ |
// take eqother values for the given node from the closest integration point |
Tm->storeeqother(ipid, 0, ncompo, Tm->ip[ipnum[i]].eqother); |
} |
ncompo = Tm->ip[ipnum[i]].ncompother; |
if (ncompo){ |
// take eqother values for the given node from the closest integration point |
Tm->storeother(ipid, 0, ncompo, Tm->ip[ipnum[i]].other); |
} |
Tm->mat_aux_values(ipid); |
//give calculated transport quantity from the first int. point |
for (j=0; j<nq; j++) |
nodval[j*ncne+i] = Tm->givetransq(qt[j], ipid); |
} |
// restore original integration point content of other/eqother arrays |
Tm->ip[ipid].copy(ipb, ntm, 0); |
} |
/** |
Function returns initial values of transport (non-mechanical) quantities at nodes of element. |
The values of selected quantity is copied from the closest integration points |
to element nodes. |
@param eid - element id |
@param nodval - %vector of nodal values |
@param ntq - type of non-mechanical quantity |
@return The function does not return anything. |
12/06/2012 TKr |
Modified by TKo, 10.10.2013 |
*/ |
void lintett::transq_init_nodval (long eid,vector &nodval,nonmechquant nmq) |
{ |
long i,ipid; |
ivector ipnum(ASTCKIVEC(nne)), enod(ASTCKIVEC(nne)); |
vector ipav; |
// numbers of integration points closest to nodes |
// (function is from the file GEFEL/ordering.cpp) |
ipid=Tt->elements[eid].ipp[0][0]; |
nodip_planelq (ipid,intordkm[0][0], ipnum); |
// element nodes |
Tt->give_elemnodes(eid, enod); |
for (i=0;i<nne;i++) |
{ |
// create reference vector to the int. point av array |
makerefv(ipav, Tm->ip[ipnum[i]].av, Tp->ntm); |
// store initial nodal values to the integration point |
initnodval2(enod[i], ipav); |
//copy transport (non-mechanical) quantity from closest int. point |
nodval[i] = Tm->givetransq(nmq, ipnum[i]); |
} |
} |
/** |
Function computes initial transport (non-mechanical) quantities at nodes of element. |
@param eid - element id |
@param nodval - %vector of initial nodal values of all required quantities, i.e., |
nodal value of i-th quantity in j-th node is given by nodval[i*ncnv+j] where ncnv |
is the number of calculated nodes on eid-th element. |
@param ncne - number of computed nodes on element (only first ncne of nodes is calculated) |
@param nq - number of required transport quantities |
@param qt - array of types of required non-mechanical, i.e. transport quantities |
@return The function does not return anything. |
Modified by TKo, 31.1.2014 |
Created by 26/09/2012 TKr |
*/ |
void lintett::transq_init_nodval_comp (long eid,vector &nodval, long ncne, long nq, nonmechquant *qt) |
{ |
long i,j,ipid,ncompo; |
ivector ipnum(ASTCKIVEC(nne)), enod(ASTCKIVEC(nne)); |
vector ipav; |
intpointst ipb; // backup of the first integration point of element |
// numbers of integration points closest to nodes |
// (function is from the file GEFEL/ordering.cpp) |
ipid=Tt->elements[eid].ipp[0][0]; |
// element nodes |
Tt->give_elemnodes(eid, enod); |
// numbers of integration points closest to element nodes |
// (function is from the file GEFEL/ordering.cpp) |
nodip_planelq (ipid,intordkm[0][0], ipnum); |
// store original content of the first integration point on element because |
// it becomes working int. point for nodal values calculations on the given element |
ipb.copy(Tm->ip[ipid], ntm, 1); |
// The first integration point will be used for computation of nodal values temporarily |
// then the original content of the first integration point will be restored |
for (i=0;i<ncne;i++) |
{ |
// create reference vector to the int. point av array |
makerefv(ipav, Tm->ip[ipid].av, Tp->ntm); |
// store initial nodal values to the first (working) integration point |
initnodval2 (enod[i], ipav); |
// store gradients to the first (working) integration point |
// for(j=0; j<ntm; j++) |
// Tm->ip[ipid].storegrad(j, Tt->nodes[enod[i]].gradient[j]); |
ncompo = Tm->ip[ipnum[i]].ncompeqother; |
if (ncompo){ |
// take eqother values for the given node from the closest integration point |
Tm->storeeqother(ipid, 0, ncompo, Tm->ip[ipnum[i]].eqother); |
} |
ncompo = Tm->ip[ipnum[i]].ncompother; |
if (ncompo){ |
// take eqother values for the given node from the closest integration point |
Tm->storeother(ipid, 0, ncompo, Tm->ip[ipnum[i]].other); |
} |
Tm->mat_aux_values(ipid); |
//give calculated transport quantity from the first int. point |
for (j=0; j<nq; j++) |
nodval[j*ncne+i] = Tm->givetransq(qt[j], ipid); |
} |
// restore original integration point content of other/eqother arrays |
Tm->ip[ipid].copy(ipb, ntm, 0); |
} |
/trunk/SIFEL/TRFEL/SRC/lintett.h |
---|
69,6 → 69,11 |
long ipcoord (long eid, long ipp, long ri, long ci, vector &coord); |
/// function returns natural coordinates of the given integration point |
long ipncoord (long eid, long ipp, vector &ncoord); |
void transq_nodval (long eid,vector &nodval,nonmechquant nmq); |
void transq_nodval_comp (long eid,vector &nodval, long ncne, long nq, nonmechquant *qt); |
void transq_init_nodval (long eid,vector &nodval,nonmechquant nmq); |
void transq_init_nodval_comp (long eid,vector &nodval, long ncne, long nq, nonmechquant *qt); |
/// number of transported matter |
long ntm; |
/trunk/SIFEL/TRFEL/SRC/masin_reten.cpp |
---|
0,0 → 1,354 |
/* |
File: masin_reten.cpp |
Author: Tomas Krejci, 28/02/2023 |
Purpose: retention curve - extended formulation from Brooks and Correy according to Masin |
sources: |
sr_type: 1 Masin, D. (2010), Predicting the dependency of a degree of saturation on void ratio and suction using effective stress principle for unsaturated soils. Int. J. Numer. Anal. Meth. Geomech., 34: 73-90. https://doi.org/10.1002/nag.808 |
sr_type: 2 Masin, D, (2013), Double structure hydromechanical coupling formalism and a model for unsaturated expansive clays, Engineering Geology, 165, 73-88, ISSN 0013-7952, https://doi.org/10.1016/j.enggeo.2013.05.026. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <math.h> |
#include "globalt.h" |
#include "masin_reten.h" |
masin_reten::masin_reten() |
{ |
sr_type = 1; |
se0 = 2700.0; |
e0 = 0.5; |
tref = 294.0; |
lambdap0 = 0.15; |
at = 0.118; |
bt = -0.000154; |
gamma0 = 0.55; |
ae = 1.0; |
} |
masin_reten::~masin_reten() |
{} |
/** |
function reads parameters |
@param in - input file |
TKr 28/02/2023 |
*/ |
void masin_reten::read(XFILE *in) |
{ |
xfscanf (in,"%ld %lf %lf %lf %lf %lf %lf %lf %lf", &sr_type, &se0,&e0,&ae,&lambdap0,&at,&bt,&tref,&gamma0); |
} |
/** |
function reads parameters |
@param in - input file |
TKr 28/02/2023 |
*/ |
void masin_reten::print(FILE *out) |
{ |
fprintf (out,"\n%ld %lf %lf %lf %lf %lf %lf %lf %lf\n", sr_type,se0,e0,ae,lambdap0,at,bt,tref,gamma0); |
} |
/** |
function computes effective stress factor psi |
@param pw - pore water pressure |
@retval sw - saturation degree |
TKr 28/02/2023 |
*/ |
double masin_reten::psi(double suction, double dsuc, double e, double temp) |
{ |
double psi,se,sr,lambdap,chi; |
if(e == 0.0)//intial porosity |
e = e0; |
se = get_se(suction,dsuc,e,temp); |
sr = sw(suction,dsuc,e,temp); |
switch (sr_type){ |
case 0: |
case 1:{ |
if(suction < se) |
psi = 1.0-gamma0; |
else{ |
lambdap = get_lambdap(suction,dsuc,e,temp); |
chi = pow(sr,(gamma0/lambdap)); |
psi = (1-gamma0)*chi; |
} |
break; |
} |
case 2:{ |
if(suction < se) |
psi = 1.0; |
else{ |
psi = sr; |
} |
break; |
} |
default:{ |
print_err("Unknown WRC type is required",__FILE__,__LINE__,__func__); |
} |
} |
check_math_errel(0); |
return(psi); |
} |
/** |
function computes parameter se - suction air-entry value |
@param pw - pore water pressure |
@retval sw - saturation degree |
TKr 28/02/2023 |
*/ |
double masin_reten::get_se(double suction, double dsuc, double e, double temp) |
{ |
double se; |
switch (sr_type){ |
case 0:{ |
se = se0; |
break; |
} |
case 1:{ |
se = se0*e0/e; |
break; |
} |
case 2:{ |
se = se0*e0/e;//drying branch |
if(dsuc >= 0.0) |
se = ae*se;//wetting branch |
break; |
} |
default:{ |
print_err("Unknown WRC type is required",__FILE__,__LINE__,__func__); |
} |
} |
return(se); |
} |
/** |
function computes derivative of parameter se with repsect to e prosity |
@param pw - pore water pressure |
@retval sw - saturation degree |
TKr 28/02/2023 |
*/ |
double masin_reten::get_dse_de(double suction, double dsuc, double e, double temp) |
{ |
double dse_de; |
switch (sr_type){ |
case 0:{ |
dse_de = 0.0; |
break; |
} |
case 1:{ |
dse_de = -se0*e0/e/e; |
break; |
} |
case 2:{ |
dse_de = -se0*e0/e/e;//drying branch |
if(dsuc >= 0.0) |
dse_de = ae;//wetting branch |
break; |
} |
default:{ |
print_err("Unknown WRC type is required",__FILE__,__LINE__,__func__); |
} |
} |
return(dse_de); |
} |
/** |
function computes parameter lambdap |
@param pw - pore water pressure |
@retval sw - saturation degree |
TKr 28/02/2023 |
*/ |
double masin_reten::get_lambdap(double suction, double dsuc, double e, double temp) |
{ |
double lambdap,chi0; |
chi0 = pow((se0/suction),gamma0); |
lambdap = gamma0/log(chi0)*log((pow(chi0,(lambdap0/gamma0)) - chi0)*pow((e/e0),(gamma0-1)) + chi0); |
return(lambdap); |
} |
/** |
function computes saturation degree |
@param pw - pore water pressure |
@retval sw - saturation degree |
TKr 28/02/2023 |
*/ |
double masin_reten::sw(double suction, double dsuc, double e, double temp) |
{ |
double sr,se,gamma,lambdap; |
if(e == 0.0)//intial porosity |
e = e0; |
se = get_se(suction,dsuc,e,temp); |
if(suction < se) |
sr = 1.0; |
else{ |
switch (sr_type){ |
case 0: |
case 1:{ |
lambdap = get_lambdap(suction,dsuc,e,temp); |
gamma = lambdap; |
break; |
} |
case 2:{ |
gamma = gamma0; |
break; |
} |
default:{ |
print_err("Unknown WRC type is required",__FILE__,__LINE__,__func__); |
} |
} |
sr = pow((se/suction),gamma); |
} |
check_math_errel(0); |
return(sr); |
} |
/** |
function computes partial derivative of degree of saturation with respect to pw, specific water content |
@param pw - water pressure |
@retval dsw_dpw - partial derivative of degree of saturation with respect to pw |
TKr 28/02/2023 |
*/ |
double masin_reten::dsw_dpw(double suction, double dsuc, double e, double temp) |
{ |
double dsr_ds,se,lambdap,gamma; |
if(e == 0.0)//intial porosity |
e = e0; |
se = get_se(suction,dsuc,e,temp); |
if(suction < se) |
dsr_ds = 0.0; |
else{ |
switch (sr_type){ |
case 0: |
case 1:{ |
lambdap = get_lambdap(suction,dsuc,e,temp); |
gamma = lambdap; |
break; |
} |
case 2:{ |
gamma = gamma0; |
break; |
} |
default:{ |
print_err("Unknown WRC type is required",__FILE__,__LINE__,__func__); |
} |
} |
dsr_ds = pow((se/suction),gamma-1)*(-se)/(suction*suction);//not completed??!!, derivative of lambdap must be added |
} |
check_math_errel(0); |
return(dsr_ds); |
} |
/** |
function computes partial derivative of degree of saturation with respect to t |
@param pw - water pressure |
@retval dsw_dt - partial derivative of degree of saturation with respect to t |
TKr 28/02/2023 |
*/ |
double masin_reten::dsw_dt(double suction, double dsuc, double e, double temp) |
{ |
double dsr_dt; |
dsr_dt = 0.0;//p. 167 |
return(dsr_dt); |
} |
/** |
function computes partial derivative of degree of saturation with respect to epsv, volumetric strain |
@param pw - water pressure |
@retval dsw_depsv - partial derivative of degree of saturation with respect to pw |
TKr 28/02/2023 |
*/ |
double masin_reten::dsw_depsv(double suction, double dsuc, double e, double temp) |
{ |
double dsr_depsv,dsr_de,dsr_dse,se,dse_de,lambdap,gamma; |
se = get_se(suction,dsuc,e,temp); |
if(suction < se) |
dsr_depsv = 0.0; |
else{ |
if(e == 0.0)//intial porosity |
e = e0; |
dse_de = get_dse_de(suction,dsuc,e,temp); |
switch (sr_type){ |
case 0: |
case 1:{ |
lambdap = get_lambdap(suction,dsuc,e,temp); |
gamma = lambdap; |
break; |
} |
case 2:{ |
gamma = gamma0; |
break; |
} |
default:{ |
print_err("Unknown WRC type is required",__FILE__,__LINE__,__func__); |
} |
} |
dsr_dse = gamma*pow((se/suction),(gamma-1))/suction; |
dsr_de = dsr_dse*dse_de; |
dsr_depsv = dsr_de*(1+e0);//not completed??!!, derivative of lambdap must be added |
} |
check_math_errel(0); |
return(dsr_depsv); |
} |
/trunk/SIFEL/TRFEL/SRC/masin_reten.h |
---|
0,0 → 1,35 |
#ifndef MASIN_RETEN_H |
#define MASIN_RETEN_H |
#include "genfile.h" |
/** |
This class defines retention curve of Masin and Schrefler's model |
*/ |
class masin_reten |
{ |
public: |
masin_reten(); //constructor |
~masin_reten(); //destructor |
void read(XFILE *in); |
void print(FILE *out); |
double psi(double suction, double dsuc, double e, double temp); |
double get_lambdap(double suction, double dsuc, double e, double temp); |
double get_se(double suction, double dsuc, double e, double temp); |
double get_dse_de(double suction, double dsuc, double e, double temp); |
double sw(double suction, double dsuc, double e, double temp); |
double dsw_dpw(double suction, double dsuc, double e, double temp); |
double dsw_dt(double suction, double dsuc, double e, double temp); |
double dsw_depsv(double suction, double dsuc, double e, double temp); |
private: |
long sr_type; /// type of retention curve and effective stress factor |
double se0; /// the air entry value of suction for the reference macrostructural void ratio e0 |
double e0; /// reference void ratio |
double ae,lambdap0,at,bt,tref,gamma0; ///parameters |
}; |
#endif |
/trunk/SIFEL/TRFEL/SRC/nnpsolvert.cpp |
---|
1769,7 → 1769,7 |
else |
stop=0; // norm is not in the given tolerance |
if (Mesprt==1) fprintf (stdout,"\n norm of residuum %e, required error %e",norf,err[0]); |
if (Mesprt==1) fprintf (stdout,"\n norm of residuum %.15e, required error %e",norf,err[0]); |
} |
if (sc==1){ |
1786,7 → 1786,7 |
else |
stop=0; // norm is not in the given tolerance |
norfb /= norrhs; |
if (Mesprt==1) fprintf (stdout,"\n norm of residuum %e, norm of rhs %e, error %e, required error %e",norf,norrhs,norf/norrhs,err[0]); |
if (Mesprt==1) fprintf (stdout,"\n norm of residuum %.15e, norm of rhs %.15e, error %e, required error %e",norf,norrhs,norf/norrhs,err[0]); |
} |
else{ |
if (norf<err[0]) |
1793,7 → 1793,7 |
stop=1; // norm is in the given tolerance |
else |
stop=0; // norm is not in the given tolerance |
if (Mesprt==1) fprintf (stdout,"\n norm of residuum %e, norm of rhs %e, required error %e",norf,norrhs,err[0]); |
if (Mesprt==1) fprintf (stdout,"\n norm of residuum %.15e, norm of rhs %.15e, required error %e",norf,norrhs,err[0]); |
} |
} |
} |
1830,7 → 1830,7 |
norfb += sqr(norf); |
if (Mesprt==1) fprintf (stdout,"\n phase %ld, norm of residuum %e, required error %e",i+1,norf,err[i]); |
if (Mesprt==1) fprintf (stdout,"\n phase %ld, norm of residuum %.15e, required error %e",i+1,norf,err[i]); |
} |
if (sc==1){ |
1839,13 → 1839,13 |
if (norf/norrhs<err[i]) |
pstop++; |
norfb += sqr(norf)/sqr(norrhs); |
if (Mesprt==1) fprintf (stdout,"\n phase %ld, norm of residuum %e, norm of rhs %e, error %e, required error %e",i+1,norf,norrhs,norf/norrhs,err[i]); |
if (Mesprt==1) fprintf (stdout,"\n phase %ld, norm of residuum %.15e, norm of rhs %.15e, error %e, required error %e",i+1,norf,norrhs,norf/norrhs,err[i]); |
} |
else{ |
if (norf<err[i]) |
pstop++; |
norfb += sqr(norf); |
if (Mesprt==1) fprintf (stdout,"\n phase %ld, norm of residuum %e, norm of rhs %e, required error %e",i+1,norf,norrhs,err[i]); |
if (Mesprt==1) fprintf (stdout,"\n phase %ld, norm of residuum %.15e, norm of rhs %.15e, required error %e",i+1,norf,norrhs,err[i]); |
} |
} |
//fprintf (stdout,"\n phase %ld, pstop %ld",i+1,pstop); |
/trunk/SIFEL/TRFEL/SRC/npsolvert.cpp |
---|
597,12 → 597,14 |
for (j=0;j<n;j++){ |
f[j] = rhs[j] - p[j]; |
} |
//if(Tp->time >= 5.342000e+04){ |
//fprintf(Outt, "\nF vector:\n"); |
//for (j=0;j<n;j++){ |
//fprintf(Outt, "%e\n",f[j]); |
// fprintf(Outt, "%e\n",f[j]); |
//} |
//fflush(Outt); |
//} |
// solution of the system of algebraic equations |
// (C + alpha dt K) v_{n+1} = f_{n+1} - K dd |
609,6 → 611,14 |
// time derivatives v_{n+1} are solved |
Tp->ssle->solve_system (Gtt,Cmat,tdlhs,f,Outt); |
//if(Tp->time >= 5.342000e+04){ |
//fprintf(Outt, "\n tdlhs vector:\n"); |
//for (j=0;j<n;j++){ |
// fprintf(Outt, "%e\n",tdlhs[j]); |
//} |
//fflush(Outt); |
//} |
// nodal values computed from nodal derivatives |
// d_{n+1} = dd + alpha dt v_{n+1} |
for (j=0;j<n;j++){ |
615,6 → 625,14 |
lhs[j] = d[j] + alpha*dt*tdlhs[j]; |
} |
//if(Tp->time >= 5.342000e+04){ |
//fprintf(Outt, "\n lhs vector:\n"); |
//for (j=0;j<n;j++){ |
// fprintf(Outt, "%e\n",lhs[j]); |
//} |
//fflush(Outt); |
//} |
// physically corrected solution |
solution_correction (); |
684,7 → 702,7 |
stop = norm_computation_vec (fb,rhs,err,thresh,2,1,norfb); |
if (stop) break; |
if (Mesprt==1) fprintf (stdout,"\n inner iteration %ld error %e", j, norfb); |
if (Mesprt==1) fprintf (stdout,"\n inner iteration %ld error %.15le", j, norfb); |
Tp->ssle->solve_system (Gtt,Cmat,fi,fb,Outt);//fi is output now |
/trunk/SIFEL/TRFEL/SRC/onemedium.cpp |
---|
502,7 → 502,7 |
switch (Tm->ip[ipp].tm){ |
case isotransmat:{ |
new_trc = Tm->itrm[i].transmission_transcoeff(trc,ri,ci,nn,bc,ipp); |
new_trc = Tm->itrm[i].transmission_transcoeff(trc,ri,ci,nn,bc,ipp,flag); |
break; |
} |
case consolawf1:{ |
/trunk/SIFEL/TRFEL/SRC/threemedia.cpp |
---|
44,6 → 44,7 |
case C60baroghelB: |
case C30baroghelB: |
case o30bazantB: |
case C30bazantB: |
case C60bazantB:{ |
multiph mtph; |
mtph.matcond(d,ri,ci,ipp); |
105,6 → 106,7 |
case C60baroghelB: |
case C30baroghelB: |
case o30bazantB: |
case C30bazantB: |
case C60bazantB:{ |
multiph mtph; |
mtph.matcond2(d,ri,ci,ipp); |
161,6 → 163,7 |
case C60baroghelB: |
case C30baroghelB: |
case o30bazantB: |
case C30bazantB: |
case C60bazantB:{ |
multiph mtph; |
mtph.matcap(c,ri,ci,ipp); |
220,6 → 223,7 |
case C60baroghelB: |
case C30baroghelB: |
case o30bazantB: |
case C30bazantB: |
case C60bazantB:{ |
multiph mtph; |
279,6 → 283,7 |
case C60baroghelB: |
case C30baroghelB: |
case o30bazantB: |
case C30bazantB: |
case C60bazantB:{ |
//multiph mtph; |
323,6 → 328,7 |
case C60baroghelB: |
case C30baroghelB: |
case o30bazantB: |
case C30bazantB: |
case C60bazantB:{ |
multiph mtph; |
388,6 → 394,7 |
case C60baroghelB: |
case C30baroghelB: |
case o30bazantB: |
case C30bazantB: |
case C60bazantB:{ |
multiph mtph; |
452,6 → 459,7 |
case C60baroghelB: |
case C30baroghelB: |
case o30bazantB: |
case C30bazantB: |
case C60bazantB:{ |
multiph mtph; |
517,6 → 525,7 |
case C60baroghelB: |
case C30baroghelB: |
case o30bazantB: |
case C30bazantB: |
case C60bazantB:{ |
multiph mtph; |
584,6 → 593,7 |
case C60baroghelB: |
case C30baroghelB: |
case o30bazantB: |
case C30bazantB: |
case C60bazantB: |
{ |
multiph mtph; |
647,6 → 657,7 |
case C60baroghelB: |
case C30baroghelB: |
case o30bazantB: |
case C30bazantB: |
case C60bazantB:{ |
multiph mtph; |
/trunk/SIFEL/TRFEL/SRC/transmat.cpp |
---|
686,6 → 686,10 |
break; |
} |
case C30bazantB: |
C30bazant[i].give_dof_names(dofname, ntm); |
break; |
case C60bazantB:{ |
C60bazant[i].give_dof_names(dofname, ntm); |
break; |
2653,6 → 2657,7 |
case C60baroghelB: |
case C30baroghelB: |
case o30bazantB: |
case C30bazantB: |
case C60bazantB: |
case soilmat1: |
break; |
2821,10 → 2826,9 |
break; |
} |
default:{ |
print_err("unknown material type is required",__FILE__,__LINE__,__func__); |
print_err("unknown material type is required on ip %ld, eid=%ld",__FILE__,__LINE__,__func__, ipp, Tm->elip[ipp]+1); |
} |
} |
return t; |
} |
2870,7 → 2874,7 |
break; |
} |
default:{ |
print_err("unknown material type is required",__FILE__,__LINE__,__func__); |
print_err("unknown material type %d is required on ip %ld, eid=%ld",__FILE__,__LINE__,__func__, ipp, Tm->elip[ipp]+1); |
} |
} |
3140,6 → 3144,14 |
pp = consol_wf1[i].give_effective_pore_pressure (ipp); |
break; |
} |
case consolhwf2:{ |
pp = consol_hwf2[i].give_effective_pore_pressure (ipp); |
break; |
} |
case consolhawf3:{ |
pp = consol_hawf3[i].give_effective_pore_pressure (ipp); |
break; |
} |
default:{ |
print_err("unknown material type is required",__FILE__,__LINE__,__func__); |
} |
4257,6 → 4269,7 |
case C60baroghelB: |
case C30baroghelB: |
case o30bazantB: |
case C30bazantB: |
case C60bazantB:{ |
multiph mtph; |
mtph.values_correction (nv); |
4748,6 → 4761,7 |
case C60baroghelB: |
case C30baroghelB: |
case o30bazantB: |
case C30bazantB: |
case C60bazantB: |
case soilmat1: |
break; |
5034,6 → 5048,7 |
case C60baroghelB: |
case C30baroghelB: |
case o30bazantB: |
case C30bazantB: |
case C60bazantB: |
case soilmat1: |
break; |
5213,6 → 5228,7 |
case C60baroghelB: |
case C30baroghelB: |
case o30bazantB: |
case C30bazantB: |
case C60bazantB: |
case soilmat1: |
case consolwf2: |
5508,6 → 5524,7 |
case C60baroghelB: |
case C30baroghelB: |
case o30bazantB: |
case C30bazantB: |
case C60bazantB: |
case soilmat1: |
case consolwf2: |
/trunk/SIFEL/TRFEL/SRC/van_genuchten.cpp |
---|
3,9 → 3,20 |
Author: Tomas Krejci, 13/04/2018 |
Purpose: retention curve accorging to Van_Genuchten model |
sources: |
M. Th. van Genuchten, A closed equation for predicting the hydraulic conductivity of |
classical expr: M. Th. van Genuchten, A closed equation for predicting the hydraulic conductivity of |
unsaturated soils, Journal Soil Science Society of America 44 (1980), 892-898; |
pore water pressure (suction) is assumed in kPa (kilo Pascals) |
extension 1: A full-scale in situ heating test for high-level nuclear waste disposal: observations, analysis and interpretation |
A. Gens, M. Sanchez, L. Do N. Guimaraes, E. E. Alonso, A. Lloret, S. Olivella, M. V. Villar, and F. Huertas |
Geotechnique 2009 59:4, 377-399 |
extension 2: ?? |
extension 3: Abel Carlos Jacinto, Maria Victoria Villar, Roberto Gomez-Espina, Alberto Ledesma, |
Adaptation of the van Genuchten expression to the effects of temperature and density for compacted bentonites, Applied Clay Science, |
Volume 42, Issues 3–4, 2009,Pages 575-582,ISSN 0169-1317,https://doi.org/10.1016/j.clay.2008.04.001. |
*/ |
#include <stdio.h> |
16,6 → 27,8 |
van_genuchten_reten::van_genuchten_reten() |
{ |
vg_ret_type = 0; //retention curve type |
ssat = 1.0; //saturation degree [-] |
sirr = 0.2; //irreversible saturation degree [-] |
ksat = 0.1; //saturation permeability [??] |
23,6 → 36,11 |
delta = 20.0; //parameter in m^(-1); delta = 20.0 [1/m]; delta = 0.2 [1/cm] |
expn = 2.0; //parameter n |
expm = 0.0; //parameter m |
p0 = 0.0; //parameter |
pd = 0.0; //parameter |
lambda0 = 1.0; //parameter |
lambdap = 1.0; //parameter |
} |
van_genuchten_reten::~van_genuchten_reten() |
38,7 → 56,29 |
*/ |
void van_genuchten_reten::read(XFILE *in) |
{ |
xfscanf (in,"%lf %lf %lf %lf %lf %lf", &ssat, &sirr, &expn, &expm, &ksat, &delta); |
//retention curve type: |
xfscanf (in,"%ld",&vg_ret_type); |
switch (vg_ret_type){ |
case 0:{//classical expression |
xfscanf (in,"%lf %lf %lf %lf %lf %lf", &ssat, &sirr, &expn, &expm, &ksat, &delta); |
break; |
} |
case 1:{//extended for expansive clays |
xfscanf (in,"%lf %lf %lf %lf %lf %lf", &ssat, &sirr, &p0, &lambda0, &pd, &lambdap); |
break; |
} |
case 2:{//extended for expansive clays and temperature dependent |
xfscanf (in,"%lf %lf %lf %lf %lf %lf", &ssat, &sirr, &p0, &lambda0, &pd, &lambdap); |
break; |
} |
default:{ |
print_err ("unknown van genuchten retention curve type is required", __FILE__, __LINE__, __func__); |
abort(); |
} |
} |
} |
/** |
50,7 → 90,24 |
*/ |
void van_genuchten_reten::print(FILE *out) |
{ |
fprintf (out,"\n%lf %lf %lf %lf %lf %lf\n", ssat, sirr, expn, expm, ksat, delta); |
switch (vg_ret_type){ |
case 0:{//classical expression |
fprintf (out,"\n%lf %lf %lf %lf %lf %lf\n", ssat, sirr, expn, expm, ksat, delta); |
break; |
} |
case 1:{//extended for expansive clays |
fprintf (out,"\n%lf %lf %lf %lf %lf %lf\n", ssat, sirr, p0, lambda0, pd, lambdap); |
break; |
} |
case 2:{//extended for expansive clays and temperature dependent |
fprintf (out,"\n%lf %lf %lf %lf %lf %lf\n", ssat, sirr, p0, lambda0, pd, lambdap); |
break; |
} |
default:{ |
print_err ("unknown van genuchten retention curve type is required", __FILE__, __LINE__, __func__); |
abort(); |
} |
} |
} |
/** |
63,18 → 120,48 |
*/ |
double van_genuchten_reten::sw(double pw) |
{ |
double sw,hp,theta; |
double sw,hp,theta,fd=1.0,ft=1.0; |
pw = pw/1000.0;//in kPa |
if(pw >= 0.0) |
pw = 0.0;//for positive pressure |
hp = pw/gamaw; |
if(expm == 0.0) |
expm = 1.0 - 1.0/expn; |
theta = pow(1+(pow(delta*fabs(hp),expn)),-expm); |
sw = sirr + (ssat - sirr)*theta; |
switch (vg_ret_type){ |
case 0:{//classical expression |
if(pw >= 0.0) |
pw = 0.0;//for positive pressure |
hp = pw/gamaw; |
if(expm == 0.0) |
expm = 1.0 - 1.0/expn; |
theta = pow(1+(pow(delta*fabs(hp),expn)),-expm); |
sw = sirr + (ssat - sirr)*theta; |
break; |
} |
case 1:{//extended for expansive clays - this is wrong!! |
if(pw >= 0.0) |
pw = 0.0;//for positive pressure (suction) |
expm = 1.0 - 1.0/lambda0; |
fd = pow((1.0-pw/pd),lambdap); |
theta = pow(1+(pow((pw/p0),expm)),-lambda0)*fd; |
sw = sirr + (ssat - sirr)*theta; |
break; |
} |
case 2:{//extended for expansive clays and temperature dependent - this is wrong!! |
if(pw >= 0.0) |
pw = 0.0;//for positive pressure (suction) |
expm = 1.0 - 1.0/lambda0; |
fd = pow((1.0-pw/pd),lambdap); |
ft = 1.0;//temp |
theta = pow(1+(pow((pw/p0),expm)),-lambda0)*fd*ft; |
sw = sirr + (ssat - sirr)*theta; |
break; |
} |
default:{ |
print_err ("unknown van genuchten retention curve type is required", __FILE__, __LINE__, __func__); |
abort(); |
} |
} |
return(sw); |
} |
89,21 → 176,51 |
*/ |
double van_genuchten_reten::dsw_dpw(double pw) |
{ |
double dsw_dpw,hp; |
double dsw_dpw,hp,fd,theta,dtheta_dpw,dfd_dpw; |
pw = pw/1000.0;//in kPa |
if(pw >= 0.0){ |
pw = 0.0;//for positive pressure |
dsw_dpw = 0.0; |
switch (vg_ret_type){ |
case 0:{//classical expression |
if(pw >= 0.0){ |
pw = 0.0;//for positive pressure |
dsw_dpw = 0.0; |
} |
else{ |
hp = pw/gamaw; |
if(expm == 0.0) |
expm = 1.0 - 1.0/expn; |
dsw_dpw = (expm*expn*delta*(ssat - sirr)*pow(delta*fabs(hp),(expn-1)))/(pow(1+(pow(delta*fabs(hp),expn)),(expm+1)))/gamaw; |
} |
break; |
} |
else{ |
hp = pw/gamaw; |
if(expm == 0.0) |
expm = 1.0 - 1.0/expn; |
dsw_dpw = (expm*expn*delta*(ssat - sirr)*pow(delta*fabs(hp),(expn-1)))/(pow(1+(pow(delta*fabs(hp),expn)),(expm+1)))/gamaw; |
case 1:{//extended for expansive clays - this is wrong!! |
if(pw >= 0.0){ |
pw = 0.0;//for positive pressure |
dsw_dpw = 0.0; |
} |
else{ |
expm = 1.0 - 1.0/lambda0; |
fd = pow((1.0-pw/pd),lambdap); |
theta = pow(1+(pow((pw/p0),expm)),-lambda0); |
dtheta_dpw = -lambda0*pow(1+(pow((pw/p0),expm)),-lambda0-1.0)*expm*pow((pw/p0),expm-1); |
dfd_dpw = lambdap*pow((1.0-pw/pd),-lambdap-1.0); |
dsw_dpw = dtheta_dpw*fd + theta*dfd_dpw; |
dsw_dpw = (ssat - sirr)*dsw_dpw; |
} |
break; |
} |
case 2:{//extended for expansive clays and temperature dependent |
//has to be completed |
break; |
} |
default:{ |
print_err ("unknown van genuchten retention curve type is required", __FILE__, __LINE__, __func__); |
abort(); |
} |
} |
dsw_dpw = dsw_dpw/1000.0;//basic units are Pa |
return(dsw_dpw); |
121,7 → 238,7 |
double van_genuchten_reten::dsw_dt(double pw) |
{ |
double dsw_dt; |
//has to be completed |
dsw_dt = 0.0; |
return(dsw_dt); |
/trunk/SIFEL/TRFEL/SRC/van_genuchten.h |
---|
23,7 → 23,9 |
double get_k(double pw); |
private: |
long vg_ret_type; |
double ssat,sirr,ksat,gamaw,delta,expn,expm; |
double p0,pd,lambda0,lambdap; |
}; |