00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <math.h>
00026
00027 #include "load.h"
00028 #include "elm.h"
00029 #include "material.h"
00030 #include "node.h"
00031 #include "rio.h"
00032
00033
00034
00035
00036 void MaterialTimeStep( sMaterial *, double * );
00037 void MaterialDensity ( sMaterial *, double * );
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 typedef struct _mohrnacdata
00049 {
00050 double E;
00051 double Nu;
00052 double sC;
00053 double iC;
00054 double fC;
00055 double sPhi;
00056 double iPhi;
00057 double fPhi;
00058 double sPsi;
00059 double iPsi;
00060 double fPsi;
00061 } sMohrNAVData;
00062
00063 #ifndef PI
00064 #define PI 3.141592654
00065 #endif
00066
00067
00068
00069
00070
00071 static double _UpdateParameter( double, double, double, double );
00072
00073
00074
00075
00076 static double _UpdateParameter( double effdef, double spar, double ipar,
00077 double fpar )
00078 {
00079 double aux, npar;
00080
00081
00082
00083 if( effdef == 0.0 )
00084 return fpar;
00085
00086
00087
00088 aux = effdef / spar;
00089 if( aux <= 1.0 )
00090 npar = (fpar * aux) + (ipar * (1.0 - aux));
00091 else
00092 npar = fpar;
00093
00094 return npar;
00095
00096 }
00097
00098
00099
00100
00101
00102
00103 static void MohrCoulombNAVNew ( int, sMaterial ** );
00104 static void MohrCoulombNAVFree ( sMaterial * );
00105 static void MohrCoulombNAVRead ( sMaterial * );
00106 static void MohrCoulombNAVEParameter ( sMaterial *, double * );
00107 static void MohrCoulombNAVNuParameter ( sMaterial *, double * );
00108 static void MohrCoulombNAVCMatrix ( sMaterial *, double [6][6] );
00109 static void MohrCoulombNAVUpdateStress( sMaterial *, double, double *,
00110 double *, double *,
00111 double * );
00112
00113
00114
00115
00116
00117
00118
00119
00120 static void MohrCoulombNAVNew( int label, sMaterial **mat )
00121 {
00122 sMohrNAVData *data = 0L;
00123
00124
00125
00126 (*mat) = (sMaterial *)calloc(1, sizeof(sMaterial));
00127
00128
00129
00130 data = (sMohrNAVData *)calloc(1, sizeof(sMohrNAVData));
00131
00132
00133
00134 data->E = data->Nu = 0.0;
00135 data->sC = data->iC = data->fC = 0.0;
00136 data->sPhi = data->iPhi = data->fPhi = 0.0;
00137 data->sPsi = data->iPsi = data->fPsi = 0.0;
00138
00139
00140
00141 (*mat)->type = MOHR_COULOMB_NAV;
00142 (*mat)->label = label;
00143 (*mat)->Gamma = 0.0;
00144 (*mat)->data = (void *)data;
00145
00146
00147
00148 MatList[label-1] = (*mat);
00149
00150 }
00151
00152
00153
00154
00155
00156
00157
00158 static void MohrCoulombNAVFree( sMaterial *mat )
00159 {
00160 sMohrNAVData *data = 0L;
00161
00162
00163
00164 data = (sMohrNAVData *)mat->data;
00165
00166
00167
00168 free( data );
00169
00170
00171
00172 mat->data = 0L;
00173
00174 }
00175
00176
00177
00178
00179
00180
00181
00182 static void MohrCoulombNAVRead( sMaterial *mat )
00183 {
00184 sMohrNAVData *data = 0L;
00185 double nu, e;
00186 double sc, ic, fc;
00187 double sphi, iphi, fphi;
00188 double spsi, ipsi, fpsi;
00189
00190
00191
00192 data = (sMohrNAVData *)mat->data;
00193
00194
00195
00196 fscanf( nf, "%lf %lf", &e, &nu );
00197 fscanf( nf, "%lf %lf %lf", &ic, &fc, &sc );
00198 fscanf( nf, "%lf %lf %lf", &iphi, &fphi, &sphi );
00199 fscanf( nf, "%lf %lf %lf", &ipsi, &fpsi, &spsi );
00200
00201
00202
00203 data->E = e;
00204 data->Nu = nu;
00205 data->sC = sc;
00206 data->iC = ic;
00207 data->fC = fc;
00208 data->sPhi = sphi;
00209 data->iPhi = iphi;
00210 data->fPhi = fphi;
00211 data->sPsi = spsi;
00212 data->iPsi = ipsi;
00213 data->fPsi = fpsi;
00214
00215 }
00216
00217
00218
00219
00220 static void MohrCoulombNAVEParameter( sMaterial *mat, double *e )
00221 {
00222 sMohrNAVData *data = 0L;
00223
00224
00225
00226 data = (sMohrNAVData *)mat->data;
00227
00228
00229
00230 (*e) = data->E;
00231
00232 }
00233
00234
00235
00236
00237
00238 static void MohrCoulombNAVNuParameter( sMaterial *mat, double *nu )
00239 {
00240 sMohrNAVData *data = 0L;
00241
00242
00243
00244 data = (sMohrNAVData *)mat->data;
00245
00246
00247
00248 (*nu) = data->Nu;
00249
00250 }
00251
00252
00253
00254
00255
00256 static void MohrCoulombNAVCMatrix( sMaterial *mat, double cm[6][6] )
00257 {
00258 int i, j;
00259 sMohrNAVData *data = 0L;
00260 double e, nu;
00261
00262
00263
00264 for( i = 0; i < 6; i++ )
00265 for( j = 0; j < 6; j++ )
00266 cm[i][j] = 0.0;
00267
00268
00269
00270 data = (sMohrNAVData *)mat->data;
00271
00272
00273
00274 e = data->E;
00275 nu = data->Nu;
00276
00277
00278
00279 if( NDof == 3 )
00280 {
00281 cm[0][0] =
00282 cm[1][1] =
00283 cm[2][2] = e*(nu*nu-1.0) / (nu*(nu+nu*nu)+nu*(nu*nu+nu)+nu*nu-1.0);
00284 cm[1][0] =
00285 cm[2][0] =
00286 cm[0][1] =
00287 cm[2][1] =
00288 cm[0][2] =
00289 cm[1][2] = -e*(nu*nu+nu) / (nu*(nu+nu*nu)+nu*(nu*nu+nu)+nu*nu-1.0);
00290 cm[3][3] =
00291 cm[4][4] =
00292 cm[5][5] = (e * e) / (e + e * (1.0 + 2.0 * nu));
00293 }
00294 else
00295 {
00296 cm[0][0] = cm[1][1] = (e * (1.0 - nu)) / ((1.0 + nu) * (1.0 - (2.0 * nu)));
00297 cm[0][1] = cm[1][0] = (e * nu) / ((1.0 + nu) * (1.0 - (2.0 * nu)));
00298 cm[2][2] = e / (2.0 * (1.0 + nu));
00299 }
00300
00301 }
00302
00303
00304
00305
00306
00307 static void MohrCoulombNAVUpdateStress( sMaterial *mat, double dtime,
00308 double *yield,
00309 double *effdef,
00310 double *str,
00311 double *def )
00312 {
00313 sMohrNAVData *data = 0L;
00314 double sig1, sig3, sig2;
00315 double c, sc, ic, fc;
00316 double phi, sphi, iphi, fphi;
00317 double psi, spsi, ipsi, fpsi;
00318 double pf, mult, aldp, ni;
00319 double cm[6][6];
00320
00321
00322
00323 data = (sMohrNAVData *)mat->data;
00324
00325
00326
00327 MohrCoulombNAVCMatrix( mat, cm );
00328
00329
00330
00331 MohrCoulombNAVNuParameter( mat, &ni );
00332
00333
00334
00335 sc = data->sC;
00336 ic = data->iC;
00337 fc = data->fC;
00338 sphi = data->sPhi;
00339 iphi = data->iPhi;
00340 fphi = data->fPhi;
00341 spsi = data->sPsi;
00342 ipsi = data->iPsi;
00343 fpsi = data->fPsi;
00344
00345
00346
00347 sig1 = ((str[0] + str[1]) / 2.0) -
00348 sqrt( (str[0] - str[1])*(str[0] - str[1])/4.0 + str[2] * str[2] );
00349 sig3 = ((str[0] + str[1]) / 2.0) +
00350 sqrt( (str[0] - str[1])*(str[0] - str[1])/4.0 + str[2] * str[2] );
00351 sig2 = ni * (sig1 + sig3);
00352
00353
00354
00355 phi = _UpdateParameter( (*effdef), sphi, iphi, fphi );
00356 phi *= PI / 180.0;
00357 phi = (1.0 + sin(phi)) / (1.0 - sin(phi));
00358
00359
00360
00361 c = _UpdateParameter( (*effdef), sc, ic, fc );
00362
00363
00364
00365 (*yield) = pf = sig1 - (sig3 * phi) + (2.0 * c * sqrt(phi));
00366
00367
00368
00369 if( pf <= 0.0 )
00370 {
00371 if( sig1 == str[0]) aldp = 0.0;
00372 else aldp = atan2( (sig1 - str[0]), str[2] );
00373
00374 psi = _UpdateParameter( (*effdef), spsi, ipsi, fpsi );
00375 psi *= PI / 180.0;
00376 psi = (1.0 + sin(psi)) / (1.0 - sin(psi));
00377
00378 mult = pf / (-cm[0][0] * (1.0 + (phi*psi)) + (2.0 * psi * cm[0][1]));
00379
00380 sig1 += mult * (cm[0][0] - (cm[0][1] * psi));
00381 sig3 += mult * (cm[0][1] - (cm[0][0] * psi));
00382 sig2 += mult * cm[0][0] * (1.0 - psi);
00383
00384 str[0] = ((sig1 + sig3) / 2.0) + ((sig1-sig3) * cos(2.0 * aldp) / 2.0);
00385 str[1] = ((sig1 + sig3) / 2.0) - ((sig1-sig3) * cos(2.0 * aldp) / 2.0);
00386 str[2] = ((sig1 - sig3) * (sin(2.0 * aldp))) / 2.0;
00387 str[3] = sig2;
00388
00389
00390
00391 (*effdef) += mult * sqrt((2.0/3.0)*(1.0+(psi*psi)));
00392 }
00393
00394 }
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405 void MohrCoulombNAVInit( void );
00406 void MohrCoulombNAVInit( void )
00407 {
00408
00409
00410 MatClass[MOHR_COULOMB_NAV].new = MohrCoulombNAVNew;
00411 MatClass[MOHR_COULOMB_NAV].free = MohrCoulombNAVFree;
00412 MatClass[MOHR_COULOMB_NAV].read = MohrCoulombNAVRead;
00413 MatClass[MOHR_COULOMB_NAV].epar = MohrCoulombNAVEParameter;
00414 MatClass[MOHR_COULOMB_NAV].nupar = MohrCoulombNAVNuParameter;
00415 MatClass[MOHR_COULOMB_NAV].cmatrix = MohrCoulombNAVCMatrix;
00416 MatClass[MOHR_COULOMB_NAV].updatestr = MohrCoulombNAVUpdateStress;
00417 MatClass[MOHR_COULOMB_NAV].updatepar = 0L;
00418 MatClass[MOHR_COULOMB_NAV].timestep = MaterialTimeStep;
00419 MatClass[MOHR_COULOMB_NAV].density = MaterialDensity;
00420 MatClass[MOHR_COULOMB_NAV].vstrain = 0L;
00421
00422 }
00423
00424
00425
00426