RankTwoTensor TensorMechanicsPlasticTensile::dyieldFunction_dstress(const RankTwoTensor & stress, Real /*intnl*/) const { Real mean_stress = stress.trace() / 3.0; RankTwoTensor dmean_stress = stress.dtrace() / 3.0; Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0); if (sin3Lode <= _sin3tt) { // the non-edge-smoothed version std::vector<Real> eigvals; std::vector<RankTwoTensor> deigvals; stress.dsymmetricEigenvalues(eigvals, deigvals); Real denom = std::sqrt(smooth(stress) + Utility::pow<2>(eigvals[2] - mean_stress)); return dmean_stress + (0.5 * dsmooth(stress) * dmean_stress + (eigvals[2] - mean_stress) * (deigvals[2] - dmean_stress)) / denom; } else { // the edge-smoothed version Real kk = _aaa + _bbb * sin3Lode + _ccc * Utility::pow<2>(sin3Lode); RankTwoTensor dkk = (_bbb + 2.0 * _ccc * sin3Lode) * stress.dsin3Lode(_lode_cutoff); Real sibar2 = stress.secondInvariant(); RankTwoTensor dsibar2 = stress.dsecondInvariant(); Real denom = std::sqrt(smooth(stress) + sibar2 * Utility::pow<2>(kk)); return dmean_stress + (0.5 * dsmooth(stress) * dmean_stress + 0.5 * dsibar2 * Utility::pow<2>(kk) + sibar2 * kk * dkk) / denom; } }
RankFourTensor TensorMechanicsPlasticWeakPlaneShear::dflowPotential_dstress(const RankTwoTensor & stress, const Real & /*intnl*/) const { RankFourTensor dr_dstress; Real tau = std::sqrt(std::pow((stress(0,2) + stress(2,0))/2, 2) + std::pow((stress(1,2) + stress(2,1))/2, 2) + smooth(stress)); if (tau == 0.0) return dr_dstress; // note that i explicitly symmeterise RankTwoTensor dtau; dtau(0, 2) = dtau(2, 0) = 0.25*(stress(0, 2) + stress(2, 0))/tau; dtau(1, 2) = dtau(2, 1) = 0.25*(stress(1, 2) + stress(2, 1))/tau; dtau(2, 2) = 0.5*dsmooth(stress)/tau; for (unsigned i = 0 ; i < 3 ; ++i) for (unsigned j = 0 ; j < 3 ; ++j) for (unsigned k = 0 ; k < 3 ; ++k) for (unsigned l = 0 ; l < 3 ; ++l) dr_dstress(i, j, k, l) = -dtau(i, j)*dtau(k, l)/tau; // note that i explicitly symmeterise dr_dstress(0, 2, 0, 2) += 0.25/tau; dr_dstress(0, 2, 2, 0) += 0.25/tau; dr_dstress(2, 0, 0, 2) += 0.25/tau; dr_dstress(2, 0, 2, 0) += 0.25/tau; dr_dstress(1, 2, 1, 2) += 0.25/tau; dr_dstress(1, 2, 2, 1) += 0.25/tau; dr_dstress(2, 1, 1, 2) += 0.25/tau; dr_dstress(2, 1, 2, 1) += 0.25/tau; dr_dstress(2, 2, 2, 2) += 0.5*d2smooth(stress)/tau; return dr_dstress; }
void test_dsmooth_vs_dsmooth2(CuTest* tc) { float* img; float* img_orig; int nx, ny; float* smooth1; float* smooth2; float sigma; int bites; float eps; nx = 20; ny = 19; sigma = 2.0; eps = 1e-6; bites = nx * ny * sizeof(float); img = random_image(nx, ny); img_orig = calloc(bites, 1); memcpy(img_orig, img, bites); CuAssertIntEquals(tc, 0, compare_images(img, img_orig, nx, ny, 0.0)); smooth1 = calloc(bites, 1); smooth2 = calloc(bites, 1); dsmooth(img, nx, ny, sigma, smooth1); // test: don't change the input image CuAssertIntEquals(tc, 0, compare_images(img, img_orig, nx, ny, 0.0)); dsmooth2(img, nx, ny, sigma, smooth2); // test: don't change the input image CuAssertIntEquals(tc, 0, compare_images(img, img_orig, nx, ny, 0.0)); // test: dsmooth == dsmooth2 CuAssertIntEquals(tc, 0, compare_images(smooth1, smooth2, nx, ny, eps)); free(img); free(img_orig); free(smooth1); free(smooth2); }
RankTwoTensor TensorMechanicsPlasticWeakPlaneShear::df_dsig(const RankTwoTensor & stress, const Real & _tan_phi_or_psi) const { RankTwoTensor deriv; // the constructor zeroes this Real tau = std::sqrt(std::pow((stress(0,2) + stress(2,0))/2, 2) + std::pow((stress(1,2) + stress(2,1))/2, 2) + smooth(stress)); // note that i explicitly symmeterise in preparation for Cosserat if (tau == 0.0) { // the derivative is not defined here, but i want to set it nonzero // because otherwise the return direction might be too crazy deriv(0, 2) = deriv(2, 0) = 0.5; deriv(1, 2) = deriv(2, 1) = 0.5; } else { deriv(0, 2) = deriv(2, 0) = 0.25*(stress(0, 2)+stress(2,0))/tau; deriv(1, 2) = deriv(2, 1) = 0.25*(stress(1, 2)+stress(2,1))/tau; deriv(2, 2) = 0.5*dsmooth(stress)/tau; } deriv(2, 2) += _tan_phi_or_psi; return deriv; }
IDL_LONG idl_dsmooth (int argc, void * argv[]) { IDL_LONG nx,ny; float *image, *smooth, sigma; IDL_LONG i; IDL_LONG retval=1; /* 0. allocate pointers from IDL */ i=0; image=((float *)argv[i]); i++; nx=*((int *)argv[i]); i++; ny=*((int *)argv[i]); i++; sigma=*((float *)argv[i]); i++; smooth=((float *)argv[i]); i++; /* 1. run the fitting routine */ retval=(IDL_LONG) dsmooth(image, nx, ny, sigma, smooth); /* 2. free memory and leave */ free_memory(); return retval; }
RankFourTensor TensorMechanicsPlasticTensile::dflowPotential_dstress(const RankTwoTensor & stress, Real /*intnl*/) const { Real mean_stress = stress.trace() / 3.0; RankTwoTensor dmean_stress = stress.dtrace() / 3.0; Real sin3Lode = stress.sin3Lode(_lode_cutoff, 0); if (sin3Lode <= _sin3tt) { // the non-edge-smoothed version std::vector<Real> eigvals; std::vector<RankTwoTensor> deigvals; std::vector<RankFourTensor> d2eigvals; stress.dsymmetricEigenvalues(eigvals, deigvals); stress.d2symmetricEigenvalues(d2eigvals); Real denom = std::sqrt(smooth(stress) + Utility::pow<2>(eigvals[2] - mean_stress)); Real denom3 = Utility::pow<3>(denom); RankTwoTensor numer_part = deigvals[2] - dmean_stress; RankTwoTensor numer_full = 0.5 * dsmooth(stress) * dmean_stress + (eigvals[2] - mean_stress) * numer_part; Real d2smooth_over_denom = d2smooth(stress) / denom; RankFourTensor dr_dstress = (eigvals[2] - mean_stress) * d2eigvals[2] / denom; for (unsigned i = 0; i < 3; ++i) for (unsigned j = 0; j < 3; ++j) for (unsigned k = 0; k < 3; ++k) for (unsigned l = 0; l < 3; ++l) { dr_dstress(i, j, k, l) += 0.5 * d2smooth_over_denom * dmean_stress(i, j) * dmean_stress(k, l); dr_dstress(i, j, k, l) += numer_part(i, j) * numer_part(k, l) / denom; dr_dstress(i, j, k, l) -= numer_full(i, j) * numer_full(k, l) / denom3; } return dr_dstress; } else { // the edge-smoothed version RankTwoTensor dsin3Lode = stress.dsin3Lode(_lode_cutoff); Real kk = _aaa + _bbb * sin3Lode + _ccc * Utility::pow<2>(sin3Lode); RankTwoTensor dkk = (_bbb + 2.0 * _ccc * sin3Lode) * dsin3Lode; RankFourTensor d2kk = (_bbb + 2.0 * _ccc * sin3Lode) * stress.d2sin3Lode(_lode_cutoff); for (unsigned i = 0; i < 3; ++i) for (unsigned j = 0; j < 3; ++j) for (unsigned k = 0; k < 3; ++k) for (unsigned l = 0; l < 3; ++l) d2kk(i, j, k, l) += 2.0 * _ccc * dsin3Lode(i, j) * dsin3Lode(k, l); Real sibar2 = stress.secondInvariant(); RankTwoTensor dsibar2 = stress.dsecondInvariant(); RankFourTensor d2sibar2 = stress.d2secondInvariant(); Real denom = std::sqrt(smooth(stress) + sibar2 * Utility::pow<2>(kk)); Real denom3 = Utility::pow<3>(denom); Real d2smooth_over_denom = d2smooth(stress) / denom; RankTwoTensor numer_full = 0.5 * dsmooth(stress) * dmean_stress + 0.5 * dsibar2 * kk * kk + sibar2 * kk * dkk; RankFourTensor dr_dstress = (0.5 * d2sibar2 * Utility::pow<2>(kk) + sibar2 * kk * d2kk) / denom; for (unsigned i = 0; i < 3; ++i) for (unsigned j = 0; j < 3; ++j) for (unsigned k = 0; k < 3; ++k) for (unsigned l = 0; l < 3; ++l) { dr_dstress(i, j, k, l) += 0.5 * d2smooth_over_denom * dmean_stress(i, j) * dmean_stress(k, l); dr_dstress(i, j, k, l) += (dsibar2(i, j) * dkk(k, l) * kk + dkk(i, j) * dsibar2(k, l) * kk + sibar2 * dkk(i, j) * dkk(k, l)) / denom; dr_dstress(i, j, k, l) -= numer_full(i, j) * numer_full(k, l) / denom3; } return dr_dstress; } }
int main(void) { struct dirent **namelist; int i, n, N; unsigned char *image = NULL; float *image_bw_f; unsigned char *image_bw_u8; float *image_out_old; float *image_out_new; char fullpath[255]; char outpath_old[255]; char outpath_new[255]; int imW, imH; float sigma; float err; sigma = 1.0; N = scandir("demo_simplexy_images", &namelist, is_input_image, alphasort); if (N < 0) { perror("scandir"); return 1; } for (n = 0; n < N; n++) { strcpy(fullpath, "demo_simplexy_images/"); strcat(fullpath, namelist[n]->d_name); strcpy(outpath_old, "demo_simplexy_images/out_"); strcat(outpath_old, namelist[n]->d_name); outpath_old[strlen(outpath_old)-4] = '\0'; strcat(outpath_old, "_old"); strcat(outpath_old, ".png"); strcpy(outpath_new, "demo_simplexy_images/out_"); strcat(outpath_new, namelist[n]->d_name); outpath_new[strlen(outpath_new)-4] = '\0'; strcat(outpath_new, "_new"); strcat(outpath_new, ".png"); fprintf(stderr,"demo_dsmooth: loading %s ", fullpath); if (is_png(namelist[n])) { fprintf(stderr, "as a PNG\n"); image = cairoutils_read_png(fullpath, &imW, &imH); } if (is_jpeg(namelist[n])) { fprintf(stderr, "as a JPEG\n"); image = cairoutils_read_jpeg(fullpath, &imW, &imH); } image_bw_u8 = to_bw_u8(image, imW, imH); image_bw_f = malloc(sizeof(float) * imW * imH); for (i = 0; i < imW*imH; i++) { image_bw_f[i] = (float)image_bw_u8[i]; } image_out_old = malloc(sizeof(float)*imW*imH); image_out_new = malloc(sizeof(float)*imW*imH); fprintf(stderr,"demo_dsmooth: running %s through dsmooth\n", fullpath); dsmooth(image_bw_f, imW, imH, sigma, image_out_old); fprintf(stderr,"demo_dsmooth: running %s through dsmooth2\n", fullpath); dsmooth2(image_bw_f, imW, imH, sigma, image_out_new); err = 0.0; for (i = 0; i < imW*imH; i++) { err += fabs(image_out_old[i]-image_out_new[i]); } err = err / (imW*imH); fprintf(stderr, "demo_dsmooth: error between smooths: %f per pixel\n", err); // fprintf(stderr, "demo_dsmooth: writing old dsmoothed image to %s\n", outpath_old); // cairoutils_write_png(outpath_old, to_cairo_bw(image_out_old, imW, imH), imW, imH); // fprintf(stderr, "demo_dsmooth: writing new dsmoothed image to %s\n", outpath_new); // cairoutils_write_png(outpath_new, to_cairo_bw(image_out_new, imW, imH), imW, imH); free(namelist[n]); free(image); free(image_bw_f); free(image_bw_u8); free(image_out_old); free(image_out_new); } free(namelist); return 0; }