├── bar_under_tension.png ├── block_under_tension.png ├── plate_with_a_hole_fail.png ├── plate_with_a_hole_no_fail.png ├── longitudinal_bar_vibration.png ├── plate_with_a_preexisting_crack_v50.png ├── plate_with_a_preexisting_crack_v20_cl.png ├── plate_under_uniform_temperature_change.png ├── plate_with_a_preexisting_crack_no_fail.png ├── README.md ├── longitudinal_bar_vibration.m ├── bar_under_tension.m ├── plate_under_uniform_temperature_change.m ├── plate_under_tension.m ├── plate_with_a_hole_no_fail.m ├── plate_with_a_preexisting_crack_no_fail.m ├── plate_with_a_preexisting_crack_v50.m ├── plate_with_a_preexisting_crack_v20_cl.m ├── plate_with_a_hole_fail.m └── block_under_tension.m /bar_under_tension.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyzq/MatlabPeridynamicsCode/HEAD/bar_under_tension.png -------------------------------------------------------------------------------- /block_under_tension.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyzq/MatlabPeridynamicsCode/HEAD/block_under_tension.png -------------------------------------------------------------------------------- /plate_with_a_hole_fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyzq/MatlabPeridynamicsCode/HEAD/plate_with_a_hole_fail.png -------------------------------------------------------------------------------- /plate_with_a_hole_no_fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyzq/MatlabPeridynamicsCode/HEAD/plate_with_a_hole_no_fail.png -------------------------------------------------------------------------------- /longitudinal_bar_vibration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyzq/MatlabPeridynamicsCode/HEAD/longitudinal_bar_vibration.png -------------------------------------------------------------------------------- /plate_with_a_preexisting_crack_v50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyzq/MatlabPeridynamicsCode/HEAD/plate_with_a_preexisting_crack_v50.png -------------------------------------------------------------------------------- /plate_with_a_preexisting_crack_v20_cl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyzq/MatlabPeridynamicsCode/HEAD/plate_with_a_preexisting_crack_v20_cl.png -------------------------------------------------------------------------------- /plate_under_uniform_temperature_change.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyzq/MatlabPeridynamicsCode/HEAD/plate_under_uniform_temperature_change.png -------------------------------------------------------------------------------- /plate_with_a_preexisting_crack_no_fail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lazyzq/MatlabPeridynamicsCode/HEAD/plate_with_a_preexisting_crack_no_fail.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Matlab Peridynamics Code 2 | Translation of Fortran codes in book Peridynamic Theory and Its Applications (Erdogan Madenci, Erkan Oterkus) into a MATLAB version. 3 | 4 | Results are as following: 5 | ## 8.1 Longitudinal Vibration of Bar 6 | ![](longitudinal_bar_vibration.png) 7 | ## 8.2 Bar Under Tension 8 | ![](bar_under_tension.png) 9 | ## 8.3 Isotropic Plate Under Uniaxial Tension or Uniform Temperature Change 10 | ![](plate_under_uniform_temperature_change.png) 11 | ## 8.5 Block of Material Under Tension 12 | ![](block_under_tension.png) 13 | ## 9.1 Plate with a Circular Cutout Under Quasi-Static Loading 14 | ![](plate_with_a_hole_no_fail.png) 15 | ![](plate_with_a_hole_fail.png) 16 | ## 9.2 Plate with a Pre-existing Crack Under Velocity Boundary Conditions 17 | ![](plate_with_a_preexisting_crack_no_fail.png) 18 | ![](plate_with_a_preexisting_crack_v20_cl.png) 19 | ![](plate_with_a_preexisting_crack_v50.png) 20 | 21 | -------------------------------------------------------------------------------- /longitudinal_bar_vibration.m: -------------------------------------------------------------------------------- 1 | %% 2 | clear; 3 | clc; 4 | 5 | %% Specification of the locations of material points 6 | length = 1.0; 7 | % length: Total length of the bar 8 | ndivx = 1000; 9 | % ndivx: Number of divisions in x direction - except boundary region 10 | dx = length / ndivx; 11 | % dx: Spacing between material points 12 | nbnd = 3; 13 | % nbnd: Number of divisions in the boundary region 14 | totnode = ndivx + nbnd; 15 | % totnode: Total number of material points 16 | 17 | coord = zeros(totnode, 1); 18 | % coord: Material point locations 19 | 20 | nnum = 0; 21 | % nnum: Material point number 22 | 23 | % Material points of the bar 24 | for i = 1:ndivx 25 | coordx = (dx / 2.0) + (i - 1) * dx; 26 | nnum = nnum + 1; 27 | coord(nnum, 1) = coordx; 28 | end 29 | 30 | % Material points of the constrained region 31 | for i = 1:nbnd 32 | coordx = (-1.0 / 2.0 * dx) - (i - 1) * dx; 33 | nnum = nnum + 1; 34 | coord(nnum, 1) = coordx; 35 | end 36 | 37 | %% Determination of material points inside the horizon of each material point 38 | delta = 3.015 * dx; 39 | % delta: Horizon 40 | 41 | 42 | pointfam = int32(zeros(totnode, 1)); 43 | % pointfam: index array to find the family members in nodefam array 44 | numfam = int32(zeros(totnode, 1)); 45 | % numfam: Number of family members of each material point 46 | nodefam = int32(zeros(1000000, 1)); 47 | % nodefam: array containing family members of all material points 48 | 49 | for i = 1:totnode 50 | if (i == 1) 51 | pointfam(i, 1) = 1; 52 | else 53 | pointfam(i, 1) = pointfam(i - 1, 1) + numfam(i - 1, 1); 54 | end 55 | for j = 1:totnode 56 | idist = norm(coord(j, :)-coord(i, :)); 57 | if (i ~= j) 58 | if (idist <= delta) 59 | numfam(i, 1) = numfam(i, 1) + 1; 60 | nodefam(pointfam(i, 1)+numfam(i, 1)-1, 1) = j; 61 | end 62 | end 63 | end 64 | end 65 | 66 | %% Determination of surface correction factors 67 | radij = dx / 2.0; 68 | % radij: Material point radius 69 | area = dx * dx; 70 | % area: Cross-sectional area 71 | vol = area * dx; 72 | % vol: Volume of a material point 73 | 74 | dens = 7850.0; 75 | % dens: Density 76 | emod = 200.0e9; 77 | % emod: Elastic modulus 78 | bc = 2.0 * emod / (area * (delta^2)); 79 | % bc: Bond constant 80 | 81 | 82 | disp = zeros(totnode, 1); 83 | % disp: displacement of a material point 84 | stendens = zeros(totnode, 1); 85 | % stendens: strain energy of a material point 86 | fncst = ones(totnode, 1); 87 | 88 | % Loading 1 89 | sedload1 = 0.5 * emod * 1.0e-6; 90 | % sedload1: strain energy density of a material point for the first loading condition based on classical continuum mechanics 91 | 92 | for i = 1:totnode 93 | disp(i, 1) = 0.001 * coord(i, 1); 94 | end 95 | 96 | for i = 1:totnode 97 | stendens(i, 1) = 0.0; 98 | for j = 1:numfam(i, 1) 99 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 100 | idist = norm(coord(cnode, :)-coord(i, :)); 101 | nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 102 | 103 | if (idist <= delta - radij) 104 | fac = 1.0; 105 | elseif (idist <= delta + radij) 106 | fac = (delta + radij - idist) / (2.0 * radij); 107 | else 108 | fac = 0.0; 109 | end 110 | 111 | stendens(i, 1) = stendens(i, 1) + 0.5 * 0.5 * bc * ((nlength - idist) / idist)^2 * idist * vol * fac; 112 | end 113 | % Calculation of surface correction factor in x direction 114 | % by finding the ratio of the analytical strain energy density value 115 | % to the strain energy density value obtained from PD Theory 116 | fncst(i, 1) = sedload1 / stendens(i, 1); 117 | end 118 | 119 | %% Initialization of displacements and velocities 120 | vel = zeros(totnode, 1); 121 | disp = zeros(totnode, 1); 122 | 123 | %% Initial condition 124 | for i = 1:ndivx 125 | vel(i, 1) = 0.0; 126 | disp(i, 1) = 0.001 * coord(i, 1); 127 | end 128 | 129 | %% Boundary condition - Zero displacement at x = 0 130 | for i = (ndivx + 1):totnode 131 | vel(i, 1) = 0.0; 132 | disp(i, 1) = 0.0; 133 | end 134 | 135 | %% Time integration 136 | nt = 26000; 137 | % nt: Total number of time step 138 | dt = 0.8 * sqrt(2.0*dens*dx/(2.0 * delta * area * bc)); 139 | % dt: Time step size 140 | ntotrao = 20; 141 | % ntotrao: Number of terms in the summation for the analytical displacement calculation 142 | cwave = sqrt(emod/dens); 143 | % cwave: Wave speed 144 | 145 | pforce = zeros(totnode, 1); 146 | % pforce: total peridynamic force acting on a material point 147 | bforce = zeros(totnode, 1); 148 | % bforce: body load acting on a material point 149 | acc = zeros(totnode, 1); 150 | % acc: acceleration of a material point 151 | 152 | andisp = zeros(nt, 1); 153 | % andisp: analytical displacements for results 154 | pddisp = zeros(nt, 1); 155 | % pddisp: peridynamic displacements for results 156 | pdtime = zeros(nt, 1); 157 | % pdtime: time array for results 158 | 159 | for tt = 1:nt 160 | fprintf("%d/%d\n", tt, nt); 161 | ctime = tt * dt; 162 | 163 | for i = 1:ndivx 164 | pforce(i, 1) = 0.0; 165 | for j = 1:numfam(i, 1) 166 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 167 | idist = norm(coord(cnode, :)-coord(i, :)); 168 | nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 169 | 170 | % Volume correction 171 | if (idist <= delta - radij) 172 | fac = 1.0; 173 | elseif (idist <= delta + radij) 174 | fac = (delta + radij - idist) / (2.0 * radij); 175 | else 176 | fac = 0.0; 177 | end 178 | 179 | % Determination of the surface correction between two material points 180 | scr = (fncst(i, 1) + fncst(cnode, 1)) / 2.0; 181 | 182 | % Calculation of the peridynamic force in x direction 183 | % acting on a material point i due to a material point j 184 | dforce1 = bc * (nlength - idist) / idist * vol * scr * fac * (coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1)) / nlength; 185 | 186 | pforce(i, 1) = pforce(i, 1) + dforce1; 187 | end 188 | end 189 | 190 | for i = 1:ndivx 191 | acc(i, 1) = (pforce(i, 1) + bforce(i, 1)) / dens; 192 | % Calculate the acceleration of material point i 193 | vel(i, 1) = vel(i, 1) + acc(i, 1) * dt; 194 | % Calculate the displacement of material point i 195 | % by integrating the velocity of material point i 196 | disp(i, 1) = disp(i, 1) + vel(i, 1) * dt; 197 | end 198 | 199 | % Store the displacement and time information for the material point at the center 200 | % of the bar for results 201 | pddisp(tt, 1) = disp(500, 1); 202 | pdtime(tt, 1) = ctime; 203 | % Calculate the analytical displacement solution of the material point at the center 204 | % of the bar 205 | for nrao = 0:ntotrao 206 | andisp(tt, 1) = andisp(tt, 1) + ((-1.0)^(nrao)) / ((2.0 * nrao + 1.0)^2) * sin((2.0 * nrao + 1.0)*pi*coord(500, 1)/2.0) * cos((2.0 * nrao + 1.0)*pi*cwave*ctime/2.0); 207 | end 208 | andisp(tt, 1) = 8.0 * 0.001 * 1.0 / (pi^2) * andisp(tt, 1); 209 | end 210 | 211 | %% plot 212 | plot(pdtime(1:nt, 1), pddisp(1:nt, 1), pdtime(1:nt, 1), andisp(1:nt, 1)); 213 | legend("Peridynamics", "Analytical") 214 | xlabel("Tims(s)"); 215 | ylabel("Displacement(m)") -------------------------------------------------------------------------------- /bar_under_tension.m: -------------------------------------------------------------------------------- 1 | %% 2 | clear; 3 | clc; 4 | 5 | %% Specification of the locations of material points 6 | length = 1.0; 7 | % length: Total length of the bar 8 | ndivx = 1000; 9 | % ndivx: Number of divisions in x direction - except boundary region 10 | dx = length / ndivx; 11 | % dx: Spacing between material points 12 | nbnd = 3; 13 | % nbnd: Number of divisions in the boundary region 14 | totnode = ndivx + nbnd; 15 | % totnode: Total number of material points 16 | 17 | coord = zeros(totnode, 1); 18 | % coord: Material point locations 19 | 20 | nnum = 0; 21 | % nnum: Material point number 22 | 23 | % Material points of the bar 24 | for i = 1:ndivx 25 | coordx = (dx / 2.0) + (i - 1) * dx; 26 | nnum = nnum + 1; 27 | coord(nnum, 1) = coordx; 28 | end 29 | 30 | % Material points of the constrained region 31 | for i = 1:nbnd 32 | coordx = (-1.0 / 2.0 * dx) - (i - 1) * dx; 33 | nnum = nnum + 1; 34 | coord(nnum, 1) = coordx; 35 | end 36 | 37 | %% Determination of material points inside the horizon of each material point 38 | delta = 3.015 * dx; 39 | % delta: Horizon 40 | 41 | 42 | pointfam = int32(zeros(totnode, 1)); 43 | % pointfam: index array to find the family members in nodefam array 44 | numfam = int32(zeros(totnode, 1)); 45 | % numfam: Number of family members of each material point 46 | nodefam = int32(zeros(1000000, 1)); 47 | % nodefam: array containing family members of all material points 48 | 49 | for i = 1:totnode 50 | if (i == 1) 51 | pointfam(i, 1) = 1; 52 | else 53 | pointfam(i, 1) = pointfam(i - 1, 1) + numfam(i - 1, 1); 54 | end 55 | for j = 1:totnode 56 | idist = norm(coord(j, :)-coord(i, :)); 57 | if (i ~= j) 58 | if (idist <= delta) 59 | numfam(i, 1) = numfam(i, 1) + 1; 60 | nodefam(pointfam(i, 1)+numfam(i, 1)-1, 1) = j; 61 | end 62 | end 63 | end 64 | end 65 | 66 | %% Determination of surface correction factors 67 | radij = dx / 2.0; 68 | % radij: Material point radius 69 | area = dx * dx; 70 | % area: Cross-sectional area 71 | vol = area * dx; 72 | % vol: Volume of a material point 73 | 74 | dens = 7850.0; 75 | % dens: Density 76 | emod = 200.0e9; 77 | % emod: Elastic modulus 78 | bc = 2.0 * emod / (area * (delta^2)); 79 | % bc: Bond constant 80 | 81 | 82 | disp = zeros(totnode, 1); 83 | % disp: displacement of a material point 84 | stendens = zeros(totnode, 1); 85 | % stendens: strain energy of a material point 86 | fncst = ones(totnode, 1); 87 | 88 | % Loading 1 89 | sedload1 = 0.5 * emod * 1.0e-6; 90 | % sedload1: strain energy density of a material point for the first loading condition based on classical continuum mechanics 91 | 92 | for i = 1:totnode 93 | disp(i, 1) = 0.001 * coord(i, 1); 94 | end 95 | 96 | for i = 1:totnode 97 | stendens(i, 1) = 0.0; 98 | for j = 1:numfam(i, 1) 99 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 100 | idist = norm(coord(cnode, :)-coord(i, :)); 101 | nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 102 | 103 | if (idist <= delta - radij) 104 | fac = 1.0; 105 | elseif (idist <= delta + radij) 106 | fac = (delta + radij - idist) / (2.0 * radij); 107 | else 108 | fac = 0.0; 109 | end 110 | 111 | stendens(i, 1) = stendens(i, 1) + 0.5 * 0.5 * bc * ((nlength - idist) / idist)^2 * idist * vol * fac; 112 | end 113 | % Calculation of surface correction factor in x direction 114 | % by finding the ratio of the analytical strain energy density value 115 | % to the strain energy density value obtained from PD Theory 116 | fncst(i, 1) = sedload1 / stendens(i, 1); 117 | end 118 | 119 | %% Initialization of displacements and velocities 120 | vel = zeros(totnode, 1); 121 | disp = zeros(totnode, 1); 122 | 123 | %% Stable mass vector computation 124 | dt = 1.0; 125 | % dt: Time interval 126 | 127 | massvec = zeros(totnode, 1); 128 | % massvec: massvector for adaptive dynamic relaxation 129 | 130 | for i = 1:totnode 131 | massvec(i, 1) = 0.25 * dt * dt * (2.0 * area * delta) * bc / dx * 5.0; 132 | end 133 | 134 | %% Applied loading 135 | appres = 200.0e6; 136 | % appres: Applied pressure 137 | 138 | bforce = zeros(totnode, 1); 139 | % bforce: body load acting on a material point 140 | 141 | bforce(ndivx, 1) = appres / (dx); 142 | 143 | %% Boundary condition - Constrained region 144 | for i = (ndivx + 1):totnode 145 | vel(i, 1) = 0.0; 146 | disp(i, 1) = 0.0; 147 | end 148 | 149 | %% Time integration 150 | nt = 10000; 151 | % nt: Total number of time step 152 | 153 | pforce = zeros(totnode, 1); 154 | % pforce: total peridynamic force acting on a material point 155 | pforceold = zeros(totnode, 1); 156 | % pforce: total peridynamic force acting on a material point 157 | acc = zeros(totnode, 1); 158 | % acc: acceleration of a material point 159 | 160 | velhalf = zeros(totnode, 1); 161 | velhalfold = zeros(totnode, 1); 162 | % vel: velocity of a material point 163 | 164 | coord_disp_pd_nt = zeros(ndivx, 3); 165 | % Peridynamic displacement and Analytical displacement of all points at time step of nt 166 | center_node = zeros(nt, 2); 167 | % Peridynamic displacement at center node of all time step. 168 | cn = 0.0; 169 | cn1 = 0.0; 170 | cn2 = 0.0; 171 | for tt = 1:nt 172 | fprintf("%d/%d\n", tt, nt); 173 | 174 | for i = 1:totnode 175 | pforce(i, 1) = 0.0; 176 | for j = 1:numfam(i, 1) 177 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 178 | idist = norm(coord(cnode, :)-coord(i, :)); 179 | nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 180 | 181 | % Volume correction 182 | if (idist <= delta - radij) 183 | fac = 1.0; 184 | elseif (idist <= delta + radij) 185 | fac = (delta + radij - idist) / (2.0 * radij); 186 | else 187 | fac = 0.0; 188 | end 189 | 190 | % Determination of the surface correction between two material points 191 | scr = (fncst(i, 1) + fncst(cnode, 1)) / 2.0; 192 | 193 | % Calculation of the peridynamic force in x direction 194 | % acting on a material point i due to a material point j 195 | dforce1 = bc * (nlength - idist) / idist * vol * scr * fac * (coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1)) / nlength; 196 | 197 | pforce(i, 1) = pforce(i, 1) + dforce1; 198 | end 199 | end 200 | 201 | % Adaptive dynamic relaxation ⬇⬇⬇ 202 | 203 | for i = 1:ndivx 204 | if (velhalfold(i, 1) ~= 0.0) 205 | cn1 = cn1 - disp(i, 1) * disp(i, 1) * (pforce(i, 1) / massvec(i, 1) - pforceold(i, 1) / massvec(i, 1)) / (dt * velhalfold(i, 1)); 206 | end 207 | cn2 = cn2 + disp(i, 1) * disp(i, 1); 208 | end 209 | 210 | if (cn2 ~= 0.0) 211 | if ((cn1 / cn2) > 0.0) 212 | cn = 2.0 * sqrt(cn1/cn2); 213 | else 214 | cn = 0.0; 215 | end 216 | else 217 | cn = 0.0; 218 | end 219 | 220 | if (cn > 2.0) 221 | cn = 1.9; 222 | end 223 | 224 | for i = 1:ndivx 225 | % Integrate acceleration over time. 226 | if (tt == 1) 227 | velhalf(i, 1) = 1.0 * dt / massvec(i, 1) * (pforce(i, 1) + bforce(i, 1)) / 2.0; 228 | else 229 | velhalf(i, 1) = ((2.0 - cn * dt) * velhalfold(i, 1) + 2.0 * dt / massvec(i, 1) * (pforce(i, 1) + bforce(i, 1))) / (2.0 + cn * dt); 230 | end 231 | 232 | vel(i, 1) = 0.5 * (velhalfold(i, 1) + velhalf(i, 1)); 233 | disp(i, 1) = disp(i, 1) + velhalf(i, 1) * dt; 234 | 235 | velhalfold(i, 1) = velhalf(i, 1); 236 | pforceold(i, 1) = pforce(i, 1); 237 | end 238 | 239 | % Adaptive dynamic relaxation ⬆⬆⬆ 240 | 241 | if (tt == nt) 242 | for i = 1:ndivx 243 | coord_disp_pd_nt(i, 1:3) = [coord(i, 1), disp(i, 1), 0.001 * coord(i, 1)]; 244 | end 245 | end 246 | 247 | center_node(tt, 1:2) = [tt, disp(500, 1)]; 248 | end 249 | 250 | %% plot 251 | subplot(121) 252 | plot(center_node(:, 1), center_node(:, 2)); 253 | subplot(122) 254 | hold on; 255 | plot(coord_disp_pd_nt(:, 1), coord_disp_pd_nt(:, 2)); 256 | plot(coord_disp_pd_nt(:, 1), coord_disp_pd_nt(:, 3)); 257 | legend("Peridynamics", "Analytical"); 258 | hold off; -------------------------------------------------------------------------------- /plate_under_uniform_temperature_change.m: -------------------------------------------------------------------------------- 1 | %% 2 | clear; 3 | clc; 4 | 5 | %% Specification of the locations of material points 6 | length = 1.0; 7 | % length: Total length of the bar 8 | width = 0.5; 9 | % width: Total width of the plate 10 | ndivx = 100; 11 | % ndivx: Number of divisions in x direction - except boundary region 12 | ndivy = 50; 13 | % ndivy: Number of divisions in y direction - except boundary region 14 | dx = length / ndivx; 15 | % dx: Spacing between material points 16 | nbnd = 0; 17 | % nbnd: Number of divisions in the boundary region 18 | totnode = ndivx * ndivy; 19 | % totnode: Total number of material points 20 | 21 | coord = zeros(totnode, 2); 22 | % coord: Material point locations 23 | 24 | nnum = 0; 25 | % nnum: Material point number 26 | 27 | % Material points of the plate 28 | for i = 1:ndivx 29 | for j = 1:ndivy 30 | coordx = -1.0 / 2.0 * length + (dx / 2.0) + (i - 1) * dx; 31 | coordy = -1.0 / 2.0 * width + (dx / 2.0) + (j - 1) * dx; 32 | nnum = nnum + 1; 33 | coord(nnum, 1) = coordx; 34 | coord(nnum, 2) = coordy; 35 | end 36 | end 37 | 38 | %% Determination of material points inside the horizon of each material point 39 | delta = 3.015 * dx; 40 | % delta: Horizon 41 | 42 | pointfam = int32(zeros(totnode, 1)); 43 | % pointfam: index array to find the family members in nodefam array 44 | numfam = int32(zeros(totnode, 1)); 45 | % numfam: Number of family members of each material point 46 | nodefam = int32(zeros(1000000, 1)); 47 | % nodefam: array containing family members of all material points 48 | 49 | for i = 1:totnode 50 | if (i == 1) 51 | pointfam(i, 1) = 1; 52 | else 53 | pointfam(i, 1) = pointfam(i - 1, 1) + numfam(i - 1, 1); 54 | end 55 | for j = 1:totnode 56 | % idist = norm(coord(j, :)-coord(i, :)); 57 | idist = sqrt((coord(j, 1) - coord(i, 1))^2+(coord(j, 2) - coord(i, 2))^2); 58 | if (i ~= j) 59 | if (idist <= delta) 60 | numfam(i, 1) = numfam(i, 1) + 1; 61 | nodefam(pointfam(i, 1)+numfam(i, 1)-1, 1) = j; 62 | end 63 | end 64 | end 65 | end 66 | 67 | %% Determination of surface correction factors 68 | radij = dx / 2.0; 69 | % radij: Material point radius 70 | area = dx * dx; 71 | % area: Cross-sectional area 72 | vol = area * dx; 73 | % vol: Volume of a material point 74 | thick = dx; 75 | % thick: Total thickness of the plate 76 | 77 | dens = 7850.0; 78 | % dens: Density 79 | emod = 200.0e9; 80 | % emod: Elastic modulus 81 | bc = 9.0 * emod / (pi * thick * (delta^3)); 82 | % bc: Bond constant 83 | 84 | disp = zeros(totnode, 2); 85 | % disp: displacement of a material point 86 | stendens = zeros(totnode, 2); 87 | % stendens: strain energy of a material point 88 | fncst = ones(totnode, 2); 89 | % fncst: surface correction factors of a material point, 1:loading 1, 2:loading 2 90 | 91 | % Loading 1 92 | sedload1 = 9.0 / 16.0 * emod * 1.0e-6; 93 | % sedload1: strain energy density of a material point for the first loading condition based on classical continuum mechanics 94 | 95 | for i = 1:totnode 96 | disp(i, 1) = 0.001 * coord(i, 1); 97 | disp(i, 2) = 0.0; 98 | end 99 | 100 | for i = 1:totnode 101 | stendens(i, 1) = 0.0; 102 | for j = 1:numfam(i, 1) 103 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 104 | % idist = norm(coord(cnode, :)-coord(i, :)); 105 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 106 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2); 107 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2); 108 | 109 | if (idist <= delta - radij) 110 | fac = 1.0; 111 | elseif (idist <= delta + radij) 112 | fac = (delta + radij - idist) / (2.0 * radij); 113 | else 114 | fac = 0.0; 115 | end 116 | 117 | stendens(i, 1) = stendens(i, 1) + 0.5 * 0.5 * bc * ((nlength - idist) / idist)^2 * idist * vol * fac; 118 | end 119 | % Calculation of surface correction factor in x direction 120 | % by finding the ratio of the analytical strain energy density value 121 | % to the strain energy density value obtained from PD Theory 122 | fncst(i, 1) = sedload1 / stendens(i, 1); 123 | end 124 | 125 | % Loading 2 126 | sedload2 = 9.0 / 16.0 * emod * 1.0e-6; 127 | % sedload2: strain energy density of a material point for the second loading condition based on classical continuum mechanics 128 | 129 | for i = 1:totnode 130 | disp(i, 1) = 0.0; 131 | disp(i, 2) = 0.001 * coord(i, 2); 132 | end 133 | 134 | for i = 1:totnode 135 | stendens(i, 2) = 0.0; 136 | for j = 1:numfam(i, 1) 137 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 138 | % idist = norm(coord(cnode, :)-coord(i, :)); 139 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 140 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2); 141 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2); 142 | 143 | if (idist <= delta - radij) 144 | fac = 1.0; 145 | elseif (idist <= delta + radij) 146 | fac = (delta + radij - idist) / (2.0 * radij); 147 | else 148 | fac = 0.0; 149 | end 150 | 151 | stendens(i, 2) = stendens(i, 2) + 0.5 * 0.5 * bc * ((nlength - idist) / idist)^2 * idist * vol * fac; 152 | end 153 | % Calculation of surface correction factor in x direction 154 | % by finding the ratio of the analytical strain energy density value 155 | % to the strain energy density value obtained from PD Theory 156 | fncst(i, 2) = sedload2 / stendens(i, 2); 157 | end 158 | 159 | %% Initialization of displacements and velocities 160 | vel = zeros(totnode, 2); 161 | disp = zeros(totnode, 2); 162 | 163 | %% Stable mass vector computation 164 | dt = 1.0; 165 | % dt: Time interval 166 | 167 | massvec = zeros(totnode, 2); 168 | % massvec: massvector for adaptive dynamic relaxation 169 | 170 | for i = 1:totnode 171 | % 5 is a safety factor 172 | massvec(i, 1) = 0.25 * dt * dt * (pi * (delta)^2 * thick) * bc / dx * 5.0; 173 | massvec(i, 2) = 0.25 * dt * dt * (pi * (delta)^2 * thick) * bc / dx * 5.0; 174 | end 175 | 176 | %% Applied loading 177 | % appres = 200.0e6; 178 | % % appres: Applied pressure 179 | 180 | bforce = zeros(totnode, 2); 181 | % bforce: body load acting on a material point 182 | 183 | %% Time integration 184 | nt = 4000; 185 | % nt: Total number of time step 186 | alpha = 23.0e-6; 187 | % alpha: Coefficient of thermal expansion 188 | dtemp = 50.0; 189 | % dtemp: Temperature change 190 | pratio = 1.0 / 3.0; 191 | % pratio: Poisson's ratio 192 | 193 | pforce = zeros(totnode, 2); 194 | % pforce: total peridynamic force acting on a material point 195 | pforceold = zeros(totnode, 2); 196 | % pforceold: total peridynamic force acting on a material point in the previous time step 1:x-coord, 2:y-coord 197 | acc = zeros(totnode, 2); 198 | % acc: acceleration of a material point 199 | 200 | velhalf = zeros(totnode, 2); 201 | velhalfold = zeros(totnode, 2); 202 | % vel: velocity of a material point 203 | 204 | coord_disp_pd_nt = zeros(ndivx*ndivy, 4); 205 | % Peridynamic displacement and Analytical displacement of all points at time step of nt 206 | horiCnt = 0; 207 | horizontal_disps = zeros(ndivx, 6); 208 | % Peridynamic displacement and Analytical displacement of points at y = 0; 209 | vertiCnt = 0; 210 | vertical_disps = zeros(ndivy, 6); 211 | % Peridynamic displacement and Analytical displacement of points at x = 0; 212 | steady_check = zeros(nt, 3); 213 | 214 | cn = 0.0; 215 | cn1 = 0.0; 216 | cn2 = 0.0; 217 | for tt = 1:nt 218 | fprintf("%d/%d\n", tt, nt); 219 | 220 | for i = 1:totnode 221 | pforce(i, 1) = 0.0; 222 | pforce(i, 2) = 0.0; 223 | for j = 1:numfam(i, 1) 224 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 225 | % idist = norm(coord(cnode, :)-coord(i, :)); 226 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 227 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2); 228 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2); 229 | 230 | % Volume correction 231 | if (idist <= delta - radij) 232 | fac = 1.0; 233 | elseif (idist <= delta + radij) 234 | fac = (delta + radij - idist) / (2.0 * radij); 235 | else 236 | fac = 0.0; 237 | end 238 | 239 | % Determination of the surface correction between two material points 240 | if (abs(coord(cnode, 2)-coord(i, 2)) <= 1.0e-10) 241 | theta = 0.0; 242 | elseif (abs(coord(cnode, 1)-coord(i, 1)) <= 1.0e-10) 243 | theta = 90.0 * pi / 180.0; 244 | else 245 | theta = atan(abs(coord(cnode, 2)-coord(i, 2))/abs(coord(cnode, 1)-coord(i, 1))); 246 | end 247 | scx = (fncst(i, 1) + fncst(cnode, 1)) / 2.0; 248 | scy = (fncst(i, 2) + fncst(cnode, 2)) / 2.0; 249 | scr = 1.0 / (((cos(theta))^2.0 / (scx)^2.0) + ((sin(theta))^2.0 / (scy)^2.0)); 250 | scr = sqrt(scr); 251 | 252 | % Calculation of the peridynamic force in x direction acting on a material point i due to a material point j 253 | dforce1 = bc * ((nlength - idist) / idist - (alpha * dtemp)) * vol * scr * fac * (coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1)) / nlength; 254 | dforce2 = bc * ((nlength - idist) / idist - (alpha * dtemp)) * vol * scr * fac * (coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2)) / nlength; 255 | 256 | pforce(i, 1) = pforce(i, 1) + dforce1; 257 | pforce(i, 2) = pforce(i, 2) + dforce2; 258 | end 259 | end 260 | 261 | % Adaptive dynamic relaxation ⬇⬇⬇ 262 | 263 | for i = 1:totnode 264 | if (velhalfold(i, 1) ~= 0.0) 265 | cn1 = cn1 - disp(i, 1) * disp(i, 1) * (pforce(i, 1) / massvec(i, 1) - pforceold(i, 1) / massvec(i, 1)) / (dt * velhalfold(i, 1)); 266 | end 267 | if (velhalfold(i, 2) ~= 0.0) 268 | cn1 = cn1 - disp(i, 2) * disp(i, 2) * (pforce(i, 2) / massvec(i, 2) - pforceold(i, 2) / massvec(i, 2)) / (dt * velhalfold(i, 2)); 269 | end 270 | cn2 = cn2 + disp(i, 1) * disp(i, 1); 271 | cn2 = cn2 + disp(i, 2) * disp(i, 2); 272 | end 273 | 274 | if (cn2 ~= 0.0) 275 | if ((cn1 / cn2) > 0.0) 276 | cn = 2.0 * sqrt(cn1/cn2); 277 | else 278 | cn = 0.0; 279 | end 280 | else 281 | cn = 0.0; 282 | end 283 | 284 | if (cn > 2.0) 285 | cn = 1.9; 286 | end 287 | 288 | for i = 1:totnode 289 | % Integrate acceleration over time. 290 | if (tt == 1) 291 | velhalf(i, 1) = 1.0 * dt / massvec(i, 1) * (pforce(i, 1) + bforce(i, 1)) / 2.0; 292 | velhalf(i, 2) = 1.0 * dt / massvec(i, 2) * (pforce(i, 2) + bforce(i, 2)) / 2.0; 293 | else 294 | velhalf(i, 1) = ((2.0 - cn * dt) * velhalfold(i, 1) + 2.0 * dt / massvec(i, 1) * (pforce(i, 1) + bforce(i, 1))) / (2.0 + cn * dt); 295 | velhalf(i, 2) = ((2.0 - cn * dt) * velhalfold(i, 2) + 2.0 * dt / massvec(i, 2) * (pforce(i, 2) + bforce(i, 2))) / (2.0 + cn * dt); 296 | end 297 | 298 | vel(i, 1) = 0.5 * (velhalfold(i, 1) + velhalf(i, 1)); 299 | vel(i, 2) = 0.5 * (velhalfold(i, 2) + velhalf(i, 2)); 300 | disp(i, 1) = disp(i, 1) + velhalf(i, 1) * dt; 301 | disp(i, 2) = disp(i, 2) + velhalf(i, 2) * dt; 302 | 303 | velhalfold(i, 1) = velhalf(i, 1); 304 | velhalfold(i, 2) = velhalf(i, 2); 305 | pforceold(i, 1) = pforce(i, 1); 306 | pforceold(i, 2) = pforce(i, 2); 307 | end 308 | 309 | % Adaptive dynamic relaxation ⬆⬆⬆ 310 | 311 | if (tt == nt) 312 | for i = 1:(ndivx * ndivy) 313 | coord_disp_pd_nt(i, 1:4) = [coord(i, 1), coord(i, 2), disp(i, 1), disp(i, 2)]; 314 | if (abs(coord(i, 2)-(dx / 2.0)) <= 1.0e-8) 315 | horiCnt = horiCnt + 1; 316 | horizontal_disps(horiCnt, 1:6) = [coord(i, 1), coord(i, 2), disp(i, 1), disp(i, 2), alpha * dtemp * coord(i, 1), alpha * dtemp * coord(i, 2)]; 317 | end 318 | if (abs(coord(i, 1)-(dx / 2.0)) <= 1.0e-8) 319 | vertiCnt = vertiCnt + 1; 320 | vertical_disps(vertiCnt, 1:6) = [coord(i, 1), coord(i, 2), disp(i, 1), disp(i, 2), alpha * dtemp * coord(i, 1), alpha * dtemp * coord(i, 2)]; 321 | end 322 | end 323 | end 324 | 325 | steady_check(tt, 1:3) = [tt, disp(3788, 1), disp(3788, 2)]; 326 | end 327 | 328 | %% plot 329 | colormap jet; 330 | subplot(221) 331 | scale = 500; 332 | scatter(coord_disp_pd_nt(:, 1)+scale*coord_disp_pd_nt(:, 3), coord_disp_pd_nt(:, 2)+scale*coord_disp_pd_nt(:, 4), [], sqrt(coord_disp_pd_nt(:, 3).^2+coord_disp_pd_nt(:, 4).^2), "filled") 333 | subplot(222) 334 | plot(steady_check(:, 1), steady_check(:, 2), steady_check(:, 1), steady_check(:, 3)) 335 | subplot(223) 336 | plot(horizontal_disps(:, 1), horizontal_disps(:, 3), horizontal_disps(:, 1), horizontal_disps(:, 5)) 337 | legend('Peridynamics', 'Analytical'); 338 | subplot(224) 339 | plot(vertical_disps(:, 2), vertical_disps(:, 4), vertical_disps(:, 2), vertical_disps(:, 6)) 340 | legend('Peridynamics', 'Analytical'); 341 | -------------------------------------------------------------------------------- /plate_under_tension.m: -------------------------------------------------------------------------------- 1 | %% 2 | clear; 3 | clc; 4 | 5 | %% Specification of the locations of material points 6 | length = 1.0; 7 | % length: Total length of the bar 8 | width = 0.5; 9 | % width: Total width of the plate 10 | ndivx = 100; 11 | % ndivx: Number of divisions in x direction - except boundary region 12 | ndivy = 50; 13 | % ndivy: Number of divisions in y direction - except boundary region 14 | dx = length / ndivx; 15 | % dx: Spacing between material points 16 | nbnd = 0; 17 | % nbnd: Number of divisions in the boundary region 18 | totnode = ndivx * ndivy; 19 | % totnode: Total number of material points 20 | 21 | coord = zeros(totnode, 2); 22 | % coord: Material point locations 23 | 24 | nnum = 0; 25 | % nnum: Material point number 26 | 27 | % Material points of the plate 28 | for i = 1:ndivx 29 | for j = 1:ndivy 30 | coordx = -1.0 / 2.0 * length + (dx / 2.0) + (i - 1) * dx; 31 | coordy = -1.0 / 2.0 * width + (dx / 2.0) + (j - 1) * dx; 32 | nnum = nnum + 1; 33 | coord(nnum, 1) = coordx; 34 | coord(nnum, 2) = coordy; 35 | end 36 | end 37 | 38 | %% Determination of material points inside the horizon of each material point 39 | delta = 3.015 * dx; 40 | % delta: Horizon 41 | 42 | pointfam = int32(zeros(totnode, 1)); 43 | % pointfam: index array to find the family members in nodefam array 44 | numfam = int32(zeros(totnode, 1)); 45 | % numfam: Number of family members of each material point 46 | nodefam = int32(zeros(1000000, 1)); 47 | % nodefam: array containing family members of all material points 48 | 49 | for i = 1:totnode 50 | if (i == 1) 51 | pointfam(i, 1) = 1; 52 | else 53 | pointfam(i, 1) = pointfam(i - 1, 1) + numfam(i - 1, 1); 54 | end 55 | for j = 1:totnode 56 | % idist = norm(coord(j, :)-coord(i, :)); 57 | idist = sqrt((coord(j, 1) - coord(i, 1))^2+(coord(j, 2) - coord(i, 2))^2); 58 | if (i ~= j) 59 | if (idist <= delta) 60 | numfam(i, 1) = numfam(i, 1) + 1; 61 | nodefam(pointfam(i, 1)+numfam(i, 1)-1, 1) = j; 62 | end 63 | end 64 | end 65 | end 66 | 67 | %% Determination of surface correction factors 68 | radij = dx / 2.0; 69 | % radij: Material point radius 70 | area = dx * dx; 71 | % area: Cross-sectional area 72 | vol = area * dx; 73 | % vol: Volume of a material point 74 | thick = dx; 75 | % thick: Total thickness of the plate 76 | 77 | dens = 7850.0; 78 | % dens: Density 79 | emod = 200.0e9; 80 | % emod: Elastic modulus 81 | bc = 9.0 * emod / (pi * thick * (delta^3)); 82 | % bc: Bond constant 83 | 84 | disp = zeros(totnode, 2); 85 | % disp: displacement of a material point 86 | stendens = zeros(totnode, 2); 87 | % stendens: strain energy of a material point 88 | fncst = ones(totnode, 2); 89 | % fncst: surface correction factors of a material point, 1:loading 1, 2:loading 2 90 | 91 | % Loading 1 92 | sedload1 = 9.0 / 16.0 * emod * 1.0e-6; 93 | % sedload1: strain energy density of a material point for the first loading condition based on classical continuum mechanics 94 | 95 | for i = 1:totnode 96 | disp(i, 1) = 0.001 * coord(i, 1); 97 | disp(i, 2) = 0.0; 98 | end 99 | 100 | for i = 1:totnode 101 | stendens(i, 1) = 0.0; 102 | for j = 1:numfam(i, 1) 103 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 104 | % idist = norm(coord(cnode, :)-coord(i, :)); 105 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 106 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2); 107 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2); 108 | 109 | if (idist <= delta - radij) 110 | fac = 1.0; 111 | elseif (idist <= delta + radij) 112 | fac = (delta + radij - idist) / (2.0 * radij); 113 | else 114 | fac = 0.0; 115 | end 116 | 117 | stendens(i, 1) = stendens(i, 1) + 0.5 * 0.5 * bc * ((nlength - idist) / idist)^2 * idist * vol * fac; 118 | end 119 | % Calculation of surface correction factor in x direction 120 | % by finding the ratio of the analytical strain energy density value 121 | % to the strain energy density value obtained from PD Theory 122 | fncst(i, 1) = sedload1 / stendens(i, 1); 123 | end 124 | 125 | % Loading 2 126 | sedload2 = 9.0 / 16.0 * emod * 1.0e-6; 127 | % sedload2: strain energy density of a material point for the second loading condition based on classical continuum mechanics 128 | 129 | for i = 1:totnode 130 | disp(i, 1) = 0.0; 131 | disp(i, 2) = 0.001 * coord(i, 2); 132 | end 133 | 134 | for i = 1:totnode 135 | stendens(i, 2) = 0.0; 136 | for j = 1:numfam(i, 1) 137 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 138 | % idist = norm(coord(cnode, :)-coord(i, :)); 139 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 140 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2); 141 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2); 142 | 143 | if (idist <= delta - radij) 144 | fac = 1.0; 145 | elseif (idist <= delta + radij) 146 | fac = (delta + radij - idist) / (2.0 * radij); 147 | else 148 | fac = 0.0; 149 | end 150 | 151 | stendens(i, 2) = stendens(i, 2) + 0.5 * 0.5 * bc * ((nlength - idist) / idist)^2 * idist * vol * fac; 152 | end 153 | % Calculation of surface correction factor in x direction 154 | % by finding the ratio of the analytical strain energy density value 155 | % to the strain energy density value obtained from PD Theory 156 | fncst(i, 2) = sedload2 / stendens(i, 2); 157 | end 158 | 159 | %% Initialization of displacements and velocities 160 | vel = zeros(totnode, 2); 161 | disp = zeros(totnode, 2); 162 | 163 | %% Stable mass vector computation 164 | dt = 1.0; 165 | % dt: Time interval 166 | 167 | massvec = zeros(totnode, 2); 168 | % massvec: massvector for adaptive dynamic relaxation 169 | 170 | for i = 1:totnode 171 | % 5 is a safety factor 172 | massvec(i, 1) = 0.25 * dt * dt * (pi * (delta)^2 * thick) * bc / dx * 5.0; 173 | massvec(i, 2) = 0.25 * dt * dt * (pi * (delta)^2 * thick) * bc / dx * 5.0; 174 | end 175 | 176 | %% Applied loading - Left and Right 177 | appres = 200.0e6; 178 | % appres: Applied pressure 179 | 180 | bforce = zeros(totnode, 2); 181 | % bforce: body load acting on a material point 182 | 183 | % left 184 | for i = 1:ndivy 185 | bforce(i, 1) = -1.0 * appres / (dx); 186 | end 187 | 188 | % right 189 | for i = (totnode - ndivy + 1):totnode 190 | bforce(i, 1) = appres / (dx); 191 | end 192 | 193 | %% Time integration 194 | nt = 1000; 195 | % nt: Total number of time step 196 | alpha = 23.0e-6; 197 | % alpha: Coefficient of thermal expansion 198 | dtemp = 0.0; 199 | % dtemp: Temperature change 200 | pratio = 1.0 / 3.0; 201 | % pratio: Poisson's ratio 202 | 203 | pforce = zeros(totnode, 2); 204 | % pforce: total peridynamic force acting on a material point 205 | pforceold = zeros(totnode, 2); 206 | % pforceold: total peridynamic force acting on a material point in the previous time step 1:x-coord, 2:y-coord 207 | acc = zeros(totnode, 2); 208 | % acc: acceleration of a material point 209 | 210 | velhalf = zeros(totnode, 2); 211 | velhalfold = zeros(totnode, 2); 212 | % vel: velocity of a material point 213 | 214 | coord_disp_pd_nt = zeros(ndivx*ndivy, 4); 215 | % Peridynamic displacement and Analytical displacement of all points at time step of nt 216 | horiCnt = 0; 217 | horizontal_disps = zeros(ndivx, 6); 218 | % Peridynamic displacement and Analytical displacement of points at y = 0; 219 | vertiCnt = 0; 220 | vertical_disps = zeros(ndivy, 6); 221 | % Peridynamic displacement and Analytical displacement of points at x = 0; 222 | steady_check = zeros(nt, 3); 223 | 224 | cn = 0.0; 225 | cn1 = 0.0; 226 | cn2 = 0.0; 227 | for tt = 1:nt 228 | fprintf("%d/%d\n", tt, nt); 229 | 230 | for i = 1:totnode 231 | pforce(i, 1) = 0.0; 232 | pforce(i, 2) = 0.0; 233 | for j = 1:numfam(i, 1) 234 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 235 | % idist = norm(coord(cnode, :)-coord(i, :)); 236 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 237 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2); 238 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2); 239 | 240 | % Volume correction 241 | if (idist <= delta - radij) 242 | fac = 1.0; 243 | elseif (idist <= delta + radij) 244 | fac = (delta + radij - idist) / (2.0 * radij); 245 | else 246 | fac = 0.0; 247 | end 248 | 249 | % Determination of the surface correction between two material points 250 | if (abs(coord(cnode, 2)-coord(i, 2)) <= 1.0e-10) 251 | theta = 0.0; 252 | elseif (abs(coord(cnode, 1)-coord(i, 1)) <= 1.0e-10) 253 | theta = 90.0 * pi / 180.0; 254 | else 255 | theta = atan(abs(coord(cnode, 2)-coord(i, 2))/abs(coord(cnode, 1)-coord(i, 1))); 256 | end 257 | scx = (fncst(i, 1) + fncst(cnode, 1)) / 2.0; 258 | scy = (fncst(i, 2) + fncst(cnode, 2)) / 2.0; 259 | scr = 1.0 / (((cos(theta))^2.0 / (scx)^2.0) + ((sin(theta))^2.0 / (scy)^2.0)); 260 | scr = sqrt(scr); 261 | 262 | % Calculation of the peridynamic force in x direction acting on a material point i due to a material point j 263 | dforce1 = bc * ((nlength - idist) / idist - (alpha * dtemp)) * vol * scr * fac * (coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1)) / nlength; 264 | dforce2 = bc * ((nlength - idist) / idist - (alpha * dtemp)) * vol * scr * fac * (coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2)) / nlength; 265 | 266 | pforce(i, 1) = pforce(i, 1) + dforce1; 267 | pforce(i, 2) = pforce(i, 2) + dforce2; 268 | end 269 | end 270 | 271 | % Adaptive dynamic relaxation ⬇⬇⬇ 272 | 273 | for i = 1:totnode 274 | if (velhalfold(i, 1) ~= 0.0) 275 | cn1 = cn1 - disp(i, 1) * disp(i, 1) * (pforce(i, 1) / massvec(i, 1) - pforceold(i, 1) / massvec(i, 1)) / (dt * velhalfold(i, 1)); 276 | end 277 | if (velhalfold(i, 2) ~= 0.0) 278 | cn1 = cn1 - disp(i, 2) * disp(i, 2) * (pforce(i, 2) / massvec(i, 2) - pforceold(i, 2) / massvec(i, 2)) / (dt * velhalfold(i, 2)); 279 | end 280 | cn2 = cn2 + disp(i, 1) * disp(i, 1); 281 | cn2 = cn2 + disp(i, 2) * disp(i, 2); 282 | end 283 | 284 | if (cn2 ~= 0.0) 285 | if ((cn1 / cn2) > 0.0) 286 | cn = 2.0 * sqrt(cn1/cn2); 287 | else 288 | cn = 0.0; 289 | end 290 | else 291 | cn = 0.0; 292 | end 293 | 294 | if (cn > 2.0) 295 | cn = 1.9; 296 | end 297 | 298 | for i = 1:totnode 299 | % Integrate acceleration over time. 300 | if (tt == 1) 301 | velhalf(i, 1) = 1.0 * dt / massvec(i, 1) * (pforce(i, 1) + bforce(i, 1)) / 2.0; 302 | velhalf(i, 2) = 1.0 * dt / massvec(i, 2) * (pforce(i, 2) + bforce(i, 2)) / 2.0; 303 | else 304 | velhalf(i, 1) = ((2.0 - cn * dt) * velhalfold(i, 1) + 2.0 * dt / massvec(i, 1) * (pforce(i, 1) + bforce(i, 1))) / (2.0 + cn * dt); 305 | velhalf(i, 2) = ((2.0 - cn * dt) * velhalfold(i, 2) + 2.0 * dt / massvec(i, 2) * (pforce(i, 2) + bforce(i, 2))) / (2.0 + cn * dt); 306 | end 307 | 308 | vel(i, 1) = 0.5 * (velhalfold(i, 1) + velhalf(i, 1)); 309 | vel(i, 2) = 0.5 * (velhalfold(i, 2) + velhalf(i, 2)); 310 | disp(i, 1) = disp(i, 1) + velhalf(i, 1) * dt; 311 | disp(i, 2) = disp(i, 2) + velhalf(i, 2) * dt; 312 | 313 | velhalfold(i, 1) = velhalf(i, 1); 314 | velhalfold(i, 2) = velhalf(i, 2); 315 | pforceold(i, 1) = pforce(i, 1); 316 | pforceold(i, 2) = pforce(i, 2); 317 | end 318 | 319 | % Adaptive dynamic relaxation ⬆⬆⬆ 320 | 321 | if (tt == nt) 322 | for i = 1:(ndivx * ndivy) 323 | coord_disp_pd_nt(i, 1:4) = [coord(i, 1), coord(i, 2), disp(i, 1), disp(i, 2)]; 324 | if (abs(coord(i, 2)-(dx / 2.0)) <= 1.0e-8) 325 | horiCnt = horiCnt + 1; 326 | horizontal_disps(horiCnt, 1:6) = [coord(i, 1), coord(i, 2), disp(i, 1), disp(i, 2), 0.001 * coord(i, 1), -1.0 * 0.001 * pratio * coord(i, 2)]; 327 | end 328 | if (abs(coord(i, 1)-(dx / 2.0)) <= 1.0e-8) 329 | vertiCnt = vertiCnt + 1; 330 | vertical_disps(vertiCnt, 1:6) = [coord(i, 1), coord(i, 2), disp(i, 1), disp(i, 2), 0.001 * coord(i, 1), -1.0 * 0.001 * pratio * coord(i, 2)]; 331 | end 332 | end 333 | end 334 | 335 | steady_check(tt, 1:3) = [tt, disp(3788, 1), disp(3788, 2)]; 336 | end 337 | 338 | %% plot 339 | colormap jet; 340 | subplot(221) 341 | scale = 500; 342 | scatter(coord_disp_pd_nt(:, 1)+scale*coord_disp_pd_nt(:, 3), coord_disp_pd_nt(:, 2)+scale*coord_disp_pd_nt(:, 4), [], sqrt(coord_disp_pd_nt(:, 3).^2+coord_disp_pd_nt(:, 4).^2), "filled") 343 | subplot(222) 344 | plot(steady_check(:, 1), steady_check(:, 2), steady_check(:, 1), steady_check(:, 3)) 345 | subplot(223) 346 | plot(horizontal_disps(:, 1), horizontal_disps(:, 3), horizontal_disps(:, 1), horizontal_disps(:, 5)) 347 | subplot(224) 348 | plot(vertical_disps(:, 2), vertical_disps(:, 4), vertical_disps(:, 2), vertical_disps(:, 6)) 349 | -------------------------------------------------------------------------------- /plate_with_a_hole_no_fail.m: -------------------------------------------------------------------------------- 1 | %% 2 | clear; 3 | clc; 4 | 5 | %% Specification of the locations of material points 6 | length = 0.05; 7 | % length: Total length of the bar 8 | width = 0.05; 9 | % width: Total width of the plate 10 | holerad = 0.005; 11 | % holerad: Hole radius 12 | ndivx = 100; 13 | % ndivx: Number of divisions in x direction - except boundary region 14 | ndivy = 100; 15 | % ndivy: Number of divisions in y direction - except boundary region 16 | 17 | dx = length / ndivx; 18 | % dx: Spacing between material points 19 | nbnd = 3; 20 | % nbnd: Number of divisions in the boundary region 21 | totnode = ndivx * (ndivy + 2*nbnd); 22 | % totnode: Total number of material points 23 | 24 | coord = zeros(totnode, 2); 25 | % coord: Material point locations 26 | 27 | nnum = 0; 28 | % nnum: Material point number 29 | 30 | % Material points of the internal region 31 | for i = 1:ndivy 32 | for j = 1:ndivx 33 | coordx = (-1.0*length/2.0) + (dx/2.0) + (j - 1)*dx; 34 | coordy = (-1.0*width/2.0) + (dx/2.0) + (i - 1)*dx; 35 | tmprad = sqrt((coordx)^2 + (coordy)^2); 36 | if (tmprad > holerad) 37 | nnum = nnum + 1; 38 | coord(nnum, 1) = coordx; 39 | coord(nnum, 2) = coordy; 40 | end 41 | end 42 | end 43 | 44 | totint = nnum; 45 | 46 | % Material points of the boundary region - bottom 47 | for i = 1:nbnd 48 | for j = 1: ndivx 49 | nnum = nnum + 1; 50 | coord(nnum, 1) = -1.0/2.0*length + (dx/2.0) + (j - 1)*dx; 51 | coord(nnum, 2) = -1.0/2.0*width - (dx/2.0) - (i - 1)*dx; 52 | end 53 | end 54 | 55 | totbottom = nnum; 56 | 57 | % Material points of the boundary region - top 58 | for i = 1: nbnd 59 | for j = 1: ndivx 60 | nnum = nnum + 1; 61 | coord(nnum, 1) = -1.0/2.0*length + (dx/2.0) + (j - 1)*dx; 62 | coord(nnum, 2) = 1.0/2.0*width + (dx/2.0) + (i - 1)*dx; 63 | end 64 | end 65 | 66 | tottop = nnum; 67 | totnode = nnum; 68 | 69 | 70 | %% Initialization of fail flag array 71 | maxfam = 100; 72 | % maxfam: Maximum number of material points inside a horizon of a material point 73 | 74 | fail = ones(totnode, maxfam); 75 | 76 | %% Determination of material points inside the horizon of each material point 77 | delta = 3.015 * dx; 78 | % delta: Horizon 79 | 80 | pointfam = int32(zeros(totnode, 1)); 81 | % pointfam: index array to find the family members in nodefam array 82 | numfam = int32(zeros(totnode, 1)); 83 | % numfam: Number of family members of each material point 84 | nodefam = int32(zeros(1000000, 1)); 85 | % nodefam: array containing family members of all material points 86 | 87 | for i = 1:totnode 88 | if (i == 1) 89 | pointfam(i, 1) = 1; 90 | else 91 | pointfam(i, 1) = pointfam(i - 1, 1) + numfam(i - 1, 1); 92 | end 93 | for j = 1:totnode 94 | % idist = norm(coord(j, :)-coord(i, :)); 95 | idist = sqrt((coord(j, 1) - coord(i, 1))^2+(coord(j, 2) - coord(i, 2))^2); 96 | if (i ~= j) 97 | if (idist <= delta) 98 | numfam(i, 1) = numfam(i, 1) + 1; 99 | nodefam(pointfam(i, 1)+numfam(i, 1)-1, 1) = j; 100 | end 101 | end 102 | end 103 | end 104 | 105 | %% Determination of surface correction factors 106 | radij = dx / 2.0; 107 | % radij: Material point radius 108 | area = dx * dx; 109 | % area: Cross-sectional area 110 | vol = area * dx; 111 | % vol: Volume of a material point 112 | thick = dx; 113 | % thick: Total thickness of the plate 114 | 115 | dens = 8000.0; 116 | % dens: Density 117 | emod = 192.0e9; 118 | % emod: Elastic modulus 119 | bc = 9.0 * emod / (pi * thick * (delta^3)); 120 | % bc: Bond constant 121 | 122 | disp = zeros(totnode, 2); 123 | % disp: displacement of a material point 124 | stendens = zeros(totnode, 2); 125 | % stendens: strain energy of a material point 126 | fncst = ones(totnode, 2); 127 | % fncst: surface correction factors of a material point, 1:loading 1, 2:loading 2 128 | 129 | % Loading 1 130 | sedload1 = 9.0 / 16.0 * emod * 1.0e-6; 131 | % sedload1: strain energy density of a material point for the first loading condition based on classical continuum mechanics 132 | 133 | for i = 1:totnode 134 | disp(i, 1) = 0.001 * coord(i, 1); 135 | disp(i, 2) = 0.0; 136 | end 137 | 138 | for i = 1:totnode 139 | stendens(i, 1) = 0.0; 140 | for j = 1:numfam(i, 1) 141 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 142 | % idist = norm(coord(cnode, :)-coord(i, :)); 143 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 144 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2); 145 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2); 146 | 147 | if (idist <= delta - radij) 148 | fac = 1.0; 149 | elseif (idist <= delta + radij) 150 | fac = (delta + radij - idist) / (2.0 * radij); 151 | else 152 | fac = 0.0; 153 | end 154 | 155 | stendens(i, 1) = stendens(i, 1) + 0.5 * 0.5 * bc * ((nlength - idist) / idist)^2 * idist * vol * fac; 156 | end 157 | % Calculation of surface correction factor in x direction 158 | % by finding the ratio of the analytical strain energy density value 159 | % to the strain energy density value obtained from PD Theory 160 | fncst(i, 1) = sedload1 / stendens(i, 1); 161 | end 162 | 163 | % Loading 2 164 | sedload2 = 9.0 / 16.0 * emod * 1.0e-6; 165 | % sedload2: strain energy density of a material point for the second loading condition based on classical continuum mechanics 166 | 167 | for i = 1:totnode 168 | disp(i, 1) = 0.0; 169 | disp(i, 2) = 0.001 * coord(i, 2); 170 | end 171 | 172 | for i = 1:totnode 173 | stendens(i, 2) = 0.0; 174 | for j = 1:numfam(i, 1) 175 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 176 | % idist = norm(coord(cnode, :)-coord(i, :)); 177 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 178 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2); 179 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2); 180 | 181 | if (idist <= delta - radij) 182 | fac = 1.0; 183 | elseif (idist <= delta + radij) 184 | fac = (delta + radij - idist) / (2.0 * radij); 185 | else 186 | fac = 0.0; 187 | end 188 | 189 | stendens(i, 2) = stendens(i, 2) + 0.5 * 0.5 * bc * ((nlength - idist) / idist)^2 * idist * vol * fac; 190 | end 191 | % Calculation of surface correction factor in x direction 192 | % by finding the ratio of the analytical strain energy density value 193 | % to the strain energy density value obtained from PD Theory 194 | fncst(i, 2) = sedload2 / stendens(i, 2); 195 | end 196 | 197 | %% Initialization of displacements and velocities 198 | vel = zeros(totnode, 2); 199 | disp = zeros(totnode, 2); 200 | 201 | %% Stable mass vector computation 202 | dt = 1.0; 203 | % dt: Time interval 204 | 205 | massvec = zeros(totnode, 2); 206 | % massvec: massvector for adaptive dynamic relaxation 207 | 208 | for i = 1:totnode 209 | % 5 is a safety factor 210 | massvec(i, 1) = 0.25 * dt * dt * (pi * (delta)^2 * thick) * bc / dx;% * 5.0; 211 | massvec(i, 2) = 0.25 * dt * dt * (pi * (delta)^2 * thick) * bc / dx;% * 5.0; 212 | end 213 | 214 | %% Applied loading - Left and Right 215 | appres = 200.0e6; 216 | % appres: Applied pressure 217 | 218 | bforce = zeros(totnode, 2); 219 | % bforce: body load acting on a material point 220 | 221 | 222 | %% Time integration 223 | nt = 1000; 224 | % nt: Total number of time step 225 | alpha = 23.0e-6; 226 | % alpha: Coefficient of thermal expansion 227 | dtemp = 0.0; 228 | % dtemp: Temperature change 229 | pratio = 1.0 / 3.0; 230 | % pratio: Poisson's ratio 231 | scr0 = 1.0; 232 | % scr0: Critical stretch 233 | 234 | dmg = zeros(totint, 1); 235 | 236 | pforce = zeros(totnode, 2); 237 | % pforce: total peridynamic force acting on a material point 238 | pforceold = zeros(totnode, 2); 239 | % pforceold: total peridynamic force acting on a material point in the previous time step 1:x-coord, 2:y-coord 240 | acc = zeros(totnode, 2); 241 | % acc: acceleration of a material point 242 | 243 | velhalf = zeros(totnode, 2); 244 | velhalfold = zeros(totnode, 2); 245 | % vel: velocity of a material point 246 | 247 | coord_disp_pd_nt = zeros(totint, 4); 248 | % Peridynamic displacement and Analytical displacement of all points at time step of nt 249 | horiCnt = 0; 250 | horizontal_disps = zeros(ndivx, 4); 251 | % Peridynamic displacement and Analytical displacement of points at y = 0; 252 | vertiCnt = 0; 253 | vertical_disps = zeros(ndivy, 4); 254 | % Peridynamic displacement and Analytical displacement of points at x = 0; 255 | steady_check = zeros(nt, 3); 256 | 257 | cn = 0.0; 258 | cn1 = 0.0; 259 | cn2 = 0.0; 260 | for tt = 1:nt 261 | fprintf("%d/%d\n", tt, nt); 262 | ctime = tt * dt; 263 | 264 | % Application of boundary conditions at the top and bottom edges 265 | for i = (totint + 1): totbottom 266 | vel(i, 2) = -2.7541e-7; 267 | disp(i, 2) = -2.7541e-7*tt*dt; 268 | end 269 | 270 | for i = (totbottom + 1): tottop 271 | vel(i, 2) = 2.7541e-7; 272 | disp(i, 2) = 2.7541e-7*tt*dt; 273 | end 274 | 275 | 276 | for i = 1:totint 277 | dmgpar1 = 0.0; 278 | dmgpar2 = 0.0; 279 | pforce(i, 1) = 0.0; 280 | pforce(i, 2) = 0.0; 281 | for j = 1:numfam(i, 1) 282 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 283 | % idist = norm(coord(cnode, :)-coord(i, :)); 284 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 285 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2); 286 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2); 287 | 288 | % Volume correction 289 | if (idist <= delta - radij) 290 | fac = 1.0; 291 | elseif (idist <= delta + radij) 292 | fac = (delta + radij - idist) / (2.0 * radij); 293 | else 294 | fac = 0.0; 295 | end 296 | 297 | % Determination of the surface correction between two material points 298 | if (abs(coord(cnode, 2)-coord(i, 2)) <= 1.0e-10) 299 | theta = 0.0; 300 | elseif (abs(coord(cnode, 1)-coord(i, 1)) <= 1.0e-10) 301 | theta = 90.0 * pi / 180.0; 302 | else 303 | theta = atan(abs(coord(cnode, 2)-coord(i, 2))/abs(coord(cnode, 1)-coord(i, 1))); 304 | end 305 | scx = (fncst(i, 1) + fncst(cnode, 1)) / 2.0; 306 | scy = (fncst(i, 2) + fncst(cnode, 2)) / 2.0; 307 | scr = 1.0 / (((cos(theta))^2.0 / (scx)^2.0) + ((sin(theta))^2.0 / (scy)^2.0)); 308 | scr = sqrt(scr); 309 | 310 | if (fail(i, j) == 1) 311 | dforce1 = bc*(nlength - idist)/idist*vol*scr*fac*(coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))/nlength; 312 | dforce2 = bc*(nlength - idist)/idist*vol*scr*fac*(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))/nlength; 313 | else 314 | dforce1 = 0.0; 315 | dforce2 = 0.0; 316 | end 317 | pforce(i, 1) = pforce(i, 1) + dforce1; 318 | pforce(i, 2) = pforce(i, 2) + dforce2; 319 | 320 | % Definition of a no-fail zone 321 | if (abs((nlength - idist)/idist) > scr0) 322 | if (abs(coord(i, 2)) <= (length/4.0)) 323 | fail(i, j) = 0; 324 | end 325 | end 326 | 327 | dmgpar1 = dmgpar1 + fail(i, j)*vol*fac; 328 | dmgpar2 = dmgpar2 + vol*fac; 329 | end 330 | % Calculation of the damage parameter 331 | dmg(i, 1) = 1.0 - dmgpar1/dmgpar2; 332 | end 333 | 334 | % Adaptive dynamic relaxation ⬇⬇⬇ 335 | 336 | for i = 1:totint 337 | if (velhalfold(i, 1) ~= 0.0) 338 | cn1 = cn1 - disp(i, 1) * disp(i, 1) * (pforce(i, 1) / massvec(i, 1) - pforceold(i, 1) / massvec(i, 1)) / (dt * velhalfold(i, 1)); 339 | end 340 | if (velhalfold(i, 2) ~= 0.0) 341 | cn1 = cn1 - disp(i, 2) * disp(i, 2) * (pforce(i, 2) / massvec(i, 2) - pforceold(i, 2) / massvec(i, 2)) / (dt * velhalfold(i, 2)); 342 | end 343 | cn2 = cn2 + disp(i, 1) * disp(i, 1); 344 | cn2 = cn2 + disp(i, 2) * disp(i, 2); 345 | end 346 | 347 | if (cn2 ~= 0.0) 348 | if ((cn1 / cn2) > 0.0) 349 | cn = 2.0 * sqrt(cn1/cn2); 350 | else 351 | cn = 0.0; 352 | end 353 | else 354 | cn = 0.0; 355 | end 356 | 357 | if (cn > 2.0) 358 | cn = 1.9; 359 | end 360 | 361 | for i = 1:totint 362 | % Integrate acceleration over time. 363 | if (tt == 1) 364 | velhalf(i, 1) = 1.0 * dt / massvec(i, 1) * (pforce(i, 1) + bforce(i, 1)) / 2.0; 365 | velhalf(i, 2) = 1.0 * dt / massvec(i, 2) * (pforce(i, 2) + bforce(i, 2)) / 2.0; 366 | else 367 | velhalf(i, 1) = ((2.0 - cn * dt) * velhalfold(i, 1) + 2.0 * dt / massvec(i, 1) * (pforce(i, 1) + bforce(i, 1))) / (2.0 + cn * dt); 368 | velhalf(i, 2) = ((2.0 - cn * dt) * velhalfold(i, 2) + 2.0 * dt / massvec(i, 2) * (pforce(i, 2) + bforce(i, 2))) / (2.0 + cn * dt); 369 | end 370 | 371 | vel(i, 1) = 0.5 * (velhalfold(i, 1) + velhalf(i, 1)); 372 | vel(i, 2) = 0.5 * (velhalfold(i, 2) + velhalf(i, 2)); 373 | disp(i, 1) = disp(i, 1) + velhalf(i, 1) * dt; 374 | disp(i, 2) = disp(i, 2) + velhalf(i, 2) * dt; 375 | 376 | velhalfold(i, 1) = velhalf(i, 1); 377 | velhalfold(i, 2) = velhalf(i, 2); 378 | pforceold(i, 1) = pforce(i, 1); 379 | pforceold(i, 2) = pforce(i, 2); 380 | end 381 | 382 | % Adaptive dynamic relaxation ⬆⬆⬆ 383 | 384 | if (tt == nt) 385 | for i = 1:totint 386 | coord_disp_pd_nt(i, 1:4) = [coord(i, 1), coord(i, 2), disp(i, 1), disp(i, 2)]; 387 | if (abs(coord(i, 2)-(dx / 2.0)) <= 1.0e-8) 388 | horiCnt = horiCnt + 1; 389 | horizontal_disps(horiCnt, 1:4) = [coord(i, 1), coord(i, 2), disp(i, 1), disp(i, 2)]; 390 | end 391 | if (abs(coord(i, 1)-(dx / 2.0)) <= 1.0e-8) 392 | vertiCnt = vertiCnt + 1; 393 | vertical_disps(vertiCnt, 1:4) = [coord(i, 1), coord(i, 2), disp(i, 1), disp(i, 2)]; 394 | end 395 | end 396 | end 397 | 398 | steady_check(tt, 1:3) = [tt, disp(3788, 1), disp(3788, 2)]; 399 | end 400 | 401 | %% plot 402 | colormap jet; 403 | subplot(221) 404 | scale = 1; 405 | scatter(coord_disp_pd_nt(:, 1)+scale*coord_disp_pd_nt(:, 3), coord_disp_pd_nt(:, 2)+scale*coord_disp_pd_nt(:, 4), [], sqrt(coord_disp_pd_nt(:, 3).^2+coord_disp_pd_nt(:, 4).^2), "filled") 406 | subplot(222) 407 | plot(steady_check(:, 1), steady_check(:, 2), steady_check(:, 1), steady_check(:, 3)) 408 | subplot(223) 409 | plot(horizontal_disps(1:horiCnt, 1), horizontal_disps(1:horiCnt, 3)) 410 | subplot(224) 411 | plot(vertical_disps(1:vertiCnt, 2), vertical_disps(1:vertiCnt, 4)) 412 | -------------------------------------------------------------------------------- /plate_with_a_preexisting_crack_no_fail.m: -------------------------------------------------------------------------------- 1 | %% 2 | clear; 3 | clc; 4 | 5 | %% Specification of the locations of material points 6 | length = 0.05; 7 | % length: Total length of the bar 8 | width = 0.05; 9 | % width: Total width of the plate 10 | 11 | ndivx = 500; 12 | % ndivx: Number of divisions in x direction - except boundary region 13 | ndivy = 500; 14 | % ndivy: Number of divisions in y direction - except boundary region 15 | 16 | dx = length / ndivx; 17 | % dx: Spacing between material points 18 | nbnd = 3; 19 | % nbnd: Number of divisions in the boundary region 20 | totnode = ndivx * (ndivy + 2 * nbnd); 21 | % totnode: Total number of material points 22 | 23 | coord = zeros(totnode, 2); 24 | % coord: Material point locations 25 | 26 | nnum = 0; 27 | % nnum: Material point number 28 | 29 | % Material points of the internal region 30 | for i = 1:ndivy 31 | for j = 1:ndivx 32 | nnum = nnum + 1; 33 | coord(nnum, 1) = (-1.0 * length / 2.0) + (dx / 2.0) + (j - 1) * dx; 34 | coord(nnum, 2) = (-1.0 * width / 2.0) + (dx / 2.0) + (i - 1) * dx; 35 | end 36 | end 37 | 38 | totint = nnum; 39 | 40 | % Material points of the boundary region - bottom 41 | for i = 1:nbnd 42 | for j = 1:ndivx 43 | nnum = nnum + 1; 44 | coord(nnum, 1) = -1.0 / 2.0 * length + (dx / 2.0) + (j - 1) * dx; 45 | coord(nnum, 2) = -1.0 / 2.0 * width - (dx / 2.0) - (i - 1) * dx; 46 | end 47 | end 48 | 49 | totbottom = nnum; 50 | 51 | % Material points of the boundary region - top 52 | for i = 1:nbnd 53 | for j = 1:ndivx 54 | nnum = nnum + 1; 55 | coord(nnum, 1) = -1.0 / 2.0 * length + (dx / 2.0) + (j - 1) * dx; 56 | coord(nnum, 2) = 1.0 / 2.0 * width + (dx / 2.0) + (i - 1) * dx; 57 | end 58 | end 59 | 60 | tottop = nnum; 61 | totnode = nnum; 62 | 63 | %% Initialization of fail flag array 64 | maxfam = 100; 65 | % maxfam: Maximum number of material points inside a horizon of a material point 66 | 67 | fail = ones(totnode, maxfam); 68 | 69 | %% Determination of material points inside the horizon of each material point 70 | delta = 3.015 * dx; 71 | % delta: Horizon 72 | 73 | pointfam = int32(zeros(totnode, 1)); 74 | % pointfam: index array to find the family members in nodefam array 75 | numfam = int32(zeros(totnode, 1)); 76 | % numfam: Number of family members of each material point 77 | nodefam = int32(zeros(1000000, 1)); 78 | % nodefam: array containing family members of all material points 79 | 80 | for i = 1:totnode 81 | if (i == 1) 82 | pointfam(i, 1) = 1; 83 | else 84 | pointfam(i, 1) = pointfam(i - 1, 1) + numfam(i - 1, 1); 85 | end 86 | for j = 1:totnode 87 | % idist = norm(coord(j, :)-coord(i, :)); 88 | idist = sqrt((coord(j, 1) - coord(i, 1))^2+(coord(j, 2) - coord(i, 2))^2); 89 | if (i ~= j) 90 | if (idist <= delta) 91 | numfam(i, 1) = numfam(i, 1) + 1; 92 | nodefam(pointfam(i, 1)+numfam(i, 1)-1, 1) = j; 93 | end 94 | end 95 | end 96 | end 97 | 98 | %% Definition of the crack surface 99 | crlength = 0.01; 100 | % crlength: Crack length 101 | 102 | % PD bonds penetrating through the crack surface are broken 103 | for i = 1:totnode 104 | for j = 1:numfam(i, 1) 105 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 106 | if ((coord(cnode, 2) > 0.0) && (coord(i, 2) < 0.0)) 107 | if ((abs(coord(i, 1)) - (crlength / 2.0)) <= 1.0e-10) 108 | fail(i, j) = 0; 109 | elseif ((abs(coord(cnode, 1)) - (crlength / 2.0)) <= 1.0e-10) 110 | fail(i, j) = 0; 111 | end 112 | elseif ((coord(i, 2) > 0.0) && (coord(cnode, 2) < 0.0)) 113 | if ((abs(coord(i, 1)) - (crlength / 2.0)) <= 1.0e-10) 114 | fail(i, j) = 0; 115 | elseif ((abs(coord(cnode, 1)) - (crlength / 2.0)) <= 1.0e-10) 116 | fail(i, j) = 0; 117 | end 118 | end 119 | end 120 | end 121 | 122 | %% Determination of surface correction factors 123 | radij = dx / 2.0; 124 | % radij: Material point radius 125 | area = dx * dx; 126 | % area: Cross-sectional area 127 | vol = area * dx; 128 | % vol: Volume of a material point 129 | thick = dx; 130 | % thick: Total thickness of the plate 131 | 132 | dens = 8000.0; 133 | % dens: Density 134 | emod = 192.0e9; 135 | % emod: Elastic modulus 136 | bc = 9.0 * emod / (pi * thick * (delta^3)); 137 | % bc: Bond constant 138 | 139 | disp = zeros(totnode, 2); 140 | % disp: displacement of a material point 141 | stendens = zeros(totnode, 2); 142 | % stendens: strain energy of a material point 143 | fncst = ones(totnode, 2); 144 | % fncst: surface correction factors of a material point, 1:loading 1, 2:loading 2 145 | 146 | % Loading 1 147 | sedload1 = 9.0 / 16.0 * emod * 1.0e-6; 148 | % sedload1: strain energy density of a material point for the first loading condition based on classical continuum mechanics 149 | 150 | for i = 1:totnode 151 | disp(i, 1) = 0.001 * coord(i, 1); 152 | disp(i, 2) = 0.0; 153 | end 154 | 155 | for i = 1:totnode 156 | stendens(i, 1) = 0.0; 157 | for j = 1:numfam(i, 1) 158 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 159 | % idist = norm(coord(cnode, :)-coord(i, :)); 160 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 161 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2); 162 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2); 163 | 164 | if (idist <= delta - radij) 165 | fac = 1.0; 166 | elseif (idist <= delta + radij) 167 | fac = (delta + radij - idist) / (2.0 * radij); 168 | else 169 | fac = 0.0; 170 | end 171 | 172 | stendens(i, 1) = stendens(i, 1) + 0.5 * 0.5 * bc * ((nlength - idist) / idist)^2 * idist * vol * fac; 173 | end 174 | % Calculation of surface correction factor in x direction 175 | % by finding the ratio of the analytical strain energy density value 176 | % to the strain energy density value obtained from PD Theory 177 | fncst(i, 1) = sedload1 / stendens(i, 1); 178 | end 179 | 180 | % Loading 2 181 | sedload2 = 9.0 / 16.0 * emod * 1.0e-6; 182 | % sedload2: strain energy density of a material point for the second loading condition based on classical continuum mechanics 183 | 184 | for i = 1:totnode 185 | disp(i, 1) = 0.0; 186 | disp(i, 2) = 0.001 * coord(i, 2); 187 | end 188 | 189 | for i = 1:totnode 190 | stendens(i, 2) = 0.0; 191 | for j = 1:numfam(i, 1) 192 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 193 | % idist = norm(coord(cnode, :)-coord(i, :)); 194 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 195 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2); 196 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2); 197 | 198 | if (idist <= delta - radij) 199 | fac = 1.0; 200 | elseif (idist <= delta + radij) 201 | fac = (delta + radij - idist) / (2.0 * radij); 202 | else 203 | fac = 0.0; 204 | end 205 | 206 | stendens(i, 2) = stendens(i, 2) + 0.5 * 0.5 * bc * ((nlength - idist) / idist)^2 * idist * vol * fac; 207 | end 208 | % Calculation of surface correction factor in x direction 209 | % by finding the ratio of the analytical strain energy density value 210 | % to the strain energy density value obtained from PD Theory 211 | fncst(i, 2) = sedload2 / stendens(i, 2); 212 | end 213 | 214 | %% Initialization of displacements and velocities 215 | vel = zeros(totnode, 2); 216 | disp = zeros(totnode, 2); 217 | 218 | %% Stable mass vector computation 219 | dt = 0.8 * sqrt(2.0*dens*dx/(pi * delta^2 * dx * bc)); 220 | % dt: Time interval 221 | 222 | % massvec = zeros(totnode, 2); 223 | % % massvec: massvector for adaptive dynamic relaxation 224 | % 225 | % for i = 1:totnode 226 | % % 5 is a safety factor 227 | % massvec(i, 1) = 0.25 * dt * dt * (pi * (delta)^2 * thick) * bc / dx;% * 5.0; 228 | % massvec(i, 2) = 0.25 * dt * dt * (pi * (delta)^2 * thick) * bc / dx;% * 5.0; 229 | % end 230 | 231 | %% Applied loading - Left and Right 232 | appres = 200.0e6; 233 | % appres: Applied pressure 234 | 235 | bforce = zeros(totnode, 2); 236 | % bforce: body load acting on a material point 237 | 238 | %% Time integration 239 | nt = 1250; 240 | % nt: Total number of time step 241 | alpha = 23.0e-6; 242 | % alpha: Coefficient of thermal expansion 243 | dtemp = 0.0; 244 | % dtemp: Temperature change 245 | pratio = 1.0 / 3.0; 246 | % pratio: Poisson's ratio 247 | scr0 = 1.0; 248 | % scr0: Critical stretch 249 | 250 | dmg = zeros(totint, 1); 251 | 252 | pforce = zeros(totnode, 2); 253 | % pforce: total peridynamic force acting on a material point 254 | pforceold = zeros(totnode, 2); 255 | % pforceold: total peridynamic force acting on a material point in the previous time step 1:x-coord, 2:y-coord 256 | acc = zeros(totnode, 2); 257 | % acc: acceleration of a material point 258 | 259 | velhalf = zeros(totnode, 2); 260 | velhalfold = zeros(totnode, 2); 261 | % vel: velocity of a material point 262 | 263 | coord_disp_pd_750_pwc = zeros(totint, 4); 264 | % Peridynamic displacement and Analytical displacement of all points at time step of nt 265 | coord_disp_pd_1000_pwc = zeros(totint, 4); 266 | coord_disp_pd_1250_pwc = zeros(totint, 4); 267 | 268 | steady_check = zeros(nt, 3); 269 | 270 | cn = 0.0; 271 | cn1 = 0.0; 272 | cn2 = 0.0; 273 | for tt = 1:nt 274 | fprintf("%d/%d\n", tt, nt); 275 | ctime = tt * dt; 276 | 277 | % Application of boundary conditions at the top and bottom edges 278 | for i = (totint + 1):totbottom 279 | vel(i, 2) = -20.0; 280 | disp(i, 2) = -20.0 * tt * dt; 281 | end 282 | 283 | for i = (totbottom + 1):tottop 284 | vel(i, 2) = 20.0; 285 | disp(i, 2) = 20.0 * tt * dt; 286 | end 287 | 288 | 289 | for i = 1:totint 290 | dmgpar1 = 0.0; 291 | dmgpar2 = 0.0; 292 | pforce(i, 1) = 0.0; 293 | pforce(i, 2) = 0.0; 294 | for j = 1:numfam(i, 1) 295 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 296 | % idist = norm(coord(cnode, :)-coord(i, :)); 297 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 298 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2); 299 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2); 300 | 301 | % Volume correction 302 | if (idist <= delta - radij) 303 | fac = 1.0; 304 | elseif (idist <= delta + radij) 305 | fac = (delta + radij - idist) / (2.0 * radij); 306 | else 307 | fac = 0.0; 308 | end 309 | 310 | % Determination of the surface correction between two material points 311 | if (abs(coord(cnode, 2)-coord(i, 2)) <= 1.0e-10) 312 | theta = 0.0; 313 | elseif (abs(coord(cnode, 1)-coord(i, 1)) <= 1.0e-10) 314 | theta = 90.0 * pi / 180.0; 315 | else 316 | theta = atan(abs(coord(cnode, 2)-coord(i, 2))/abs(coord(cnode, 1)-coord(i, 1))); 317 | end 318 | scx = (fncst(i, 1) + fncst(cnode, 1)) / 2.0; 319 | scy = (fncst(i, 2) + fncst(cnode, 2)) / 2.0; 320 | scr = 1.0 / (((cos(theta))^2.0 / (scx)^2.0) + ((sin(theta))^2.0 / (scy)^2.0)); 321 | scr = sqrt(scr); 322 | 323 | if (fail(i, j) == 1) 324 | dforce1 = bc * (nlength - idist) / idist * vol * scr * fac * (coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1)) / nlength; 325 | dforce2 = bc * (nlength - idist) / idist * vol * scr * fac * (coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2)) / nlength; 326 | else 327 | dforce1 = 0.0; 328 | dforce2 = 0.0; 329 | end 330 | pforce(i, 1) = pforce(i, 1) + dforce1; 331 | pforce(i, 2) = pforce(i, 2) + dforce2; 332 | 333 | % Definition of a no-fail zone 334 | if (abs((nlength - idist)/idist) > scr0) 335 | if (abs(coord(i, 2)) <= (length / 4.0)) 336 | fail(i, j) = 0; 337 | end 338 | end 339 | 340 | dmgpar1 = dmgpar1 + fail(i, j) * vol * fac; 341 | dmgpar2 = dmgpar2 + vol * fac; 342 | end 343 | % Calculation of the damage parameter 344 | dmg(i, 1) = 1.0 - dmgpar1 / dmgpar2; 345 | end 346 | for i = 1:totint 347 | % Calculation of acceleration of material point i 348 | acc(i, 1) = (pforce(i, 1) + bforce(i, 1)) / dens; 349 | acc(i, 2) = (pforce(i, 2) + bforce(i, 2)) / dens; 350 | % Calculation of velocity of material point i 351 | % by integrating the acceleration of material point i 352 | vel(i, 1) = vel(i, 1) + acc(i, 1) * dt; 353 | vel(i, 2) = vel(i, 2) + acc(i, 2) * dt; 354 | % Calculation of displacement of material point i 355 | % by integrating the velocity of material point i 356 | disp(i, 1) = disp(i, 1) + vel(i, 1) * dt; 357 | disp(i, 2) = disp(i, 2) + vel(i, 2) * dt; 358 | end 359 | 360 | for i = (totint + 1):totbottom 361 | acc(i, 1) = (pforce(i, 1) + bforce(i, 1)) / dens; 362 | vel(i, 1) = vel(i, 1) + acc(i, 1) * dt; 363 | disp(i, 1) = disp(i, 1) + vel(i, 1) * dt; 364 | end 365 | 366 | for i = (totbottom + 1):tottop 367 | acc(i, 1) = (pforce(i, 1) + bforce(i, 1)) / dens; 368 | vel(i, 1) = vel(i, 1) + acc(i, 1) * dt; 369 | disp(i, 1) = disp(i, 1) + vel(i, 1) * dt; 370 | end 371 | 372 | if (tt == 750) 373 | for i = 1:totint 374 | coord_disp_pd_750_pwc(i, 1:4) = [coord(i, 1), coord(i, 2), disp(i, 1), disp(i, 2)]; 375 | end 376 | elseif (tt == 1000) 377 | for i = 1:totint 378 | coord_disp_pd_1000_pwc(i, 1:4) = [coord(i, 1), coord(i, 2), disp(i, 1), disp(i, 2)]; 379 | end 380 | elseif (tt == 1250) 381 | for i = 1:totint 382 | coord_disp_pd_1250_pwc(i, 1:4) = [coord(i, 1), coord(i, 2), disp(i, 1), disp(i, 2)]; 383 | end 384 | end 385 | 386 | steady_check(tt, 1:3) = [tt, disp(3788, 1), disp(3788, 2)]; 387 | end 388 | 389 | %% plot 390 | colormap jet; 391 | subplot(221) 392 | plot(steady_check(:, 1), steady_check(:, 2), steady_check(:, 1), steady_check(:, 3)) 393 | scale = 5; 394 | subplot(222) 395 | scatter(coord_disp_pd_750_pwc(:, 1)+scale*coord_disp_pd_750_pwc(:, 3), coord_disp_pd_750_pwc(:, 2)+scale*coord_disp_pd_750_pwc(:, 4), [], sqrt(coord_disp_pd_750_pwc(:, 3).^2+coord_disp_pd_750_pwc(:, 4).^2), "filled") 396 | subplot(223) 397 | scatter(coord_disp_pd_1000_pwc(:, 1)+scale*coord_disp_pd_1000_pwc(:, 3), coord_disp_pd_1000_pwc(:, 2)+scale*coord_disp_pd_1000_pwc(:, 4), [], sqrt(coord_disp_pd_1000_pwc(:, 3).^2+coord_disp_pd_1000_pwc(:, 4).^2), "filled") 398 | subplot(224) 399 | scatter(coord_disp_pd_1250_pwc(:, 1)+scale*coord_disp_pd_1250_pwc(:, 3), coord_disp_pd_1250_pwc(:, 2)+scale*coord_disp_pd_1250_pwc(:, 4), [], sqrt(coord_disp_pd_1250_pwc(:, 3).^2+coord_disp_pd_1250_pwc(:, 4).^2), "filled") 400 | -------------------------------------------------------------------------------- /plate_with_a_preexisting_crack_v50.m: -------------------------------------------------------------------------------- 1 | %% 2 | clear; 3 | clc; 4 | 5 | %% Specification of the locations of material points 6 | length = 0.05; 7 | % length: Total length of the bar 8 | width = 0.05; 9 | % width: Total width of the plate 10 | 11 | ndivx = 500; 12 | % ndivx: Number of divisions in x direction - except boundary region 13 | ndivy = 500; 14 | % ndivy: Number of divisions in y direction - except boundary region 15 | 16 | dx = length / ndivx; 17 | % dx: Spacing between material points 18 | nbnd = 3; 19 | % nbnd: Number of divisions in the boundary region 20 | totnode = ndivx * (ndivy + 2 * nbnd); 21 | % totnode: Total number of material points 22 | 23 | coord = zeros(totnode, 2); 24 | % coord: Material point locations 25 | 26 | nnum = 0; 27 | % nnum: Material point number 28 | 29 | % Material points of the internal region 30 | for i = 1:ndivy 31 | for j = 1:ndivx 32 | nnum = nnum + 1; 33 | coord(nnum, 1) = (-1.0 * length / 2.0) + (dx / 2.0) + (j - 1) * dx; 34 | coord(nnum, 2) = (-1.0 * width / 2.0) + (dx / 2.0) + (i - 1) * dx; 35 | end 36 | end 37 | 38 | totint = nnum; 39 | 40 | % Material points of the boundary region - bottom 41 | for i = 1:nbnd 42 | for j = 1:ndivx 43 | nnum = nnum + 1; 44 | coord(nnum, 1) = -1.0 / 2.0 * length + (dx / 2.0) + (j - 1) * dx; 45 | coord(nnum, 2) = -1.0 / 2.0 * width - (dx / 2.0) - (i - 1) * dx; 46 | end 47 | end 48 | 49 | totbottom = nnum; 50 | 51 | % Material points of the boundary region - top 52 | for i = 1:nbnd 53 | for j = 1:ndivx 54 | nnum = nnum + 1; 55 | coord(nnum, 1) = -1.0 / 2.0 * length + (dx / 2.0) + (j - 1) * dx; 56 | coord(nnum, 2) = 1.0 / 2.0 * width + (dx / 2.0) + (i - 1) * dx; 57 | end 58 | end 59 | 60 | tottop = nnum; 61 | totnode = nnum; 62 | 63 | %% Initialization of fail flag array 64 | maxfam = 100; 65 | % maxfam: Maximum number of material points inside a horizon of a material point 66 | 67 | fail = ones(totnode, maxfam); 68 | 69 | %% Determination of material points inside the horizon of each material point 70 | delta = 3.015 * dx; 71 | % delta: Horizon 72 | 73 | pointfam = int32(zeros(totnode, 1)); 74 | % pointfam: index array to find the family members in nodefam array 75 | numfam = int32(zeros(totnode, 1)); 76 | % numfam: Number of family members of each material point 77 | nodefam = int32(zeros(1000000, 1)); 78 | % nodefam: array containing family members of all material points 79 | 80 | for i = 1:totnode 81 | if (i == 1) 82 | pointfam(i, 1) = 1; 83 | else 84 | pointfam(i, 1) = pointfam(i - 1, 1) + numfam(i - 1, 1); 85 | end 86 | for j = 1:totnode 87 | % idist = norm(coord(j, :)-coord(i, :)); 88 | idist = sqrt((coord(j, 1) - coord(i, 1))^2+(coord(j, 2) - coord(i, 2))^2); 89 | if (i ~= j) 90 | if (idist <= delta) 91 | numfam(i, 1) = numfam(i, 1) + 1; 92 | nodefam(pointfam(i, 1)+numfam(i, 1)-1, 1) = j; 93 | end 94 | end 95 | end 96 | end 97 | 98 | %% Definition of the crack surface 99 | crlength = 0.01; 100 | % crlength: Crack length 101 | 102 | % PD bonds penetrating through the crack surface are broken 103 | for i = 1:totnode 104 | for j = 1:numfam(i, 1) 105 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 106 | if ((coord(cnode, 2) > 0.0) && (coord(i, 2) < 0.0)) 107 | if ((abs(coord(i, 1)) - (crlength / 2.0)) <= 1.0e-10) 108 | fail(i, j) = 0; 109 | elseif ((abs(coord(cnode, 1)) - (crlength / 2.0)) <= 1.0e-10) 110 | fail(i, j) = 0; 111 | end 112 | elseif ((coord(i, 2) > 0.0) && (coord(cnode, 2) < 0.0)) 113 | if ((abs(coord(i, 1)) - (crlength / 2.0)) <= 1.0e-10) 114 | fail(i, j) = 0; 115 | elseif ((abs(coord(cnode, 1)) - (crlength / 2.0)) <= 1.0e-10) 116 | fail(i, j) = 0; 117 | end 118 | end 119 | end 120 | end 121 | 122 | %% Determination of surface correction factors 123 | radij = dx / 2.0; 124 | % radij: Material point radius 125 | area = dx * dx; 126 | % area: Cross-sectional area 127 | vol = area * dx; 128 | % vol: Volume of a material point 129 | thick = dx; 130 | % thick: Total thickness of the plate 131 | 132 | dens = 8000.0; 133 | % dens: Density 134 | emod = 192.0e9; 135 | % emod: Elastic modulus 136 | bc = 9.0 * emod / (pi * thick * (delta^3)); 137 | % bc: Bond constant 138 | 139 | disp = zeros(totnode, 2); 140 | % disp: displacement of a material point 141 | stendens = zeros(totnode, 2); 142 | % stendens: strain energy of a material point 143 | fncst = ones(totnode, 2); 144 | % fncst: surface correction factors of a material point, 1:loading 1, 2:loading 2 145 | 146 | % Loading 1 147 | sedload1 = 9.0 / 16.0 * emod * 1.0e-6; 148 | % sedload1: strain energy density of a material point for the first loading condition based on classical continuum mechanics 149 | 150 | for i = 1:totnode 151 | disp(i, 1) = 0.001 * coord(i, 1); 152 | disp(i, 2) = 0.0; 153 | end 154 | 155 | for i = 1:totnode 156 | stendens(i, 1) = 0.0; 157 | for j = 1:numfam(i, 1) 158 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 159 | % idist = norm(coord(cnode, :)-coord(i, :)); 160 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 161 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2); 162 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2); 163 | 164 | if (idist <= delta - radij) 165 | fac = 1.0; 166 | elseif (idist <= delta + radij) 167 | fac = (delta + radij - idist) / (2.0 * radij); 168 | else 169 | fac = 0.0; 170 | end 171 | 172 | stendens(i, 1) = stendens(i, 1) + 0.5 * 0.5 * bc * ((nlength - idist) / idist)^2 * idist * vol * fac; 173 | end 174 | % Calculation of surface correction factor in x direction 175 | % by finding the ratio of the analytical strain energy density value 176 | % to the strain energy density value obtained from PD Theory 177 | fncst(i, 1) = sedload1 / stendens(i, 1); 178 | end 179 | 180 | % Loading 2 181 | sedload2 = 9.0 / 16.0 * emod * 1.0e-6; 182 | % sedload2: strain energy density of a material point for the second loading condition based on classical continuum mechanics 183 | 184 | for i = 1:totnode 185 | disp(i, 1) = 0.0; 186 | disp(i, 2) = 0.001 * coord(i, 2); 187 | end 188 | 189 | for i = 1:totnode 190 | stendens(i, 2) = 0.0; 191 | for j = 1:numfam(i, 1) 192 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 193 | % idist = norm(coord(cnode, :)-coord(i, :)); 194 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 195 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2); 196 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2); 197 | 198 | if (idist <= delta - radij) 199 | fac = 1.0; 200 | elseif (idist <= delta + radij) 201 | fac = (delta + radij - idist) / (2.0 * radij); 202 | else 203 | fac = 0.0; 204 | end 205 | 206 | stendens(i, 2) = stendens(i, 2) + 0.5 * 0.5 * bc * ((nlength - idist) / idist)^2 * idist * vol * fac; 207 | end 208 | % Calculation of surface correction factor in x direction 209 | % by finding the ratio of the analytical strain energy density value 210 | % to the strain energy density value obtained from PD Theory 211 | fncst(i, 2) = sedload2 / stendens(i, 2); 212 | end 213 | 214 | %% Initialization of displacements and velocities 215 | vel = zeros(totnode, 2); 216 | disp = zeros(totnode, 2); 217 | 218 | %% Stable mass vector computation 219 | dt = 0.8 * sqrt(2.0*dens*dx/(pi * delta^2 * dx * bc)); 220 | % dt: Time interval 221 | 222 | % massvec = zeros(totnode, 2); 223 | % % massvec: massvector for adaptive dynamic relaxation 224 | % 225 | % for i = 1:totnode 226 | % % 5 is a safety factor 227 | % massvec(i, 1) = 0.25 * dt * dt * (pi * (delta)^2 * thick) * bc / dx;% * 5.0; 228 | % massvec(i, 2) = 0.25 * dt * dt * (pi * (delta)^2 * thick) * bc / dx;% * 5.0; 229 | % end 230 | 231 | %% Applied loading - Left and Right 232 | appres = 200.0e6; 233 | % appres: Applied pressure 234 | 235 | bforce = zeros(totnode, 2); 236 | % bforce: body load acting on a material point 237 | 238 | %% Time integration 239 | nt = 1250; 240 | % nt: Total number of time step 241 | alpha = 23.0e-6; 242 | % alpha: Coefficient of thermal expansion 243 | dtemp = 0.0; 244 | % dtemp: Temperature change 245 | pratio = 1.0 / 3.0; 246 | % pratio: Poisson's ratio 247 | scr0 = 0.04472; 248 | % scr0: Critical stretch 249 | 250 | dmg = zeros(totint, 1); 251 | maxdmg = 0.5; 252 | maxxc = crlength / 2.0; 253 | 254 | crack_length = zeros(nt, 2); 255 | 256 | pforce = zeros(totnode, 2); 257 | % pforce: total peridynamic force acting on a material point 258 | pforceold = zeros(totnode, 2); 259 | % pforceold: total peridynamic force acting on a material point in the previous time step 1:x-coord, 2:y-coord 260 | acc = zeros(totnode, 2); 261 | % acc: acceleration of a material point 262 | 263 | velhalf = zeros(totnode, 2); 264 | velhalfold = zeros(totnode, 2); 265 | % vel: velocity of a material point 266 | 267 | coord_disp_pd_750_pwc = zeros(totint, 5); 268 | % Peridynamic displacement and Analytical displacement of all points at time step of nt 269 | coord_disp_pd_1000_pwc = zeros(totint, 5); 270 | coord_disp_pd_1250_pwc = zeros(totint, 5); 271 | 272 | steady_check = zeros(nt, 3); 273 | 274 | cn = 0.0; 275 | cn1 = 0.0; 276 | cn2 = 0.0; 277 | for tt = 1:nt 278 | fprintf("%d/%d\n", tt, nt); 279 | ctime = tt * dt; 280 | 281 | % Application of boundary conditions at the top and bottom edges 282 | for i = (totint + 1):totbottom 283 | vel(i, 2) = -50.0; 284 | disp(i, 2) = -50.0 * tt * dt; 285 | end 286 | 287 | for i = (totbottom + 1):tottop 288 | vel(i, 2) = 50.0; 289 | disp(i, 2) = 50.0 * tt * dt; 290 | end 291 | 292 | 293 | for i = 1:totint 294 | dmgpar1 = 0.0; 295 | dmgpar2 = 0.0; 296 | pforce(i, 1) = 0.0; 297 | pforce(i, 2) = 0.0; 298 | for j = 1:numfam(i, 1) 299 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 300 | % idist = norm(coord(cnode, :)-coord(i, :)); 301 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 302 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2); 303 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2); 304 | 305 | % Volume correction 306 | if (idist <= delta - radij) 307 | fac = 1.0; 308 | elseif (idist <= delta + radij) 309 | fac = (delta + radij - idist) / (2.0 * radij); 310 | else 311 | fac = 0.0; 312 | end 313 | 314 | % Determination of the surface correction between two material points 315 | if (abs(coord(cnode, 2)-coord(i, 2)) <= 1.0e-10) 316 | theta = 0.0; 317 | elseif (abs(coord(cnode, 1)-coord(i, 1)) <= 1.0e-10) 318 | theta = 90.0 * pi / 180.0; 319 | else 320 | theta = atan(abs(coord(cnode, 2)-coord(i, 2))/abs(coord(cnode, 1)-coord(i, 1))); 321 | end 322 | scx = (fncst(i, 1) + fncst(cnode, 1)) / 2.0; 323 | scy = (fncst(i, 2) + fncst(cnode, 2)) / 2.0; 324 | scr = 1.0 / (((cos(theta))^2.0 / (scx)^2.0) + ((sin(theta))^2.0 / (scy)^2.0)); 325 | scr = sqrt(scr); 326 | 327 | if (fail(i, j) == 1) 328 | dforce1 = bc * (nlength - idist) / idist * vol * scr * fac * (coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1)) / nlength; 329 | dforce2 = bc * (nlength - idist) / idist * vol * scr * fac * (coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2)) / nlength; 330 | else 331 | dforce1 = 0.0; 332 | dforce2 = 0.0; 333 | end 334 | pforce(i, 1) = pforce(i, 1) + dforce1; 335 | pforce(i, 2) = pforce(i, 2) + dforce2; 336 | 337 | % Definition of a no-fail zone 338 | if (abs((nlength - idist)/idist) > scr0) 339 | if (abs(coord(i, 2)) <= (length / 4.0)) 340 | fail(i, j) = 0; 341 | end 342 | end 343 | 344 | dmgpar1 = dmgpar1 + fail(i, j) * vol * fac; 345 | dmgpar2 = dmgpar2 + vol * fac; 346 | end 347 | % Calculation of the damage parameter 348 | dmg(i, 1) = 1.0 - dmgpar1 / dmgpar2; 349 | if ((dmg(i, 1) > maxdmg) && (coord(i, 1) > maxxc)) 350 | maxxc = coord(i, 1); 351 | end 352 | end 353 | 354 | newcrlength = maxxc - crlength / 2.0; 355 | 356 | for i = 1:totint 357 | % Calculation of acceleration of material point i 358 | acc(i, 1) = (pforce(i, 1) + bforce(i, 1)) / dens; 359 | acc(i, 2) = (pforce(i, 2) + bforce(i, 2)) / dens; 360 | % Calculation of velocity of material point i 361 | % by integrating the acceleration of material point i 362 | vel(i, 1) = vel(i, 1) + acc(i, 1) * dt; 363 | vel(i, 2) = vel(i, 2) + acc(i, 2) * dt; 364 | % Calculation of displacement of material point i 365 | % by integrating the velocity of material point i 366 | disp(i, 1) = disp(i, 1) + vel(i, 1) * dt; 367 | disp(i, 2) = disp(i, 2) + vel(i, 2) * dt; 368 | end 369 | 370 | for i = (totint + 1):totbottom 371 | acc(i, 1) = (pforce(i, 1) + bforce(i, 1)) / dens; 372 | vel(i, 1) = vel(i, 1) + acc(i, 1) * dt; 373 | disp(i, 1) = disp(i, 1) + vel(i, 1) * dt; 374 | end 375 | 376 | for i = (totbottom + 1):tottop 377 | acc(i, 1) = (pforce(i, 1) + bforce(i, 1)) / dens; 378 | vel(i, 1) = vel(i, 1) + acc(i, 1) * dt; 379 | disp(i, 1) = disp(i, 1) + vel(i, 1) * dt; 380 | end 381 | 382 | if (tt == 750) 383 | for i = 1:totint 384 | coord_disp_pd_750_pwc(i, 1:5) = [coord(i, 1), coord(i, 2), disp(i, 1), disp(i, 2), dmg(i, 1)]; 385 | end 386 | elseif (tt == 1000) 387 | for i = 1:totint 388 | coord_disp_pd_1000_pwc(i, 1:5) = [coord(i, 1), coord(i, 2), disp(i, 1), disp(i, 2), dmg(i, 1)]; 389 | end 390 | elseif (tt == 1250) 391 | for i = 1:totint 392 | coord_disp_pd_1250_pwc(i, 1:5) = [coord(i, 1), coord(i, 2), disp(i, 1), disp(i, 2), dmg(i, 1)]; 393 | end 394 | end 395 | 396 | crack_length(tt, 1:2) = [ctime, newcrlength]; 397 | end 398 | 399 | %% plot 400 | colormap jet; 401 | subplot(221) 402 | plot(crack_length(:, 1), crack_length(:, 2)) 403 | scale = 1; 404 | subplot(222) 405 | scatter(coord_disp_pd_750_pwc(:, 1)+scale*coord_disp_pd_750_pwc(:, 3), coord_disp_pd_750_pwc(:, 2)+scale*coord_disp_pd_750_pwc(:, 4), [], coord_disp_pd_750_pwc(:, 5), "filled") 406 | subplot(223) 407 | scatter(coord_disp_pd_1000_pwc(:, 1)+scale*coord_disp_pd_1000_pwc(:, 3), coord_disp_pd_1000_pwc(:, 2)+scale*coord_disp_pd_1000_pwc(:, 4), [], coord_disp_pd_1000_pwc(:, 5), "filled") 408 | subplot(224) 409 | scatter(coord_disp_pd_1250_pwc(:, 1)+scale*coord_disp_pd_1250_pwc(:, 3), coord_disp_pd_1250_pwc(:, 2)+scale*coord_disp_pd_1250_pwc(:, 4), [], coord_disp_pd_1250_pwc(:, 5), "filled") 410 | -------------------------------------------------------------------------------- /plate_with_a_preexisting_crack_v20_cl.m: -------------------------------------------------------------------------------- 1 | %% 2 | clear; 3 | clc; 4 | 5 | %% Specification of the locations of material points 6 | length = 0.05; 7 | % length: Total length of the bar 8 | width = 0.05; 9 | % width: Total width of the plate 10 | 11 | ndivx = 500; 12 | % ndivx: Number of divisions in x direction - except boundary region 13 | ndivy = 500; 14 | % ndivy: Number of divisions in y direction - except boundary region 15 | 16 | dx = length / ndivx; 17 | % dx: Spacing between material points 18 | nbnd = 3; 19 | % nbnd: Number of divisions in the boundary region 20 | totnode = ndivx * (ndivy + 2 * nbnd); 21 | % totnode: Total number of material points 22 | 23 | coord = zeros(totnode, 2); 24 | % coord: Material point locations 25 | 26 | nnum = 0; 27 | % nnum: Material point number 28 | 29 | % Material points of the internal region 30 | for i = 1:ndivy 31 | for j = 1:ndivx 32 | nnum = nnum + 1; 33 | coord(nnum, 1) = (-1.0 * length / 2.0) + (dx / 2.0) + (j - 1) * dx; 34 | coord(nnum, 2) = (-1.0 * width / 2.0) + (dx / 2.0) + (i - 1) * dx; 35 | end 36 | end 37 | 38 | totint = nnum; 39 | 40 | % Material points of the boundary region - bottom 41 | for i = 1:nbnd 42 | for j = 1:ndivx 43 | nnum = nnum + 1; 44 | coord(nnum, 1) = -1.0 / 2.0 * length + (dx / 2.0) + (j - 1) * dx; 45 | coord(nnum, 2) = -1.0 / 2.0 * width - (dx / 2.0) - (i - 1) * dx; 46 | end 47 | end 48 | 49 | totbottom = nnum; 50 | 51 | % Material points of the boundary region - top 52 | for i = 1:nbnd 53 | for j = 1:ndivx 54 | nnum = nnum + 1; 55 | coord(nnum, 1) = -1.0 / 2.0 * length + (dx / 2.0) + (j - 1) * dx; 56 | coord(nnum, 2) = 1.0 / 2.0 * width + (dx / 2.0) + (i - 1) * dx; 57 | end 58 | end 59 | 60 | tottop = nnum; 61 | totnode = nnum; 62 | 63 | %% Initialization of fail flag array 64 | maxfam = 100; 65 | % maxfam: Maximum number of material points inside a horizon of a material point 66 | 67 | fail = ones(totnode, maxfam); 68 | 69 | %% Determination of material points inside the horizon of each material point 70 | delta = 3.015 * dx; 71 | % delta: Horizon 72 | 73 | pointfam = int32(zeros(totnode, 1)); 74 | % pointfam: index array to find the family members in nodefam array 75 | numfam = int32(zeros(totnode, 1)); 76 | % numfam: Number of family members of each material point 77 | nodefam = int32(zeros(1000000, 1)); 78 | % nodefam: array containing family members of all material points 79 | 80 | for i = 1:totnode 81 | if (i == 1) 82 | pointfam(i, 1) = 1; 83 | else 84 | pointfam(i, 1) = pointfam(i - 1, 1) + numfam(i - 1, 1); 85 | end 86 | for j = 1:totnode 87 | % idist = norm(coord(j, :)-coord(i, :)); 88 | idist = sqrt((coord(j, 1) - coord(i, 1))^2+(coord(j, 2) - coord(i, 2))^2); 89 | if (i ~= j) 90 | if (idist <= delta) 91 | numfam(i, 1) = numfam(i, 1) + 1; 92 | nodefam(pointfam(i, 1)+numfam(i, 1)-1, 1) = j; 93 | end 94 | end 95 | end 96 | end 97 | 98 | %% Definition of the crack surface 99 | crlength = 0.01; 100 | % crlength: Crack length 101 | 102 | % PD bonds penetrating through the crack surface are broken 103 | for i = 1:totnode 104 | for j = 1:numfam(i, 1) 105 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 106 | if ((coord(cnode, 2) > 0.0) && (coord(i, 2) < 0.0)) 107 | if ((abs(coord(i, 1)) - (crlength / 2.0)) <= 1.0e-10) 108 | fail(i, j) = 0; 109 | elseif ((abs(coord(cnode, 1)) - (crlength / 2.0)) <= 1.0e-10) 110 | fail(i, j) = 0; 111 | end 112 | elseif ((coord(i, 2) > 0.0) && (coord(cnode, 2) < 0.0)) 113 | if ((abs(coord(i, 1)) - (crlength / 2.0)) <= 1.0e-10) 114 | fail(i, j) = 0; 115 | elseif ((abs(coord(cnode, 1)) - (crlength / 2.0)) <= 1.0e-10) 116 | fail(i, j) = 0; 117 | end 118 | end 119 | end 120 | end 121 | 122 | %% Determination of surface correction factors 123 | radij = dx / 2.0; 124 | % radij: Material point radius 125 | area = dx * dx; 126 | % area: Cross-sectional area 127 | vol = area * dx; 128 | % vol: Volume of a material point 129 | thick = dx; 130 | % thick: Total thickness of the plate 131 | 132 | dens = 8000.0; 133 | % dens: Density 134 | emod = 192.0e9; 135 | % emod: Elastic modulus 136 | bc = 9.0 * emod / (pi * thick * (delta^3)); 137 | % bc: Bond constant 138 | 139 | disp = zeros(totnode, 2); 140 | % disp: displacement of a material point 141 | stendens = zeros(totnode, 2); 142 | % stendens: strain energy of a material point 143 | fncst = ones(totnode, 2); 144 | % fncst: surface correction factors of a material point, 1:loading 1, 2:loading 2 145 | 146 | % Loading 1 147 | sedload1 = 9.0 / 16.0 * emod * 1.0e-6; 148 | % sedload1: strain energy density of a material point for the first loading condition based on classical continuum mechanics 149 | 150 | for i = 1:totnode 151 | disp(i, 1) = 0.001 * coord(i, 1); 152 | disp(i, 2) = 0.0; 153 | end 154 | 155 | for i = 1:totnode 156 | stendens(i, 1) = 0.0; 157 | for j = 1:numfam(i, 1) 158 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 159 | % idist = norm(coord(cnode, :)-coord(i, :)); 160 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 161 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2); 162 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2); 163 | 164 | if (idist <= delta - radij) 165 | fac = 1.0; 166 | elseif (idist <= delta + radij) 167 | fac = (delta + radij - idist) / (2.0 * radij); 168 | else 169 | fac = 0.0; 170 | end 171 | 172 | stendens(i, 1) = stendens(i, 1) + 0.5 * 0.5 * bc * ((nlength - idist) / idist)^2 * idist * vol * fac; 173 | end 174 | % Calculation of surface correction factor in x direction 175 | % by finding the ratio of the analytical strain energy density value 176 | % to the strain energy density value obtained from PD Theory 177 | fncst(i, 1) = sedload1 / stendens(i, 1); 178 | end 179 | 180 | % Loading 2 181 | sedload2 = 9.0 / 16.0 * emod * 1.0e-6; 182 | % sedload2: strain energy density of a material point for the second loading condition based on classical continuum mechanics 183 | 184 | for i = 1:totnode 185 | disp(i, 1) = 0.0; 186 | disp(i, 2) = 0.001 * coord(i, 2); 187 | end 188 | 189 | for i = 1:totnode 190 | stendens(i, 2) = 0.0; 191 | for j = 1:numfam(i, 1) 192 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 193 | % idist = norm(coord(cnode, :)-coord(i, :)); 194 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 195 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2); 196 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2); 197 | 198 | if (idist <= delta - radij) 199 | fac = 1.0; 200 | elseif (idist <= delta + radij) 201 | fac = (delta + radij - idist) / (2.0 * radij); 202 | else 203 | fac = 0.0; 204 | end 205 | 206 | stendens(i, 2) = stendens(i, 2) + 0.5 * 0.5 * bc * ((nlength - idist) / idist)^2 * idist * vol * fac; 207 | end 208 | % Calculation of surface correction factor in x direction 209 | % by finding the ratio of the analytical strain energy density value 210 | % to the strain energy density value obtained from PD Theory 211 | fncst(i, 2) = sedload2 / stendens(i, 2); 212 | end 213 | 214 | %% Initialization of displacements and velocities 215 | vel = zeros(totnode, 2); 216 | disp = zeros(totnode, 2); 217 | 218 | %% Stable mass vector computation 219 | dt = 0.8 * sqrt(2.0*dens*dx/(pi * delta^2 * dx * bc)); 220 | % dt: Time interval 221 | 222 | % massvec = zeros(totnode, 2); 223 | % % massvec: massvector for adaptive dynamic relaxation 224 | % 225 | % for i = 1:totnode 226 | % % 5 is a safety factor 227 | % massvec(i, 1) = 0.25 * dt * dt * (pi * (delta)^2 * thick) * bc / dx;% * 5.0; 228 | % massvec(i, 2) = 0.25 * dt * dt * (pi * (delta)^2 * thick) * bc / dx;% * 5.0; 229 | % end 230 | 231 | %% Applied loading - Left and Right 232 | appres = 200.0e6; 233 | % appres: Applied pressure 234 | 235 | bforce = zeros(totnode, 2); 236 | % bforce: body load acting on a material point 237 | 238 | %% Time integration 239 | nt = 1250; 240 | % nt: Total number of time step 241 | alpha = 23.0e-6; 242 | % alpha: Coefficient of thermal expansion 243 | dtemp = 0.0; 244 | % dtemp: Temperature change 245 | pratio = 1.0 / 3.0; 246 | % pratio: Poisson's ratio 247 | scr0 = 0.04472; 248 | % scr0: Critical stretch 249 | 250 | dmg = zeros(totint, 1); 251 | maxdmg = 0.5; 252 | maxxc = crlength / 2.0; 253 | 254 | crack_length = zeros(nt, 2); 255 | 256 | pforce = zeros(totnode, 2); 257 | % pforce: total peridynamic force acting on a material point 258 | pforceold = zeros(totnode, 2); 259 | % pforceold: total peridynamic force acting on a material point in the previous time step 1:x-coord, 2:y-coord 260 | acc = zeros(totnode, 2); 261 | % acc: acceleration of a material point 262 | 263 | velhalf = zeros(totnode, 2); 264 | velhalfold = zeros(totnode, 2); 265 | % vel: velocity of a material point 266 | 267 | coord_disp_pd_750_pwc = zeros(totint, 5); 268 | % Peridynamic displacement and Analytical displacement of all points at time step of nt 269 | coord_disp_pd_1000_pwc = zeros(totint, 5); 270 | coord_disp_pd_1250_pwc = zeros(totint, 5); 271 | 272 | steady_check = zeros(nt, 3); 273 | 274 | cn = 0.0; 275 | cn1 = 0.0; 276 | cn2 = 0.0; 277 | for tt = 1:nt 278 | fprintf("%d/%d\n", tt, nt); 279 | ctime = tt * dt; 280 | 281 | % Application of boundary conditions at the top and bottom edges 282 | for i = (totint + 1):totbottom 283 | vel(i, 2) = -20.0; 284 | disp(i, 2) = -20.0 * tt * dt; 285 | end 286 | 287 | for i = (totbottom + 1):tottop 288 | vel(i, 2) = 20.0; 289 | disp(i, 2) = 20.0 * tt * dt; 290 | end 291 | 292 | 293 | for i = 1:totint 294 | dmgpar1 = 0.0; 295 | dmgpar2 = 0.0; 296 | pforce(i, 1) = 0.0; 297 | pforce(i, 2) = 0.0; 298 | for j = 1:numfam(i, 1) 299 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 300 | % idist = norm(coord(cnode, :)-coord(i, :)); 301 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 302 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2); 303 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2); 304 | 305 | % Volume correction 306 | if (idist <= delta - radij) 307 | fac = 1.0; 308 | elseif (idist <= delta + radij) 309 | fac = (delta + radij - idist) / (2.0 * radij); 310 | else 311 | fac = 0.0; 312 | end 313 | 314 | % Determination of the surface correction between two material points 315 | if (abs(coord(cnode, 2)-coord(i, 2)) <= 1.0e-10) 316 | theta = 0.0; 317 | elseif (abs(coord(cnode, 1)-coord(i, 1)) <= 1.0e-10) 318 | theta = 90.0 * pi / 180.0; 319 | else 320 | theta = atan(abs(coord(cnode, 2)-coord(i, 2))/abs(coord(cnode, 1)-coord(i, 1))); 321 | end 322 | scx = (fncst(i, 1) + fncst(cnode, 1)) / 2.0; 323 | scy = (fncst(i, 2) + fncst(cnode, 2)) / 2.0; 324 | scr = 1.0 / (((cos(theta))^2.0 / (scx)^2.0) + ((sin(theta))^2.0 / (scy)^2.0)); 325 | scr = sqrt(scr); 326 | 327 | if (fail(i, j) == 1) 328 | dforce1 = bc * (nlength - idist) / idist * vol * scr * fac * (coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1)) / nlength; 329 | dforce2 = bc * (nlength - idist) / idist * vol * scr * fac * (coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2)) / nlength; 330 | else 331 | dforce1 = 0.0; 332 | dforce2 = 0.0; 333 | end 334 | pforce(i, 1) = pforce(i, 1) + dforce1; 335 | pforce(i, 2) = pforce(i, 2) + dforce2; 336 | 337 | % Definition of a no-fail zone 338 | if (abs((nlength - idist)/idist) > scr0) 339 | if (abs(coord(i, 2)) <= (length / 4.0)) 340 | fail(i, j) = 0; 341 | end 342 | end 343 | 344 | dmgpar1 = dmgpar1 + fail(i, j) * vol * fac; 345 | dmgpar2 = dmgpar2 + vol * fac; 346 | end 347 | % Calculation of the damage parameter 348 | dmg(i, 1) = 1.0 - dmgpar1 / dmgpar2; 349 | if ((dmg(i, 1) > maxdmg) && (coord(i, 1) > maxxc)) 350 | maxxc = coord(i, 1); 351 | end 352 | end 353 | 354 | newcrlength = maxxc - crlength / 2.0; 355 | 356 | for i = 1:totint 357 | % Calculation of acceleration of material point i 358 | acc(i, 1) = (pforce(i, 1) + bforce(i, 1)) / dens; 359 | acc(i, 2) = (pforce(i, 2) + bforce(i, 2)) / dens; 360 | % Calculation of velocity of material point i 361 | % by integrating the acceleration of material point i 362 | vel(i, 1) = vel(i, 1) + acc(i, 1) * dt; 363 | vel(i, 2) = vel(i, 2) + acc(i, 2) * dt; 364 | % Calculation of displacement of material point i 365 | % by integrating the velocity of material point i 366 | disp(i, 1) = disp(i, 1) + vel(i, 1) * dt; 367 | disp(i, 2) = disp(i, 2) + vel(i, 2) * dt; 368 | end 369 | 370 | for i = (totint + 1):totbottom 371 | acc(i, 1) = (pforce(i, 1) + bforce(i, 1)) / dens; 372 | vel(i, 1) = vel(i, 1) + acc(i, 1) * dt; 373 | disp(i, 1) = disp(i, 1) + vel(i, 1) * dt; 374 | end 375 | 376 | for i = (totbottom + 1):tottop 377 | acc(i, 1) = (pforce(i, 1) + bforce(i, 1)) / dens; 378 | vel(i, 1) = vel(i, 1) + acc(i, 1) * dt; 379 | disp(i, 1) = disp(i, 1) + vel(i, 1) * dt; 380 | end 381 | 382 | if (tt == 750) 383 | for i = 1:totint 384 | coord_disp_pd_750_pwc(i, 1:5) = [coord(i, 1), coord(i, 2), disp(i, 1), disp(i, 2), dmg(i, 1)]; 385 | end 386 | elseif (tt == 1000) 387 | for i = 1:totint 388 | coord_disp_pd_1000_pwc(i, 1:5) = [coord(i, 1), coord(i, 2), disp(i, 1), disp(i, 2), dmg(i, 1)]; 389 | end 390 | elseif (tt == 1250) 391 | for i = 1:totint 392 | coord_disp_pd_1250_pwc(i, 1:5) = [coord(i, 1), coord(i, 2), disp(i, 1), disp(i, 2), dmg(i, 1)]; 393 | end 394 | end 395 | 396 | crack_length(tt, 1:2) = [ctime, newcrlength]; 397 | end 398 | 399 | %% plot 400 | colormap jet; 401 | subplot(221) 402 | plot(crack_length(:, 1), crack_length(:, 2)) 403 | scale = 1; 404 | subplot(222) 405 | scatter(coord_disp_pd_750_pwc(:, 1)+scale*coord_disp_pd_750_pwc(:, 3), coord_disp_pd_750_pwc(:, 2)+scale*coord_disp_pd_750_pwc(:, 4), [], coord_disp_pd_750_pwc(:, 5), "filled") 406 | subplot(223) 407 | scatter(coord_disp_pd_1000_pwc(:, 1)+scale*coord_disp_pd_1000_pwc(:, 3), coord_disp_pd_1000_pwc(:, 2)+scale*coord_disp_pd_1000_pwc(:, 4), [], coord_disp_pd_1000_pwc(:, 5), "filled") 408 | subplot(224) 409 | scatter(coord_disp_pd_1250_pwc(:, 1)+scale*coord_disp_pd_1250_pwc(:, 3), coord_disp_pd_1250_pwc(:, 2)+scale*coord_disp_pd_1250_pwc(:, 4), [], coord_disp_pd_1250_pwc(:, 5), "filled") 410 | -------------------------------------------------------------------------------- /plate_with_a_hole_fail.m: -------------------------------------------------------------------------------- 1 | %% 2 | clear; 3 | clc; 4 | 5 | %% Specification of the locations of material points 6 | length = 0.05; 7 | % length: Total length of the bar 8 | width = 0.05; 9 | % width: Total width of the plate 10 | holerad = 0.005; 11 | % holerad: Hole radius 12 | ndivx = 100; 13 | % ndivx: Number of divisions in x direction - except boundary region 14 | ndivy = 100; 15 | % ndivy: Number of divisions in y direction - except boundary region 16 | 17 | dx = length / ndivx; 18 | % dx: Spacing between material points 19 | nbnd = 3; 20 | % nbnd: Number of divisions in the boundary region 21 | totnode = ndivx * (ndivy + 2*nbnd); 22 | % totnode: Total number of material points 23 | 24 | coord = zeros(totnode, 2); 25 | % coord: Material point locations 26 | 27 | nnum = 0; 28 | % nnum: Material point number 29 | 30 | % Material points of the internal region 31 | for i = 1:ndivy 32 | for j = 1:ndivx 33 | coordx = (-1.0*length/2.0) + (dx/2.0) + (j - 1)*dx; 34 | coordy = (-1.0*width/2.0) + (dx/2.0) + (i - 1)*dx; 35 | tmprad = sqrt((coordx)^2 + (coordy)^2); 36 | if (tmprad > holerad) 37 | nnum = nnum + 1; 38 | coord(nnum, 1) = coordx; 39 | coord(nnum, 2) = coordy; 40 | end 41 | end 42 | end 43 | 44 | totint = nnum; 45 | 46 | % Material points of the boundary region - bottom 47 | for i = 1:nbnd 48 | for j = 1: ndivx 49 | nnum = nnum + 1; 50 | coord(nnum, 1) = -1.0/2.0*length + (dx/2.0) + (j - 1)*dx; 51 | coord(nnum, 2) = -1.0/2.0*width - (dx/2.0) - (i - 1)*dx; 52 | end 53 | end 54 | 55 | totbottom = nnum; 56 | 57 | % Material points of the boundary region - top 58 | for i = 1: nbnd 59 | for j = 1: ndivx 60 | nnum = nnum + 1; 61 | coord(nnum, 1) = -1.0/2.0*length + (dx/2.0) + (j - 1)*dx; 62 | coord(nnum, 2) = 1.0/2.0*width + (dx/2.0) + (i - 1)*dx; 63 | end 64 | end 65 | 66 | tottop = nnum; 67 | totnode = nnum; 68 | 69 | 70 | %% Initialization of fail flag array 71 | maxfam = 100; 72 | % maxfam: Maximum number of material points inside a horizon of a material point 73 | 74 | fail = ones(totnode, maxfam); 75 | 76 | %% Determination of material points inside the horizon of each material point 77 | delta = 3.015 * dx; 78 | % delta: Horizon 79 | 80 | pointfam = int32(zeros(totnode, 1)); 81 | % pointfam: index array to find the family members in nodefam array 82 | numfam = int32(zeros(totnode, 1)); 83 | % numfam: Number of family members of each material point 84 | nodefam = int32(zeros(1000000, 1)); 85 | % nodefam: array containing family members of all material points 86 | 87 | for i = 1:totnode 88 | if (i == 1) 89 | pointfam(i, 1) = 1; 90 | else 91 | pointfam(i, 1) = pointfam(i - 1, 1) + numfam(i - 1, 1); 92 | end 93 | for j = 1:totnode 94 | % idist = norm(coord(j, :)-coord(i, :)); 95 | idist = sqrt((coord(j, 1) - coord(i, 1))^2+(coord(j, 2) - coord(i, 2))^2); 96 | if (i ~= j) 97 | if (idist <= delta) 98 | numfam(i, 1) = numfam(i, 1) + 1; 99 | nodefam(pointfam(i, 1)+numfam(i, 1)-1, 1) = j; 100 | end 101 | end 102 | end 103 | end 104 | 105 | %% Determination of surface correction factors 106 | radij = dx / 2.0; 107 | % radij: Material point radius 108 | area = dx * dx; 109 | % area: Cross-sectional area 110 | vol = area * dx; 111 | % vol: Volume of a material point 112 | thick = dx; 113 | % thick: Total thickness of the plate 114 | 115 | dens = 8000.0; 116 | % dens: Density 117 | emod = 192.0e9; 118 | % emod: Elastic modulus 119 | bc = 9.0 * emod / (pi * thick * (delta^3)); 120 | % bc: Bond constant 121 | 122 | disp = zeros(totnode, 2); 123 | % disp: displacement of a material point 124 | stendens = zeros(totnode, 2); 125 | % stendens: strain energy of a material point 126 | fncst = ones(totnode, 2); 127 | % fncst: surface correction factors of a material point, 1:loading 1, 2:loading 2 128 | 129 | % Loading 1 130 | sedload1 = 9.0 / 16.0 * emod * 1.0e-6; 131 | % sedload1: strain energy density of a material point for the first loading condition based on classical continuum mechanics 132 | 133 | for i = 1:totnode 134 | disp(i, 1) = 0.001 * coord(i, 1); 135 | disp(i, 2) = 0.0; 136 | end 137 | 138 | for i = 1:totnode 139 | stendens(i, 1) = 0.0; 140 | for j = 1:numfam(i, 1) 141 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 142 | % idist = norm(coord(cnode, :)-coord(i, :)); 143 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 144 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2); 145 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2); 146 | 147 | if (idist <= delta - radij) 148 | fac = 1.0; 149 | elseif (idist <= delta + radij) 150 | fac = (delta + radij - idist) / (2.0 * radij); 151 | else 152 | fac = 0.0; 153 | end 154 | 155 | stendens(i, 1) = stendens(i, 1) + 0.5 * 0.5 * bc * ((nlength - idist) / idist)^2 * idist * vol * fac; 156 | end 157 | % Calculation of surface correction factor in x direction 158 | % by finding the ratio of the analytical strain energy density value 159 | % to the strain energy density value obtained from PD Theory 160 | fncst(i, 1) = sedload1 / stendens(i, 1); 161 | end 162 | 163 | % Loading 2 164 | sedload2 = 9.0 / 16.0 * emod * 1.0e-6; 165 | % sedload2: strain energy density of a material point for the second loading condition based on classical continuum mechanics 166 | 167 | for i = 1:totnode 168 | disp(i, 1) = 0.0; 169 | disp(i, 2) = 0.001 * coord(i, 2); 170 | end 171 | 172 | for i = 1:totnode 173 | stendens(i, 2) = 0.0; 174 | for j = 1:numfam(i, 1) 175 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 176 | % idist = norm(coord(cnode, :)-coord(i, :)); 177 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 178 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2); 179 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2); 180 | 181 | if (idist <= delta - radij) 182 | fac = 1.0; 183 | elseif (idist <= delta + radij) 184 | fac = (delta + radij - idist) / (2.0 * radij); 185 | else 186 | fac = 0.0; 187 | end 188 | 189 | stendens(i, 2) = stendens(i, 2) + 0.5 * 0.5 * bc * ((nlength - idist) / idist)^2 * idist * vol * fac; 190 | end 191 | % Calculation of surface correction factor in x direction 192 | % by finding the ratio of the analytical strain energy density value 193 | % to the strain energy density value obtained from PD Theory 194 | fncst(i, 2) = sedload2 / stendens(i, 2); 195 | end 196 | 197 | %% Initialization of displacements and velocities 198 | vel = zeros(totnode, 2); 199 | disp = zeros(totnode, 2); 200 | 201 | %% Stable mass vector computation 202 | dt = 1.0; 203 | % dt: Time interval 204 | 205 | massvec = zeros(totnode, 2); 206 | % massvec: massvector for adaptive dynamic relaxation 207 | 208 | for i = 1:totnode 209 | % 5 is a safety factor 210 | massvec(i, 1) = 0.25 * dt * dt * (pi * (delta)^2 * thick) * bc / dx * 1.1;% * 5.0; 211 | massvec(i, 2) = 0.25 * dt * dt * (pi * (delta)^2 * thick) * bc / dx * 1.1;% * 5.0; 212 | end 213 | 214 | %% Applied loading - Left and Right 215 | appres = 200.0e6; 216 | % appres: Applied pressure 217 | 218 | bforce = zeros(totnode, 2); 219 | % bforce: body load acting on a material point 220 | 221 | 222 | %% Time integration 223 | nt = 1000; 224 | % nt: Total number of time step 225 | alpha = 23.0e-6; 226 | % alpha: Coefficient of thermal expansion 227 | dtemp = 0.0; 228 | % dtemp: Temperature change 229 | pratio = 1.0 / 3.0; 230 | % pratio: Poisson's ratio 231 | scr0 = 0.02; 232 | % scr0: Critical stretch 233 | 234 | dmg = zeros(totint, 1); 235 | 236 | pforce = zeros(totnode, 2); 237 | % pforce: total peridynamic force acting on a material point 238 | pforceold = zeros(totnode, 2); 239 | % pforceold: total peridynamic force acting on a material point in the previous time step 1:x-coord, 2:y-coord 240 | acc = zeros(totnode, 2); 241 | % acc: acceleration of a material point 242 | 243 | velhalf = zeros(totnode, 2); 244 | velhalfold = zeros(totnode, 2); 245 | % vel: velocity of a material point 246 | 247 | coord_disp_pd_nt_675 = zeros(totint, 5); 248 | % Peridynamic displacement and Analytical displacement of all points at time step of nt 249 | coord_disp_pd_nt_750 = zeros(totint, 5); 250 | % Peridynamic displacement and Analytical displacement of all points at time step of nt 251 | coord_disp_pd_nt_825 = zeros(totint, 5); 252 | % Peridynamic displacement and Analytical displacement of all points at time step of nt 253 | coord_disp_pd_nt_1000 = zeros(totint, 5); 254 | % Peridynamic displacement and Analytical displacement of all points at time step of nt 255 | 256 | cn = 0.0; 257 | cn1 = 0.0; 258 | cn2 = 0.0; 259 | for tt = 1:nt 260 | fprintf("%d/%d\n", tt, nt); 261 | ctime = tt * dt; 262 | 263 | % Application of boundary conditions at the top and bottom edges 264 | for i = (totint + 1): totbottom 265 | vel(i, 2) = -2.7541e-7; 266 | disp(i, 2) = -2.7541e-7*tt*dt; 267 | end 268 | 269 | for i = (totbottom + 1): tottop 270 | vel(i, 2) = 2.7541e-7; 271 | disp(i, 2) = 2.7541e-7*tt*dt; 272 | end 273 | 274 | 275 | for i = 1:totint 276 | dmgpar1 = 0.0; 277 | dmgpar2 = 0.0; 278 | pforce(i, 1) = 0.0; 279 | pforce(i, 2) = 0.0; 280 | for j = 1:numfam(i, 1) 281 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 282 | % idist = norm(coord(cnode, :)-coord(i, :)); 283 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 284 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2); 285 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2); 286 | 287 | % Volume correction 288 | if (idist <= delta - radij) 289 | fac = 1.0; 290 | elseif (idist <= delta + radij) 291 | fac = (delta + radij - idist) / (2.0 * radij); 292 | else 293 | fac = 0.0; 294 | end 295 | 296 | % Determination of the surface correction between two material points 297 | if (abs(coord(cnode, 2)-coord(i, 2)) <= 1.0e-10) 298 | theta = 0.0; 299 | elseif (abs(coord(cnode, 1)-coord(i, 1)) <= 1.0e-10) 300 | theta = 90.0 * pi / 180.0; 301 | else 302 | theta = atan(abs(coord(cnode, 2)-coord(i, 2))/abs(coord(cnode, 1)-coord(i, 1))); 303 | end 304 | scx = (fncst(i, 1) + fncst(cnode, 1)) / 2.0; 305 | scy = (fncst(i, 2) + fncst(cnode, 2)) / 2.0; 306 | scr = 1.0 / (((cos(theta))^2.0 / (scx)^2.0) + ((sin(theta))^2.0 / (scy)^2.0)); 307 | scr = sqrt(scr); 308 | 309 | if (fail(i, j) == 1) 310 | dforce1 = bc*(nlength - idist)/idist*vol*scr*fac*(coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))/nlength; 311 | dforce2 = bc*(nlength - idist)/idist*vol*scr*fac*(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))/nlength; 312 | else 313 | dforce1 = 0.0; 314 | dforce2 = 0.0; 315 | end 316 | pforce(i, 1) = pforce(i, 1) + dforce1; 317 | pforce(i, 2) = pforce(i, 2) + dforce2; 318 | 319 | % Definition of a no-fail zone 320 | if (abs((nlength - idist)/idist) > scr0) 321 | if (abs(coord(i, 2)) <= (length/4.0)) 322 | fail(i, j) = 0; 323 | end 324 | end 325 | 326 | dmgpar1 = dmgpar1 + fail(i, j)*vol*fac; 327 | dmgpar2 = dmgpar2 + vol*fac; 328 | end 329 | % Calculation of the damage parameter 330 | dmg(i, 1) = 1.0 - dmgpar1/dmgpar2; 331 | end 332 | 333 | % Adaptive dynamic relaxation ⬇⬇⬇ 334 | 335 | for i = 1:totint 336 | if (velhalfold(i, 1) ~= 0.0) 337 | cn1 = cn1 - disp(i, 1) * disp(i, 1) * (pforce(i, 1) / massvec(i, 1) - pforceold(i, 1) / massvec(i, 1)) / (dt * velhalfold(i, 1)); 338 | end 339 | if (velhalfold(i, 2) ~= 0.0) 340 | cn1 = cn1 - disp(i, 2) * disp(i, 2) * (pforce(i, 2) / massvec(i, 2) - pforceold(i, 2) / massvec(i, 2)) / (dt * velhalfold(i, 2)); 341 | end 342 | cn2 = cn2 + disp(i, 1) * disp(i, 1); 343 | cn2 = cn2 + disp(i, 2) * disp(i, 2); 344 | end 345 | 346 | if (cn2 ~= 0.0) 347 | if ((cn1 / cn2) > 0.0) 348 | cn = 2.0 * sqrt(cn1/cn2); 349 | else 350 | cn = 0.0; 351 | end 352 | else 353 | cn = 0.0; 354 | end 355 | 356 | if (cn > 2.0) 357 | cn = 1.9; 358 | end 359 | 360 | for i = 1:totint 361 | % Integrate acceleration over time. 362 | if (tt == 1) 363 | velhalf(i, 1) = 1.0 * dt / massvec(i, 1) * (pforce(i, 1) + bforce(i, 1)) / 2.0; 364 | velhalf(i, 2) = 1.0 * dt / massvec(i, 2) * (pforce(i, 2) + bforce(i, 2)) / 2.0; 365 | else 366 | velhalf(i, 1) = ((2.0 - cn * dt) * velhalfold(i, 1) + 2.0 * dt / massvec(i, 1) * (pforce(i, 1) + bforce(i, 1))) / (2.0 + cn * dt); 367 | velhalf(i, 2) = ((2.0 - cn * dt) * velhalfold(i, 2) + 2.0 * dt / massvec(i, 2) * (pforce(i, 2) + bforce(i, 2))) / (2.0 + cn * dt); 368 | end 369 | 370 | vel(i, 1) = 0.5 * (velhalfold(i, 1) + velhalf(i, 1)); 371 | vel(i, 2) = 0.5 * (velhalfold(i, 2) + velhalf(i, 2)); 372 | disp(i, 1) = disp(i, 1) + velhalf(i, 1) * dt; 373 | disp(i, 2) = disp(i, 2) + velhalf(i, 2) * dt; 374 | 375 | velhalfold(i, 1) = velhalf(i, 1); 376 | velhalfold(i, 2) = velhalf(i, 2); 377 | pforceold(i, 1) = pforce(i, 1); 378 | pforceold(i, 2) = pforce(i, 2); 379 | end 380 | 381 | % Adaptive dynamic relaxation ⬆⬆⬆ 382 | 383 | if (tt == nt) 384 | for i = 1:totint 385 | coord_disp_pd_nt_1000(i, 1:5) = [coord(i, 1), coord(i, 2), disp(i, 1), disp(i, 2), dmg(i, 1)]; 386 | end 387 | elseif (tt == 675) 388 | for i = 1:totint 389 | coord_disp_pd_nt_675(i, 1:5) = [coord(i, 1), coord(i, 2), disp(i, 1), disp(i, 2), dmg(i, 1)]; 390 | end 391 | elseif (tt == 750) 392 | for i = 1:totint 393 | coord_disp_pd_nt_750(i, 1:5) = [coord(i, 1), coord(i, 2), disp(i, 1), disp(i, 2), dmg(i, 1)]; 394 | end 395 | elseif (tt == 825) 396 | for i = 1:totint 397 | coord_disp_pd_nt_825(i, 1:5) = [coord(i, 1), coord(i, 2), disp(i, 1), disp(i, 2), dmg(i, 1)]; 398 | end 399 | end 400 | end 401 | 402 | %% plot 403 | colormap jet; 404 | subplot(221) 405 | scale = 1; 406 | scatter(coord_disp_pd_nt_675(:, 1)+scale*coord_disp_pd_nt_675(:, 3), coord_disp_pd_nt_675(:, 2)+scale*coord_disp_pd_nt_675(:, 4), [], coord_disp_pd_nt_675(:, 5), "filled") 407 | subplot(222) 408 | scale = 1; 409 | scatter(coord_disp_pd_nt_750(:, 1)+scale*coord_disp_pd_nt_750(:, 3), coord_disp_pd_nt_750(:, 2)+scale*coord_disp_pd_nt_750(:, 4), [], coord_disp_pd_nt_750(:, 5), "filled") 410 | subplot(223) 411 | scale = 1; 412 | scatter(coord_disp_pd_nt_825(:, 1)+scale*coord_disp_pd_nt_825(:, 3), coord_disp_pd_nt_825(:, 2)+scale*coord_disp_pd_nt_825(:, 4), [], coord_disp_pd_nt_825(:, 5), "filled") 413 | subplot(224) 414 | scale = 1; 415 | scatter(coord_disp_pd_nt_1000(:, 1)+scale*coord_disp_pd_nt_1000(:, 3), coord_disp_pd_nt_1000(:, 2)+scale*coord_disp_pd_nt_1000(:, 4), [], coord_disp_pd_nt_1000(:, 5), "filled") 416 | -------------------------------------------------------------------------------- /block_under_tension.m: -------------------------------------------------------------------------------- 1 | %% 2 | clear; 3 | clc; 4 | 5 | %% Specification of the locations of material points 6 | length = 1.0; 7 | % length: Total length of the block 8 | width = 0.1; 9 | % width: Total width of the block 10 | thick = 0.1; 11 | % thick: Total thickness of the block 12 | ndivx = 100; 13 | % ndivx: Number of divisions in x direction - except boundary region 14 | ndivy = 10; 15 | % ndivy: Number of divisions in y direction - except boundary region 16 | ndivz = 10; 17 | % ndivz: Number of divisions in z direction - except boundary region 18 | dx = length / ndivx; 19 | % dx: Spacing between material points 20 | nbnd = 3; 21 | % nbnd: Number of divisions in the boundary region 22 | totnode = (ndivx + nbnd) * ndivy * ndivz; 23 | % totnode: Total number of material points 24 | 25 | coord = zeros(totnode, 3); 26 | % coord: Material point locations 27 | alflag = zeros(totnode, 1); 28 | % flag the points in boundary zone 29 | 30 | 31 | nnum = 0; 32 | % nnum: Material point number 33 | 34 | % Material points of the block 35 | for i = 1:ndivz 36 | for j = 1:ndivy 37 | for k = 1:ndivx 38 | coordx = (dx / 2.0) + (k - 1) * dx; 39 | coordy = -1.0 / 2.0 * width + (dx / 2.0) + (j - 1) * dx; 40 | coordz = -1.0 / 2.0 * thick + (dx / 2.0) + (i - 1) * dx; 41 | nnum = nnum + 1; 42 | coord(nnum, 1) = coordx; 43 | coord(nnum, 2) = coordy; 44 | coord(nnum, 3) = coordz; 45 | if (coordx > (length - dx)) 46 | alflag(nnum, 1) = 1; 47 | end 48 | end 49 | end 50 | end 51 | 52 | totint = nnum; 53 | 54 | % Material points of the boundary region - left 55 | for i = 1:ndivz 56 | for j = 1:ndivy 57 | for k = 1:nbnd 58 | coordx = -(dx / 2.0) - (k - 1) * dx; 59 | coordy = -1.0 / 2.0 * width + (dx / 2.0) + (j - 1) * dx; 60 | coordz = -1.0 / 2.0 * thick + (dx / 2.0) + (i - 1) * dx; 61 | nnum = nnum + 1; 62 | coord(nnum, 1) = coordx; 63 | coord(nnum, 2) = coordy; 64 | coord(nnum, 3) = coordz; 65 | end 66 | end 67 | end 68 | 69 | %% Determination of material points inside the horizon of each material point 70 | delta = 3.015 * dx; 71 | % delta: Horizon 72 | 73 | pointfam = int32(zeros(totnode, 1)); 74 | % pointfam: index array to find the family members in nodefam array 75 | numfam = int32(zeros(totnode, 1)); 76 | % numfam: Number of family members of each material point 77 | nodefam = int32(zeros(1000000, 1)); 78 | % nodefam: array containing family members of all material points 79 | 80 | for i = 1:totnode 81 | if (i == 1) 82 | pointfam(i, 1) = 1; 83 | else 84 | pointfam(i, 1) = pointfam(i - 1, 1) + numfam(i - 1, 1); 85 | end 86 | for j = 1:totnode 87 | % idist = norm(coord(j, :)-coord(i, :)); 88 | idist = sqrt((coord(j, 1) - coord(i, 1))^2+(coord(j, 2) - coord(i, 2))^2+(coord(j, 3) - coord(i, 3))^2); 89 | if (i ~= j) 90 | if (idist <= delta) 91 | numfam(i, 1) = numfam(i, 1) + 1; 92 | nodefam(pointfam(i, 1)+numfam(i, 1)-1, 1) = j; 93 | end 94 | end 95 | end 96 | end 97 | 98 | %% Determination of surface correction factors 99 | radij = dx / 2.0; 100 | % radij: Material point radius 101 | area = dx * dx; 102 | % area: Cross-sectional area 103 | vol = area * dx; 104 | % vol: Volume of a material point 105 | 106 | 107 | dens = 7850.0; 108 | % dens: Density 109 | emod = 200.0e9; 110 | % emod: Elastic modulus 111 | bc = 12.0 * emod / (pi * (delta^4)); 112 | % bc: Bond constant 113 | 114 | disp = zeros(totnode, 3); 115 | % disp: displacement of a material point, 1:x-coord, 2:y-coord, 3:z-coord 116 | stendens = zeros(totnode, 3); 117 | % stendens: strain energy of a material point, 1:loading 1, 2:loading 2, 3:loading 3 118 | fncst = ones(totnode, 3); 119 | % fncst: surface correction factors of a material point, 1:loading 1, 2:loading 2, 3:loading 3 120 | 121 | % Loading 1 122 | sedload1 = 0.6 * emod * 1.0e-6; 123 | % sedload1: Strain energy density of a material point for the first loading condition 124 | 125 | for i = 1:totnode 126 | disp(i, 1) = 0.001 * coord(i, 1); 127 | disp(i, 2) = 0.0; 128 | disp(i, 3) = 0.0; 129 | end 130 | 131 | for i = 1:totnode 132 | stendens(i, 1) = 0.0; 133 | for j = 1:numfam(i, 1) 134 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 135 | % idist = norm(coord(cnode, :)-coord(i, :)); 136 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 137 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2+(coord(cnode, 3) - coord(i, 3))^2); 138 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2+(coord(cnode, 3) + disp(cnode, 3) - coord(i, 3) - disp(i, 3))^2); 139 | 140 | if (idist <= delta - radij) 141 | fac = 1.0; 142 | elseif (idist <= delta + radij) 143 | fac = (delta + radij - idist) / (2.0 * radij); 144 | else 145 | fac = 0.0; 146 | end 147 | 148 | stendens(i, 1) = stendens(i, 1) + 0.5 * 0.5 * bc * ((nlength - idist) / idist)^2 * idist * vol * fac; 149 | end 150 | % Calculation of surface correction factor in x direction 151 | % by finding the ratio of the analytical strain energy density value 152 | % to the strain energy density value obtained from PD Theory 153 | fncst(i, 1) = sedload1 / stendens(i, 1); 154 | end 155 | 156 | % Loading 2 157 | sedload2 = 0.6 * emod * 1.0e-6; 158 | % sedload2: Strain energy density of a material point for the second loading condition 159 | 160 | for i = 1:totnode 161 | disp(i, 1) = 0.0; 162 | disp(i, 2) = 0.001 * coord(i, 2); 163 | disp(i, 3) = 0.0; 164 | end 165 | 166 | for i = 1:totnode 167 | stendens(i, 2) = 0.0; 168 | for j = 1:numfam(i, 1) 169 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 170 | % idist = norm(coord(cnode, :)-coord(i, :)); 171 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 172 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2+(coord(cnode, 3) - coord(i, 3))^2); 173 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2+(coord(cnode, 3) + disp(cnode, 3) - coord(i, 3) - disp(i, 3))^2); 174 | 175 | if (idist <= delta - radij) 176 | fac = 1.0; 177 | elseif (idist <= delta + radij) 178 | fac = (delta + radij - idist) / (2.0 * radij); 179 | else 180 | fac = 0.0; 181 | end 182 | 183 | stendens(i, 2) = stendens(i, 2) + 0.5 * 0.5 * bc * ((nlength - idist) / idist)^2 * idist * vol * fac; 184 | end 185 | % Calculation of surface correction factor in x direction 186 | % by finding the ratio of the analytical strain energy density value 187 | % to the strain energy density value obtained from PD Theory 188 | fncst(i, 2) = sedload2 / stendens(i, 2); 189 | end 190 | 191 | % Loading 3 192 | sedload3 = 0.6 * emod * 1.0e-6; 193 | % sedload3: Strain energy density of a material point for the third loading condition 194 | 195 | for i = 1:totnode 196 | disp(i, 1) = 0.0; 197 | disp(i, 2) = 0.0; 198 | disp(i, 3) = 0.001 * coord(i, 3); 199 | end 200 | 201 | for i = 1:totnode 202 | stendens(i, 3) = 0.0; 203 | for j = 1:numfam(i, 1) 204 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 205 | % idist = norm(coord(cnode, :)-coord(i, :)); 206 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 207 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2+(coord(cnode, 3) - coord(i, 3))^2); 208 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2+(coord(cnode, 3) + disp(cnode, 3) - coord(i, 3) - disp(i, 3))^2); 209 | 210 | if (idist <= delta - radij) 211 | fac = 1.0; 212 | elseif (idist <= delta + radij) 213 | fac = (delta + radij - idist) / (2.0 * radij); 214 | else 215 | fac = 0.0; 216 | end 217 | 218 | stendens(i, 3) = stendens(i, 3) + 0.5 * 0.5 * bc * ((nlength - idist) / idist)^2 * idist * vol * fac; 219 | end 220 | % Calculation of surface correction factor in x direction 221 | % by finding the ratio of the analytical strain energy density value 222 | % to the strain energy density value obtained from PD Theory 223 | fncst(i, 3) = sedload3 / stendens(i, 3); 224 | end 225 | 226 | %% Initialization of displacements and velocities 227 | vel = zeros(totnode, 3); 228 | disp = zeros(totnode, 3); 229 | 230 | %% Stable mass vector computation 231 | dt = 1.0; 232 | % dt: Time interval 233 | 234 | massvec = zeros(totnode, 3); 235 | % massvec: massvector for adaptive dynamic relaxation 236 | 237 | for i = 1:totnode 238 | % 5 is a safety factor 239 | massvec(i, 1) = 0.25 * dt * dt * ((4.0 / 3.0) * pi * (delta)^3) * bc / dx; 240 | massvec(i, 2) = 0.25 * dt * dt * ((4.0 / 3.0) * pi * (delta)^3) * bc / dx; 241 | massvec(i, 3) = 0.25 * dt * dt * ((4.0 / 3.0) * pi * (delta)^3) * bc / dx; 242 | end 243 | 244 | %% Applied loading - Right 245 | appres = 200.0e6; 246 | % appres: Applied pressure 247 | 248 | bforce = zeros(totnode, 3); 249 | % bforce: body load acting on a material point 250 | 251 | % right 252 | for i = 1:totint 253 | if (alflag(i, 1) == 1) 254 | bforce(i, 1) = appres / (dx); 255 | end 256 | end 257 | 258 | %% Time integration 259 | nt = 1000; 260 | % nt: Total number of time step 261 | alpha = 23.0e-6; 262 | % alpha: Coefficient of thermal expansion 263 | dtemp = 0.0; 264 | % dtemp: Temperature change 265 | pratio = 1.0 / 4.0; 266 | % pratio: Poisson's ratio 267 | 268 | pforce = zeros(totnode, 3); 269 | % pforce: total peridynamic force acting on a material point 270 | pforceold = zeros(totnode, 3); 271 | % pforceold: total peridynamic force acting on a material point in the previous time step 1:x-coord, 2:y-coord 272 | acc = zeros(totnode, 3); 273 | % acc: acceleration of a material point 274 | 275 | velhalf = zeros(totnode, 3); 276 | velhalfold = zeros(totnode, 3); 277 | % vel: velocity of a material point 278 | 279 | coord_disp_pd_ntbt = zeros(totint, 6); 280 | % Peridynamic displacement and Analytical displacement of all points at time step of nt 281 | horiCnt = 0; 282 | horizontal_dispsbt = zeros(ndivx, 9); 283 | % Peridynamic displacement and Analytical displacement of points at y = 0; 284 | vertiCnt = 0; 285 | vertical_dispsbt = zeros(ndivy, 9); 286 | % Peridynamic displacement and Analytical displacement of points at x = 0; 287 | transCnt = 0; 288 | transverse_dispsbt = zeros(ndivz, 9); 289 | 290 | steady_check = zeros(nt, 4); 291 | 292 | 293 | cn = 0.0; 294 | cn1 = 0.0; 295 | cn2 = 0.0; 296 | for tt = 1:nt 297 | fprintf("%d/%d\n", tt, nt); 298 | 299 | for i = 1:totint 300 | pforce(i, 1) = 0.0; 301 | pforce(i, 2) = 0.0; 302 | pforce(i, 3) = 0.0; 303 | for j = 1:numfam(i, 1) 304 | cnode = nodefam(pointfam(i, 1)+j-1, 1); 305 | % idist = norm(coord(cnode, :)-coord(i, :)); 306 | % nlength = norm((coord(cnode, :) + disp(cnode, :))-(coord(i, :) + disp(i, :))); 307 | idist = sqrt((coord(cnode, 1) - coord(i, 1))^2+(coord(cnode, 2) - coord(i, 2))^2+(coord(cnode, 3) - coord(i, 3))^2); 308 | nlength = sqrt((coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1))^2+(coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2))^2+(coord(cnode, 3) + disp(cnode, 3) - coord(i, 3) - disp(i, 3))^2); 309 | 310 | % Volume correction 311 | if (idist <= delta - radij) 312 | fac = 1.0; 313 | elseif (idist <= delta + radij) 314 | fac = (delta + radij - idist) / (2.0 * radij); 315 | else 316 | fac = 0.0; 317 | end 318 | 319 | % Determination of the surface correction between two material points 320 | if (abs(coord(cnode, 3)-coord(i, 3)) <= 1.0e-10) 321 | if (abs(coord(cnode, 2)-coord(i, 2)) <= 1.0e-10) 322 | theta = 0.0; 323 | elseif (abs(coord(cnode, 1)-coord(i, 1)) <= 1.0e-10) 324 | theta = 90.0 * pi / 180.0; 325 | else 326 | theta = atan(abs(coord(cnode, 2)-coord(i, 2))/abs(coord(cnode, 1)-coord(i, 1))); 327 | end 328 | phi = 90.0 * pi / 180.0; 329 | 330 | scx = (fncst(i, 1) + fncst(cnode, 1)) / 2.0; 331 | scy = (fncst(i, 2) + fncst(cnode, 2)) / 2.0; 332 | scz = (fncst(i, 3) + fncst(cnode, 3)) / 2.0; 333 | scr = 1.0 / (((cos(theta) * sin(phi))^2 / (scx)^2) + ((sin(theta) * sin(phi))^2 / (scy)^2) + ((cos(phi))^2 / (scz)^2)); 334 | scr = sqrt(scr); 335 | elseif ((abs(coord(cnode, 1)-coord(i, 1)) <= 1.0e-10) && (abs(coord(cnode, 2)-coord(i, 2)) <= 1.0e-10)) 336 | scz = (fncst(i, 3) + fncst(cnode, 3)) / 2.0; 337 | scr = scz; 338 | else 339 | theta = atan(abs(coord(cnode, 2)-coord(i, 2))/abs(coord(cnode, 1)-coord(i, 1))); 340 | phi = acos(abs(coord(cnode, 3)-coord(i, 3))/idist); 341 | 342 | scx = (fncst(i, 1) + fncst(cnode, 1)) / 2.0; 343 | scy = (fncst(i, 2) + fncst(cnode, 2)) / 2.0; 344 | scz = (fncst(i, 3) + fncst(cnode, 3)) / 2.0; 345 | scr = 1.0 / (((cos(theta) * sin(phi))^2 / (scx)^2) + ((sin(theta) * sin(phi))^2 / (scy)^2) + ((cos(phi))^2 / (scz)^2)); 346 | scr = sqrt(scr); 347 | end 348 | 349 | % Calculation of the peridynamic force in x direction acting on a material point i due to a material point j 350 | dforce1 = bc * ((nlength - idist) / idist - (alpha * dtemp)) * vol * scr * fac * (coord(cnode, 1) + disp(cnode, 1) - coord(i, 1) - disp(i, 1)) / nlength; 351 | dforce2 = bc * ((nlength - idist) / idist - (alpha * dtemp)) * vol * scr * fac * (coord(cnode, 2) + disp(cnode, 2) - coord(i, 2) - disp(i, 2)) / nlength; 352 | dforce3 = bc * ((nlength - idist) / idist - (alpha * dtemp)) * vol * scr * fac * (coord(cnode, 3) + disp(cnode, 3) - coord(i, 3) - disp(i, 3)) / nlength; 353 | 354 | pforce(i, 1) = pforce(i, 1) + dforce1; 355 | pforce(i, 2) = pforce(i, 2) + dforce2; 356 | pforce(i, 3) = pforce(i, 3) + dforce3; 357 | end 358 | end 359 | 360 | % Adaptive dynamic relaxation ⬇⬇⬇ 361 | 362 | for i = 1:totint 363 | if (velhalfold(i, 1) ~= 0.0) 364 | cn1 = cn1 - disp(i, 1) * disp(i, 1) * (pforce(i, 1) / massvec(i, 1) - pforceold(i, 1) / massvec(i, 1)) / (dt * velhalfold(i, 1)); 365 | end 366 | if (velhalfold(i, 2) ~= 0.0) 367 | cn1 = cn1 - disp(i, 2) * disp(i, 2) * (pforce(i, 2) / massvec(i, 2) - pforceold(i, 2) / massvec(i, 2)) / (dt * velhalfold(i, 2)); 368 | end 369 | if (velhalfold(i, 3) ~= 0.0) 370 | cn1 = cn1 - disp(i, 3) * disp(i, 3) * (pforce(i, 3) / massvec(i, 3) - pforceold(i, 3) / massvec(i, 3)) / (dt * velhalfold(i, 3)); 371 | end 372 | cn2 = cn2 + disp(i, 1) * disp(i, 1); 373 | cn2 = cn2 + disp(i, 2) * disp(i, 2); 374 | cn2 = cn2 + disp(i, 3) * disp(i, 3); 375 | end 376 | 377 | if (cn2 ~= 0.0) 378 | if ((cn1 / cn2) > 0.0) 379 | cn = 2.0 * sqrt(cn1/cn2); 380 | else 381 | cn = 0.0; 382 | end 383 | else 384 | cn = 0.0; 385 | end 386 | 387 | if (cn > 2.0) 388 | cn = 1.9; 389 | end 390 | 391 | for i = 1:totint 392 | % Integrate acceleration over time. 393 | if (tt == 1) 394 | velhalf(i, 1) = 1.0 * dt / massvec(i, 1) * (pforce(i, 1) + bforce(i, 1)) / 2.0; 395 | velhalf(i, 2) = 1.0 * dt / massvec(i, 2) * (pforce(i, 2) + bforce(i, 2)) / 2.0; 396 | velhalf(i, 3) = 1.0 * dt / massvec(i, 3) * (pforce(i, 3) + bforce(i, 3)) / 2.0; 397 | else 398 | velhalf(i, 1) = ((2.0 - cn * dt) * velhalfold(i, 1) + 2.0 * dt / massvec(i, 1) * (pforce(i, 1) + bforce(i, 1))) / (2.0 + cn * dt); 399 | velhalf(i, 2) = ((2.0 - cn * dt) * velhalfold(i, 2) + 2.0 * dt / massvec(i, 2) * (pforce(i, 2) + bforce(i, 2))) / (2.0 + cn * dt); 400 | velhalf(i, 3) = ((2.0 - cn * dt) * velhalfold(i, 3) + 2.0 * dt / massvec(i, 3) * (pforce(i, 3) + bforce(i, 3))) / (2.0 + cn * dt); 401 | end 402 | 403 | vel(i, 1) = 0.5 * (velhalfold(i, 1) + velhalf(i, 1)); 404 | vel(i, 2) = 0.5 * (velhalfold(i, 2) + velhalf(i, 2)); 405 | vel(i, 3) = 0.5 * (velhalfold(i, 3) + velhalf(i, 3)); 406 | 407 | disp(i, 1) = disp(i, 1) + velhalf(i, 1) * dt; 408 | disp(i, 2) = disp(i, 2) + velhalf(i, 2) * dt; 409 | disp(i, 3) = disp(i, 3) + velhalf(i, 3) * dt; 410 | 411 | velhalfold(i, 1) = velhalf(i, 1); 412 | velhalfold(i, 2) = velhalf(i, 2); 413 | velhalfold(i, 3) = velhalf(i, 3); 414 | pforceold(i, 1) = pforce(i, 1); 415 | pforceold(i, 2) = pforce(i, 2); 416 | pforceold(i, 3) = pforce(i, 3); 417 | end 418 | 419 | % Adaptive dynamic relaxation ⬆⬆⬆ 420 | 421 | if (tt == nt) 422 | for i = 1:totint 423 | coord_disp_pd_ntbt(i, 1:6) = [coord(i, 1), coord(i, 2), coord(i, 3), disp(i, 1), disp(i, 2), disp(i, 3)]; 424 | if ((abs(coord(i, 2)-(dx / 2.0)) <= 1.0e-8) && (abs(coord(i, 3)-(dx / 2.0)) <= 1.0e-8)) 425 | horiCnt = horiCnt + 1; 426 | horizontal_dispsbt(horiCnt, 1:9) = [coord(i, 1:3), ... 427 | disp(i, 1:3), ... 428 | 0.001 * coord(i, 1), -1.0 * 0.001 * pratio * coord(i, 2), -1.0 * 0.001 * pratio * coord(i, 3)]; 429 | end 430 | if ((abs(coord(i, 1)-(length / 2.0 + dx / 2.0)) <= 1.0e-8) && (abs(coord(i, 3)-(dx / 2.0)) <= 1.0e-8)) 431 | vertiCnt = vertiCnt + 1; 432 | vertical_dispsbt(vertiCnt, 1:9) = [coord(i, 1:3), ... 433 | disp(i, 1:3), ... 434 | 0.001 * coord(i, 1), -1.0 * 0.001 * pratio * coord(i, 2), -1.0 * 0.001 * pratio * coord(i, 3)]; 435 | end 436 | if ((abs(coord(i, 1)-(length / 2.0 + dx / 2.0)) <= 1.0e-8) && (abs(coord(i, 2)-(dx / 2.0)) <= 1.0e-8)) 437 | transCnt = transCnt + 1; 438 | transverse_dispsbt(transCnt, 1:9) = [coord(i, 1:3), ... 439 | disp(i, 1:3), ... 440 | 0.001 * coord(i, 1), -1.0 * 0.001 * pratio * coord(i, 2), -1.0 * 0.001 * pratio * coord(i, 3)]; 441 | end 442 | end 443 | end 444 | 445 | steady_check(tt, 1:4) = [tt, disp(7770, 1:3)]; 446 | end 447 | 448 | %% plot 449 | colormap jet; 450 | factor = 1000; 451 | subplot(241) 452 | scatter3(coord_disp_pd_ntbt(:, 1)+factor*coord_disp_pd_ntbt(:, 4), ... 453 | coord_disp_pd_ntbt(:, 2)+factor*coord_disp_pd_ntbt(:, 5), ... 454 | coord_disp_pd_ntbt(:, 3)+factor*coord_disp_pd_ntbt(:, 6), [], ... 455 | sqrt(coord_disp_pd_ntbt(:, 4).^2+coord_disp_pd_ntbt(:, 5).^2+coord_disp_pd_ntbt(:, 6).^2), "filled") 456 | subplot(242) 457 | scatter3(coord_disp_pd_ntbt(:, 1)+factor*coord_disp_pd_ntbt(:, 4), ... 458 | coord_disp_pd_ntbt(:, 2)+factor*coord_disp_pd_ntbt(:, 5), ... 459 | coord_disp_pd_ntbt(:, 3)+factor*coord_disp_pd_ntbt(:, 6), [], ... 460 | coord_disp_pd_ntbt(:, 4), "filled") 461 | subplot(245) 462 | scatter3(coord_disp_pd_ntbt(:, 1)+factor*coord_disp_pd_ntbt(:, 4), ... 463 | coord_disp_pd_ntbt(:, 2)+factor*coord_disp_pd_ntbt(:, 5), ... 464 | coord_disp_pd_ntbt(:, 3)+factor*coord_disp_pd_ntbt(:, 6), [], ... 465 | coord_disp_pd_ntbt(:, 5), "filled") 466 | subplot(246) 467 | scatter3(coord_disp_pd_ntbt(:, 1)+factor*coord_disp_pd_ntbt(:, 4), ... 468 | coord_disp_pd_ntbt(:, 2)+factor*coord_disp_pd_ntbt(:, 5), ... 469 | coord_disp_pd_ntbt(:, 3)+factor*coord_disp_pd_ntbt(:, 6), [], ... 470 | coord_disp_pd_ntbt(:, 6), "filled") 471 | subplot(243) 472 | plot(steady_check(:, 1), steady_check(:, 2), steady_check(:, 1), steady_check(:, 3), steady_check(:, 1), steady_check(:, 4)) 473 | subplot(244) 474 | plot(horizontal_dispsbt(:, 1), horizontal_dispsbt(:, 4), horizontal_dispsbt(:, 1), horizontal_dispsbt(:, 7)) 475 | subplot(247) 476 | plot(vertical_dispsbt(:, 2), vertical_dispsbt(:, 5), vertical_dispsbt(:, 2), vertical_dispsbt(:, 8)) 477 | subplot(248) 478 | plot(transverse_dispsbt(:, 3), transverse_dispsbt(:, 6), transverse_dispsbt(:, 3), transverse_dispsbt(:, 9)) 479 | --------------------------------------------------------------------------------