![]() | This article is rated B-class on Wikipedia's
content assessment scale. It is of interest to the following WikiProjects: | ||||||||||||||||||||
|
I'm not skilled at writing articles. I'm sure that the pictures and their captions can be placed better, I just don't know how to do it better than it currently is. Please make it better if you can :)
Janek Kozicki 17:24, 19 November 2006 (UTC)
Oh, and I don't have the formulas for Brestler-Pister and Willam-Warnke expressed in principal stresses (). If I find it, I will be able to plot it, just like all the other surfaces. If you know this formula, plese write it here, so later I will see your addition, and I will plot the surface.
Janek Kozicki 07:51, 20 November 2006 (UTC)
To plot the Willam-Warnke surface in space you will need , and in terms of . From the article on Stress we have
To find in terms of we note that
In matrix form (in terms of the principal stresses)
Therefore,
This leads to the needed expression for in terms of
Next you can compute the Haigh-Westergaard coordinates using the relations
Then compute
followed by
Finally, plug into the expression for the Willam-Warnke condition
A (untested) piece of code to generate a scalar field (of which the 0 level set is the yield surface) is:
void viewer::generateScalarField() { using namespace std; for(int i=0;i<sizeX;i++) { for(int j=0;j<sizeY;j++) { for(int k=0;k<sizeZ;k++) { // calculate s1,s2,s3 from the position in 3D array scalarField // the origin of the coordinate system is in the center (sizeXYZ * 0.5) // and the 3D array scalarField represents a cube from -1.0 to 1.0 long double s1 = (long double)i/(long double)sizeX*2.0-1.0; long double s2 = (long double)j/(long double)sizeY*2.0-1.0; long double s3 = (long double)k/(long double)sizeZ*2.0-1.0; long double I1 = s1+s2+s3; long double J2 = 1.0l/6.0l*(pow(s2-s3,2.0l)+pow(s3-s1,2.0l)+pow(s1-s2,2.0l)); long double J3 = 1.0l/27.0l*(2.0l*s1-s2-s3)*(2.0l*s2-s1-s3)*(2.0l*s3-s1-s2); long double xi = 1.0l/sqrt(3.0l)*I1; long double rho = sqrt(2.0l*J2); long double theta = 0.0000001l; // calculate theta double t4 = J2*J2*J3; double t5 = 1.5*sqrt(3)*J3; double t6 = sqrt(t4); bool flag = true; if (fabs(t6) <= fabs(t5)*1.0e-16) {theta = 0.0000001; flag = false;} if (fabs(t6) < 1.0e-16 && flag) {theta = 0.0000001; flag = false;} double t7 = t5/t6; double ta1 = fabs(t7-1.0); double ta2 = fabs(t7+1.0); if (ta1 < 0.1 && flag) {theta = 0.0000001/3.0; flag = false;} if (ta2 < 0.1 && flag) {theta = 3.1415921/3.0; flag = false;} if ((t7 > 1.0 || t7 < -1.0) && flag) {theta = 3.1415921/3.0; flag = false;} if (flag) { theta = 1.0/3.0*acos(t7); flag = false; } // Willam-Warnke long double sc = 1.0l; long double st = 0.2l; long double sb = 1.5l; long double r_c = sqrt(1.2l)*sb*st/(3.0l*sb*st + sb*sc - st*sc); long double r_t = sqrt(1.2l)*sb*st/(sc*(2.0l*sb+st)); long double g_numer = 2.0l*r_c*(r_c*r_c-r_t*r_t)*cos(theta) + r_c*(2.0l*r_t - r_c)* sqrt(4*(r_c*r_c - r_t*r_t)*pow(cos(theta),2.0l) + 5.0l*r_t*r_t - 4.0l*r_t*r_c); long double g_denom = 4.0l*(r_c*r_c - r_t*r_t)*pow(cos(theta),2.0l) + pow(r_c-2*r_t,2.0l); long double g = g_numer/g_denom; long double lambda = sqrt(0.2l)/g; long double B = 1.0l/sqrt(3.0l)*(sb*st)/(sc*sb-st); scalarField[i][j][k] = lambda*rho + B*xi - sc; } } } }
Bbanerje ( talk) 02:59, 25 May 2008 (UTC)
Pictures:
Problems:
So I calculated this again. I changed the code (shown above) to use high precision - long double (the "l" after numbres say that they are long double also, instead of double). Now we can see that the holes are rather not due to marching cubes mistake, but rather there is some linear discontinuity on the "edges".
Janek Kozicki ( talk) 19:24, 25 May 2008 (UTC)
void viewer::generateScalarField() { using namespace std; for(int i=0;i<sizeX;i++) { for(int j=0;j<sizeY;j++) { for(int k=0;k<sizeZ;k++) { // calculate s1,s2,s3 from the position in 3D array scalarField // the origin of the coordinate system is in the center (sizeXYZ * 0.5) // and the 3D array scalarField represents a cube from -1.0 to 1.0 long double s1 = (long double)i/(long double)sizeX*2.0-1.0; long double s2 = (long double)j/(long double)sizeY*2.0-1.0; long double s3 = (long double)k/(long double)sizeZ*2.0-1.0; long double I1 = s1+s2+s3; long double J2 = 1.0l/6.0l*(pow(s2-s3,2.0l)+pow(s3-s1,2.0l)+pow(s1-s2,2.0l)); long double J3 = 1.0l/27.0l*(2.0l*s1-s2-s3)*(2.0l*s2-s1-s3)*(2.0l*s3-s1-s2); long double xi = 1.0l/sqrt(3.0l)*I1; long double rho = sqrt(2.0l*J2); long double theta = 0.0000001l; // calculate theta double t4 = J2*J2*J3; double t5 = 1.5*sqrt(3)*J3; double t6 = sqrt(t4); bool flag = true; if (fabs(t6) <= fabs(t5)*1.0e-16) {theta = 0.0000001; flag = false;} if (fabs(t6) < 1.0e-16 && flag) {theta = 0.0000001; flag = false;} double t7 = t5/t6; double ta1 = fabs(t7-1.0); double ta2 = fabs(t7+1.0); if (ta1 < 0.1 && flag) {theta = 0.0000001/3.0; flag = false;} if (ta2 < 0.1 && flag) {theta = 3.1415921/3.0; flag = false;} if ((t7 > 1.0 || t7 < -1.0) && flag) {theta = 3.1415921/3.0; flag = false;} if (flag) { theta = 1.0/3.0*acos(t7); flag = false; } // Willam-Warnke long double sc = 1.0l; long double st = 0.2l; long double sb = 1.5l; long double r_c = sqrt(3.0l)*sc*(sb-st)/((sc+st)*sb-sc*st); long double r_t = sqrt(3.0l)*(sb-st)/(2.0l*sb-st); long double u_theta = 2.0l*r_c*(r_c*r_c-r_t*r_t)*cos(theta); long double v_theta = r_c*(2.0l*r_t - r_c)* sqrt(4*(r_c*r_c - r_t*r_t)*pow(cos(theta),2.0l) + 5.0l*r_t^2 - 4.0l*r_t*r_c); long double w_theta = 4.0l*(r_c*r_c - r_t*r_t)*pow(cos(theta),2.0l) + pow(r_c-2*r_t,2.0l); long double lambda = sqrt(2.0l/3.0l)*(u_theta+v_theta)/w_theta; long double B = 1.0l/sqrt(3.0l)*(sb*st)/(sb-st); scalarField[i][j][k] = rho + lambda*(xi - B); } } } }
Hi, I believe there is a mistake in the equation for the Drucker-Prager yield surface. At present the equation contains the following:
(m-1)/2 and (m+1)/2
Based on the definitions given on the main page for the Drucker Prager yield criterion ( /info/en/?search=Drucker%E2%80%93Prager_yield_criterion), I believe the coefficients should be
(m-1)/2m and (m+1)/2m.
Can somebody please check and confirm.
![]() | This article is rated B-class on Wikipedia's
content assessment scale. It is of interest to the following WikiProjects: | ||||||||||||||||||||
|
I'm not skilled at writing articles. I'm sure that the pictures and their captions can be placed better, I just don't know how to do it better than it currently is. Please make it better if you can :)
Janek Kozicki 17:24, 19 November 2006 (UTC)
Oh, and I don't have the formulas for Brestler-Pister and Willam-Warnke expressed in principal stresses (). If I find it, I will be able to plot it, just like all the other surfaces. If you know this formula, plese write it here, so later I will see your addition, and I will plot the surface.
Janek Kozicki 07:51, 20 November 2006 (UTC)
To plot the Willam-Warnke surface in space you will need , and in terms of . From the article on Stress we have
To find in terms of we note that
In matrix form (in terms of the principal stresses)
Therefore,
This leads to the needed expression for in terms of
Next you can compute the Haigh-Westergaard coordinates using the relations
Then compute
followed by
Finally, plug into the expression for the Willam-Warnke condition
A (untested) piece of code to generate a scalar field (of which the 0 level set is the yield surface) is:
void viewer::generateScalarField() { using namespace std; for(int i=0;i<sizeX;i++) { for(int j=0;j<sizeY;j++) { for(int k=0;k<sizeZ;k++) { // calculate s1,s2,s3 from the position in 3D array scalarField // the origin of the coordinate system is in the center (sizeXYZ * 0.5) // and the 3D array scalarField represents a cube from -1.0 to 1.0 long double s1 = (long double)i/(long double)sizeX*2.0-1.0; long double s2 = (long double)j/(long double)sizeY*2.0-1.0; long double s3 = (long double)k/(long double)sizeZ*2.0-1.0; long double I1 = s1+s2+s3; long double J2 = 1.0l/6.0l*(pow(s2-s3,2.0l)+pow(s3-s1,2.0l)+pow(s1-s2,2.0l)); long double J3 = 1.0l/27.0l*(2.0l*s1-s2-s3)*(2.0l*s2-s1-s3)*(2.0l*s3-s1-s2); long double xi = 1.0l/sqrt(3.0l)*I1; long double rho = sqrt(2.0l*J2); long double theta = 0.0000001l; // calculate theta double t4 = J2*J2*J3; double t5 = 1.5*sqrt(3)*J3; double t6 = sqrt(t4); bool flag = true; if (fabs(t6) <= fabs(t5)*1.0e-16) {theta = 0.0000001; flag = false;} if (fabs(t6) < 1.0e-16 && flag) {theta = 0.0000001; flag = false;} double t7 = t5/t6; double ta1 = fabs(t7-1.0); double ta2 = fabs(t7+1.0); if (ta1 < 0.1 && flag) {theta = 0.0000001/3.0; flag = false;} if (ta2 < 0.1 && flag) {theta = 3.1415921/3.0; flag = false;} if ((t7 > 1.0 || t7 < -1.0) && flag) {theta = 3.1415921/3.0; flag = false;} if (flag) { theta = 1.0/3.0*acos(t7); flag = false; } // Willam-Warnke long double sc = 1.0l; long double st = 0.2l; long double sb = 1.5l; long double r_c = sqrt(1.2l)*sb*st/(3.0l*sb*st + sb*sc - st*sc); long double r_t = sqrt(1.2l)*sb*st/(sc*(2.0l*sb+st)); long double g_numer = 2.0l*r_c*(r_c*r_c-r_t*r_t)*cos(theta) + r_c*(2.0l*r_t - r_c)* sqrt(4*(r_c*r_c - r_t*r_t)*pow(cos(theta),2.0l) + 5.0l*r_t*r_t - 4.0l*r_t*r_c); long double g_denom = 4.0l*(r_c*r_c - r_t*r_t)*pow(cos(theta),2.0l) + pow(r_c-2*r_t,2.0l); long double g = g_numer/g_denom; long double lambda = sqrt(0.2l)/g; long double B = 1.0l/sqrt(3.0l)*(sb*st)/(sc*sb-st); scalarField[i][j][k] = lambda*rho + B*xi - sc; } } } }
Bbanerje ( talk) 02:59, 25 May 2008 (UTC)
Pictures:
Problems:
So I calculated this again. I changed the code (shown above) to use high precision - long double (the "l" after numbres say that they are long double also, instead of double). Now we can see that the holes are rather not due to marching cubes mistake, but rather there is some linear discontinuity on the "edges".
Janek Kozicki ( talk) 19:24, 25 May 2008 (UTC)
void viewer::generateScalarField() { using namespace std; for(int i=0;i<sizeX;i++) { for(int j=0;j<sizeY;j++) { for(int k=0;k<sizeZ;k++) { // calculate s1,s2,s3 from the position in 3D array scalarField // the origin of the coordinate system is in the center (sizeXYZ * 0.5) // and the 3D array scalarField represents a cube from -1.0 to 1.0 long double s1 = (long double)i/(long double)sizeX*2.0-1.0; long double s2 = (long double)j/(long double)sizeY*2.0-1.0; long double s3 = (long double)k/(long double)sizeZ*2.0-1.0; long double I1 = s1+s2+s3; long double J2 = 1.0l/6.0l*(pow(s2-s3,2.0l)+pow(s3-s1,2.0l)+pow(s1-s2,2.0l)); long double J3 = 1.0l/27.0l*(2.0l*s1-s2-s3)*(2.0l*s2-s1-s3)*(2.0l*s3-s1-s2); long double xi = 1.0l/sqrt(3.0l)*I1; long double rho = sqrt(2.0l*J2); long double theta = 0.0000001l; // calculate theta double t4 = J2*J2*J3; double t5 = 1.5*sqrt(3)*J3; double t6 = sqrt(t4); bool flag = true; if (fabs(t6) <= fabs(t5)*1.0e-16) {theta = 0.0000001; flag = false;} if (fabs(t6) < 1.0e-16 && flag) {theta = 0.0000001; flag = false;} double t7 = t5/t6; double ta1 = fabs(t7-1.0); double ta2 = fabs(t7+1.0); if (ta1 < 0.1 && flag) {theta = 0.0000001/3.0; flag = false;} if (ta2 < 0.1 && flag) {theta = 3.1415921/3.0; flag = false;} if ((t7 > 1.0 || t7 < -1.0) && flag) {theta = 3.1415921/3.0; flag = false;} if (flag) { theta = 1.0/3.0*acos(t7); flag = false; } // Willam-Warnke long double sc = 1.0l; long double st = 0.2l; long double sb = 1.5l; long double r_c = sqrt(3.0l)*sc*(sb-st)/((sc+st)*sb-sc*st); long double r_t = sqrt(3.0l)*(sb-st)/(2.0l*sb-st); long double u_theta = 2.0l*r_c*(r_c*r_c-r_t*r_t)*cos(theta); long double v_theta = r_c*(2.0l*r_t - r_c)* sqrt(4*(r_c*r_c - r_t*r_t)*pow(cos(theta),2.0l) + 5.0l*r_t^2 - 4.0l*r_t*r_c); long double w_theta = 4.0l*(r_c*r_c - r_t*r_t)*pow(cos(theta),2.0l) + pow(r_c-2*r_t,2.0l); long double lambda = sqrt(2.0l/3.0l)*(u_theta+v_theta)/w_theta; long double B = 1.0l/sqrt(3.0l)*(sb*st)/(sb-st); scalarField[i][j][k] = rho + lambda*(xi - B); } } } }
Hi, I believe there is a mistake in the equation for the Drucker-Prager yield surface. At present the equation contains the following:
(m-1)/2 and (m+1)/2
Based on the definitions given on the main page for the Drucker Prager yield criterion ( /info/en/?search=Drucker%E2%80%93Prager_yield_criterion), I believe the coefficients should be
(m-1)/2m and (m+1)/2m.
Can somebody please check and confirm.