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