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 _mohrdata
00049 {
00050 double E;
00051 double Nu;
00052 double C;
00053 double Phi;
00054 } sMohrData;
00055
00056 #ifndef PI
00057 #define PI 3.141592654
00058 #endif
00059
00060 #ifndef THETA_MIN
00061 #define THETA_MIN 0.5
00062 #endif
00063
00064 #ifndef THETA_MAX
00065 #define THETA_MAX 59.5
00066 #endif
00067
00068 #ifndef ANM_TOL
00069 #define ANM_TOL 1.0e-12
00070 #endif
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 static void MohrCoulombNew ( int, sMaterial ** );
00082 static void MohrCoulombFree ( sMaterial * );
00083 static void MohrCoulombRead ( sMaterial * );
00084 static void MohrCoulombEParameter ( sMaterial *, double * );
00085 static void MohrCoulombNuParameter ( sMaterial *, double * );
00086 static void MohrCoulombCMatrix ( sMaterial *, double [6][6] );
00087 static void MohrCoulombUpdateStress( sMaterial *, double, double *, double *,
00088 double *, double * );
00089
00090
00091
00092
00093
00094
00095
00096
00097 static void MohrCoulombNew( int label, sMaterial **mat )
00098 {
00099 sMohrData *data = 0L;
00100
00101
00102
00103 (*mat) = (sMaterial *)calloc(1, sizeof(sMaterial));
00104
00105
00106
00107 data = (sMohrData *)calloc(1, sizeof(sMohrData));
00108
00109
00110
00111 data->E = 0.0;
00112 data->Nu = 0.0;
00113 data->C = 0.0;
00114 data->Phi = 0.0;
00115
00116
00117
00118 (*mat)->type = MOHR_COULOMB;
00119 (*mat)->label = label;
00120 (*mat)->Gamma = 0.0;
00121 (*mat)->data = (void *)data;
00122
00123
00124
00125 MatList[label-1] = (*mat);
00126
00127 }
00128
00129
00130
00131
00132
00133
00134 static void MohrCoulombFree( sMaterial *mat )
00135 {
00136 sMohrData *data = 0L;
00137
00138
00139
00140 data = (sMohrData *)mat->data;
00141
00142
00143
00144 free( data );
00145
00146
00147
00148 mat->data = 0L;
00149
00150 }
00151
00152
00153
00154
00155
00156
00157 static void MohrCoulombRead( sMaterial *mat )
00158 {
00159 sMohrData *data = 0L;
00160 double c, nu, e, phi;
00161
00162
00163
00164 data = (sMohrData *)mat->data;
00165
00166
00167
00168 fscanf( nf, "%lf %lf %lf %lf", &e, &nu, &c, &phi );
00169
00170
00171
00172 data->E = e;
00173 data->Nu = nu;
00174 data->C = c;
00175 data->Phi = phi;
00176
00177 }
00178
00179
00180
00181
00182 static void MohrCoulombEParameter( sMaterial *mat, double *e )
00183 {
00184 sMohrData *data = 0L;
00185
00186
00187
00188 data = (sMohrData *)mat->data;
00189
00190
00191
00192 (*e) = data->E;
00193
00194 }
00195
00196
00197
00198
00199
00200 static void MohrCoulombNuParameter( sMaterial *mat, double *nu )
00201 {
00202 sMohrData *data = 0L;
00203
00204
00205
00206 data = (sMohrData *)mat->data;
00207
00208
00209
00210 (*nu) = data->Nu;
00211
00212 }
00213
00214
00215
00216
00217
00218 static void MohrCoulombCMatrix( sMaterial *mat, double cm[6][6] )
00219 {
00220 int i, j;
00221 sMohrData *data = 0L;
00222 double e, nu;
00223
00224
00225
00226 for( i = 0; i < 6; i++ )
00227 for( j = 0; j < 6; j++ )
00228 cm[i][j] = 0.0;
00229
00230
00231
00232 data = (sMohrData *)mat->data;
00233
00234
00235
00236 e = data->E;
00237 nu = data->Nu;
00238
00239
00240
00241 if( NDof == 3 )
00242 {
00243 cm[0][0] =
00244 cm[1][1] =
00245 cm[2][2] = e*(nu*nu-1.0) / (nu*(nu+nu*nu)+nu*(nu*nu+nu)+nu*nu-1.0);
00246 cm[1][0] =
00247 cm[2][0] =
00248 cm[0][1] =
00249 cm[2][1] =
00250 cm[0][2] =
00251 cm[1][2] = -e*(nu*nu+nu) / (nu*(nu+nu*nu)+nu*(nu*nu+nu)+nu*nu-1.0);
00252 cm[3][3] =
00253 cm[4][4] =
00254 cm[5][5] = (e * e) / (e + e * (1.0 + 2.0 * nu));
00255 }
00256 else
00257 {
00258 cm[0][0] = cm[1][1] = (e * (1.0 - nu)) / ((1.0 + nu) * (1.0 - (2.0 * nu)));
00259 cm[0][1] = cm[1][0] = (e * nu) / ((1.0 + nu) * (1.0 - (2.0 * nu)));
00260 cm[2][2] = e / (2.0 * (1.0 + nu));
00261 }
00262
00263 }
00264
00265
00266
00267
00268
00269 static void MohrCoulombUpdateStress( sMaterial *mat, double dtime,
00270 double *yield,
00271 double *effdef,
00272 double *str,
00273 double *def )
00274 {
00275 sMohrData *data = 0L;
00276 double sig1, sig3, sig2;
00277 double c, phi, pf, mult, aldp, ni;
00278 double cm[6][6];
00279 double sigaux;
00280 double num, den;
00281
00282
00283
00284 data = (sMohrData *)mat->data;
00285
00286
00287
00288 MohrCoulombCMatrix( mat, cm );
00289
00290
00291
00292 MohrCoulombNuParameter( mat, &ni );
00293
00294
00295
00296 c = data->C;
00297 phi = data->Phi;
00298
00299
00300
00301 sigaux = ((str[0] + str[1]) / 2.0) -
00302 sqrt( (str[0] - str[1])*(str[0] - str[1])/4.0 + str[2] * str[2] );
00303 sig3 = ((str[0] + str[1]) / 2.0) +
00304 sqrt( (str[0] - str[1])*(str[0] - str[1])/4.0 + str[2] * str[2] );
00305
00306 if(sigaux <= sig3){
00307 sig1 = sigaux;
00308 }
00309 else{
00310 sig1 = sig3;
00311 sig3 = sigaux;
00312 }
00313
00314 sig2 = ni * (sig1 + sig3);
00315
00316
00317
00318 phi *= PI / 180.0;
00319 phi = (1.0 + sin(phi)) / (1.0 - sin(phi));
00320
00321
00322
00323 (*yield) = pf = sig1 - (sig3 * phi) + (2.0 * c * sqrt(phi));
00324
00325
00326
00327 if( pf <= 0.0 )
00328 {
00329 if( sig1 == str[0]) aldp = 0.0;
00330 else aldp = atan2( (sig1 - str[0]), str[2] );
00331
00332 mult = pf / (-cm[0][0] * (1.0 + (phi*phi)) + (2.0 * phi * cm[0][1]));
00333
00334 sig1 += mult * (cm[0][0] - (cm[0][1] * phi));
00335 sig3 += mult * (cm[0][1] - (cm[0][0] * phi));
00336 sig2 += mult * cm[0][0] * (1.0 - phi);
00337
00338 str[0] = ((sig1 + sig3) / 2.0) + ((sig1-sig3) * cos(2.0 * aldp) / 2.0);
00339 str[1] = ((sig1 + sig3) / 2.0) - ((sig1-sig3) * cos(2.0 * aldp) / 2.0);
00340 str[2] = ((sig1 - sig3) * (sin(2.0 * aldp))) / 2.0;
00341 str[3] = sig2;
00342 }
00343
00344 num = fabs(2.0 * c * sqrt(phi));
00345 den = fabs(sig1 - sig3 * phi);
00346
00347 if(num <= den){
00348 str[4] = ( num / den );
00349 }
00350 else{
00351 str[4] = ( den / num );
00352 }
00353
00354 if(str[4] > 1.0) (str[4] = 1.0);
00355
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 void MohrCoulombInit( void );
00368 void MohrCoulombInit( void )
00369 {
00370
00371
00372 MatClass[MOHR_COULOMB].new = MohrCoulombNew;
00373 MatClass[MOHR_COULOMB].free = MohrCoulombFree;
00374 MatClass[MOHR_COULOMB].read = MohrCoulombRead;
00375 MatClass[MOHR_COULOMB].epar = MohrCoulombEParameter;
00376 MatClass[MOHR_COULOMB].nupar = MohrCoulombNuParameter;
00377 MatClass[MOHR_COULOMB].cmatrix = MohrCoulombCMatrix;
00378 MatClass[MOHR_COULOMB].updatestr = MohrCoulombUpdateStress;
00379 MatClass[MOHR_COULOMB].updatepar = 0L;
00380 MatClass[MOHR_COULOMB].timestep = MaterialTimeStep;
00381 MatClass[MOHR_COULOMB].density = MaterialDensity;
00382 MatClass[MOHR_COULOMB].vstrain = 0L;
00383
00384 }
00385
00386
00387
00388