diff --git a/newdamp/Stokes2D_vep_reg.jl b/newdamp/Stokes2D_vep_reg.jl new file mode 100644 index 0000000..b55b799 --- /dev/null +++ b/newdamp/Stokes2D_vep_reg.jl @@ -0,0 +1,168 @@ +# Initialisation +using Plots, Printf, Statistics, LinearAlgebra +Dat = Float64 # Precision (double=Float64 or single=Float32) +# Macros +@views av(A) = 0.25*(A[1:end-1,1:end-1].+A[2:end,1:end-1].+A[1:end-1,2:end].+A[2:end,2:end]) +@views av_xa(A) = 0.5*(A[1:end-1,:].+A[2:end,:]) +@views av_ya(A) = 0.5*(A[:,1:end-1].+A[:,2:end]) +# 2D Stokes routine +@views function Stokes2D_vep() + do_DP = true # do_DP=false: Von Mises, do_DP=true: Drucker-Prager (friction angle) + η_reg = 1.2e-2 # regularisation "viscosity" + # Physics + Lx, Ly = 1.0, 1.0 # domain size + radi = 0.01 # inclusion radius + τ_y = 1.6 # yield stress. If do_DP=true, τ_y stand for the cohesion: c*cos(ϕ) + sinϕ = sind(30)*do_DP # sinus of the friction angle + μ0 = 1.0 # viscous viscosity + G0 = 1.0 # elastic shear modulus + Gi = G0/(6.0-4.0*do_DP) # elastic shear modulus perturbation + εbg = 1.0 # background strain-rate + # Numerics + nt = 10 # number of time steps + nx, ny = 63, 63 # numerical grid resolution + Vdmp = 4.0 # convergence acceleration (damping) + Vsc = 2.0 # iterative time step limiter + Ptsc = 6.0 # iterative time step limiter + ε = 1e-6 # nonlinear tolerence + iterMax = 3e4 # max number of iters + nout = 200 # check frequency + # Preprocessing + dx, dy = Lx/nx, Ly/ny + dt = μ0/G0/4.0 # assumes Maxwell time of 4 + # Array initialisation + Pt = zeros(Dat, nx ,ny ) + ∇V = zeros(Dat, nx ,ny ) + Vx = zeros(Dat, nx+1,ny ) + Vy = zeros(Dat, nx ,ny+1) + Exx = zeros(Dat, nx ,ny ) + Eyy = zeros(Dat, nx ,ny ) + Exyv = zeros(Dat, nx+1,ny+1) + Exx1 = zeros(Dat, nx ,ny ) + Eyy1 = zeros(Dat, nx ,ny ) + Exy1 = zeros(Dat, nx ,ny ) + Exyv1 = zeros(Dat, nx+1,ny+1) + Txx = zeros(Dat, nx ,ny ) + Tyy = zeros(Dat, nx ,ny ) + Txy = zeros(Dat, nx ,ny ) + Txyv = zeros(Dat, nx+1,ny+1) + Txx_o = zeros(Dat, nx ,ny ) + Tyy_o = zeros(Dat, nx ,ny ) + Txy_o = zeros(Dat, nx ,ny ) + Txyv_o = zeros(Dat, nx+1,ny+1) + Tii = zeros(Dat, nx ,ny ) + Eii = zeros(Dat, nx ,ny ) + F = zeros(Dat, nx ,ny ) + Fchk = zeros(Dat, nx ,ny ) + Pla = zeros(Dat, nx ,ny ) + λ = zeros(Dat, nx ,ny ) + dQdTxx = zeros(Dat, nx ,ny ) + dQdTyy = zeros(Dat, nx ,ny ) + dQdTxy = zeros(Dat, nx ,ny ) + Rx = zeros(Dat, nx-1,ny ) + Ry = zeros(Dat, nx ,ny-1) + dVxdt = zeros(Dat, nx-1,ny ) + dVydt = zeros(Dat, nx ,ny-1) + dtPt = zeros(Dat, nx ,ny ) + dtVx = zeros(Dat, nx-1,ny ) + dtVy = zeros(Dat, nx ,ny-1) + Rog = zeros(Dat, nx ,ny ) + η_v = μ0*ones(Dat, nx, ny) + η_e = dt*G0*ones(Dat, nx, ny) + η_ev = dt*G0*ones(Dat, nx+1, ny+1) + η_ve = ones(Dat, nx, ny) + η_vep = ones(Dat, nx, ny) + η_vepv = ones(Dat, nx+1, ny+1) + # Initial condition + xc, yc = LinRange(dx/2, Lx-dx/2, nx), LinRange(dy/2, Ly-dy/2, ny) + xc, yc = LinRange(dx/2, Lx-dx/2, nx), LinRange(dy/2, Ly-dy/2, ny) + xv, yv = LinRange(0.0, Lx, nx+1), LinRange(0.0, Ly, ny+1) + (Xvx,Yvx) = ([x for x=xv,y=yc], [y for x=xv,y=yc]) + (Xvy,Yvy) = ([x for x=xc,y=yv], [y for x=xc,y=yv]) + radc = (xc.-Lx./2).^2 .+ (yc'.-Ly./2).^2 + radv = (xv.-Lx./2).^2 .+ (yv'.-Ly./2).^2 + η_e[radc.ε && iter<=iterMax) + # divergence - pressure + ∇V .= diff(Vx, dims=1)./dx .+ diff(Vy, dims=2)./dy + Pt .= Pt .- dtPt.*∇V + # strain rates + Exx .= diff(Vx, dims=1)./dx .- 1.0/3.0*∇V + Eyy .= diff(Vy, dims=2)./dy .- 1.0/3.0*∇V + Exyv[2:end-1,2:end-1] .= 0.5.*(diff(Vx[2:end-1,:], dims=2)./dy .+ diff(Vy[:,2:end-1], dims=1)./dx) + # visco-elastic strain rates + Exx1 .= Exx .+ Txx_o ./2.0./η_e + Eyy1 .= Eyy .+ Tyy_o ./2.0./η_e + Exyv1 .= Exyv .+ Txyv_o./2.0./η_ev + Exy1 .= av(Exyv) .+ Txy_o ./2.0./η_e + Eii .= sqrt.(0.5*(Exx1.^2 .+ Eyy1.^2) .+ Exy1.^2) + # trial stress + Txx .= 2.0.*η_ve.*Exx1 + Tyy .= 2.0.*η_ve.*Eyy1 + Txy .= 2.0.*η_ve.*Exy1 + Tii .= sqrt.(0.5*(Txx.^2 .+ Tyy.^2) .+ Txy.^2) + # yield function + F .= Tii .- τ_y .- Pt.*sinϕ + Pla .= 0.0 + Pla .= F .> 0.0 + λ .= Pla.*F./(η_ve .+ η_reg) + dQdTxx .= 0.5.*Txx./Tii + dQdTyy .= 0.5.*Tyy./Tii + dQdTxy .= Txy./Tii + # plastic corrections + Txx .= 2.0.*η_ve.*(Exx1 .- λ.*dQdTxx) + Tyy .= 2.0.*η_ve.*(Eyy1 .- λ.*dQdTyy) + Txy .= 2.0.*η_ve.*(Exy1 .- 0.5.*λ.*dQdTxy) + Tii .= sqrt.(0.5*(Txx.^2 .+ Tyy.^2) .+ Txy.^2) + Fchk .= Tii .- τ_y .- Pt.*sinϕ .- λ.*η_reg + η_vep .= Tii./2.0./Eii + η_vepv[2:end-1,2:end-1] .= av(η_vep); η_vepv[1,:].=η_vepv[2,:]; η_vepv[end,:].=η_vepv[end-1,:]; η_vepv[:,1].=η_vepv[:,2]; η_vepv[:,end].=η_vepv[:,end-1] + Txyv .= 2.0.*η_vepv.*Exyv1 + # PT timestep + dtVx .= min(dx,dy)^2.0./av_xa(η_vep)./4.1./Vsc + dtVy .= min(dx,dy)^2.0./av_ya(η_vep)./4.1./Vsc + dtPt .= 4.1.*η_vep./max(nx,ny)./Ptsc + # velocities + Rx .= .-diff(Pt, dims=1)./dx .+ diff(Txx, dims=1)./dx .+ diff(Txyv[2:end-1,:], dims=2)./dy + Ry .= .-diff(Pt, dims=2)./dy .+ diff(Tyy, dims=2)./dy .+ diff(Txyv[:,2:end-1], dims=1)./dx .+ av_ya(Rog) + dVxdt .= dVxdt.*(1-Vdmp/nx) .+ Rx + dVydt .= dVydt.*(1-Vdmp/ny) .+ Ry + Vx[2:end-1,:] .= Vx[2:end-1,:] .+ dVxdt.*dtVx + Vy[:,2:end-1] .= Vy[:,2:end-1] .+ dVydt.*dtVy + # convergence check + if mod(iter, nout)==0 + norm_Rx = norm(Rx)/sqrt(length(Rx)); norm_Ry = norm(Ry)/sqrt(length(Ry)); norm_∇V = norm(∇V)/sqrt(length(∇V)) + err = maximum([norm_Rx, norm_Ry, norm_∇V]) + push!(err_evo1, err); push!(err_evo2, itg) + @printf("it = %d, iter = %d, err = %1.2e norm[Rx=%1.2e, Ry=%1.2e, ∇V=%1.2e] (Fchk=%1.2e) \n", it, itg, err, norm_Rx, norm_Ry, norm_∇V, maximum(Fchk)) + end + iter+=1; itg=iter; niter += 1 + end + t = t + dt + push!(evo_t, t); push!(evo_Txx, maximum(Txx)) + # Plotting + p1 = heatmap(xv, yc, Vx' , aspect_ratio=1, xlims=(0, Lx), ylims=(dy/2, Ly-dy/2), c=:inferno, title="Vx") + # p2 = heatmap(xc, yv, Vy' , aspect_ratio=1, xlims=(dx/2, Lx-dx/2), ylims=(0, Ly), c=:inferno, title="Vy") + p2 = heatmap(xc, yc, η_vep' , aspect_ratio=1, xlims=(dx/2, Lx-dx/2), ylims=(0, Ly), c=:inferno, title="η_vep") + p3 = heatmap(xc, yc, Tii' , aspect_ratio=1, xlims=(dx/2, Lx-dx/2), ylims=(0, Ly), c=:inferno, title="τii") + p4 = plot(evo_t, evo_Txx , legend=false, xlabel="time", ylabel="max(τxx)", linewidth=0, markershape=:circle, framestyle=:box, markersize=3) + plot!(evo_t, 2.0.*εbg.*μ0.*(1.0.-exp.(.-evo_t.*G0./μ0)), linewidth=2.0) # analytical solution for VE loading + plot!(evo_t, 2.0.*εbg.*μ0.*ones(size(evo_t)), linewidth=2.0) # viscous flow stress + if !do_DP plot!(evo_t, τ_y*ones(size(evo_t)), linewidth=2.0) end # von Mises yield stress + display(plot(p1, p2, p3, p4)) + end + println(niter) + return +end + +Stokes2D_vep() diff --git a/newdamp/Stokes2D_vep_reg_IU_LR.jl b/newdamp/Stokes2D_vep_reg_IU_LR.jl new file mode 100644 index 0000000..e6d9e1d --- /dev/null +++ b/newdamp/Stokes2D_vep_reg_IU_LR.jl @@ -0,0 +1,181 @@ +using Plots,LinearAlgebra,Printf +# helper functions +@views av(A) = 0.25*(A[1:end-1,1:end-1].+A[2:end,1:end-1].+A[1:end-1,2:end].+A[2:end,2:end]) +@views av_xa(A) = 0.5*(A[1:end-1,:].+A[2:end,:]) +@views av_ya(A) = 0.5*(A[:,1:end-1].+A[:,2:end]) +@views maxloc(A) = max.(A[1:end-2,1:end-2],A[1:end-2,2:end-1],A[1:end-2,3:end], + A[2:end-1,1:end-2],A[2:end-1,2:end-1],A[2:end-1,3:end], + A[3:end ,1:end-2],A[3:end ,2:end-1],A[3:end ,3:end]) +@views bc2!(A) = begin A[1,:] = A[2,:]; A[end,:] = A[end-1,:]; A[:,1] = A[:,2]; A[:,end] = A[:,end-1] end +# main function +@views function Stokes2D_vep() + use_vep = true + # phyiscs + lx,ly = 1.0,1.0 + radi = 0.1 + η0 = 1.0 + η_reg = 1.2e-2 + G0 = 1.0 + Gi = 0.5G0 + τ_y = 1.6 + sinϕ = sind(30) + ebg = 1.0 + dt = η0/G0/4.0 + # numerics + nx,ny = 63,63 + nt = 10 + εnl = 1e-6 + maxiter = 150max(nx,ny) + nchk = 2max(nx,ny) + Re = 5π + r = 1.0 + CFL = 0.99/sqrt(2) + # preprocessing + dx,dy = lx/nx,ly/ny + max_lxy = max(lx,ly) + vpdτ = CFL*min(dx,dy) + xc,yc = LinRange(-(lx-dx)/2,(lx-dx)/2,nx),LinRange(-(ly-dy)/2,(ly-dy)/2,ny) + xv,yv = LinRange(-lx/2,lx/2,nx+1),LinRange(-ly/2,ly/2,ny+1) + # allocate arrays + Pr = zeros(nx ,ny ) + τxx = zeros(nx ,ny ) + τyy = zeros(nx ,ny ) + τxy = zeros(nx+1,ny+1) + τxyc = zeros(nx ,ny ) + τii = zeros(nx ,ny ) + Eii = zeros(nx ,ny ) + λ = zeros(nx ,ny ) + F = zeros(nx ,ny ) + Fchk = zeros(nx ,ny ) + dQdTxx = zeros(nx ,ny ) + dQdTyy = zeros(nx ,ny ) + dQdTxy = zeros(nx ,ny ) + τxx_o = zeros(nx ,ny ) + τyy_o = zeros(nx ,ny ) + τxy_o = zeros(nx+1,ny+1) + Vx = zeros(nx+1,ny ) + Vy = zeros(nx ,ny+1) + dVx = zeros(nx-1,ny ) + dVy = zeros(nx ,ny-1) + Rx = zeros(nx-1,ny ) + Ry = zeros(nx ,ny-1) + ∇V = zeros(nx ,ny ) + ρg = zeros(nx ,ny ) + Exx = zeros(nx ,ny ) + Eyy = zeros(nx ,ny ) + Exy = zeros(nx+1,ny+1) + Exx_e = zeros(nx ,ny ) + Eyy_e = zeros(nx ,ny ) + Exy_e = zeros(nx+1,ny+1) + Exx_τ = zeros(nx ,ny ) + Eyy_τ = zeros(nx ,ny ) + Exy_τ = zeros(nx+1,ny+1) + Exyc_τ = zeros(nx ,ny ) + η_ve_τ = zeros(nx ,ny ) + η_ve_τv = zeros(nx+1,ny+1) + η_ve = zeros(nx ,ny ) + η_vem = zeros(nx ,ny ) + η_vev = zeros(nx+1,ny+1) + η_vevm = zeros(nx+1,ny+1) + dτ_ρ = zeros(nx ,ny ) + dτ_ρv = zeros(nx+1,ny+1) + Gdτ = zeros(nx ,ny ) + Gdτv = zeros(nx+1,ny+1) + η_vep = zeros(nx ,ny ) + η_vepv = zeros(nx+1,ny+1) + # init + Vx = [ ebg*x for x ∈ xv, _ ∈ yc ] + Vy = [-ebg*y for _ ∈ xc, y ∈ yv ] + η = fill(η0,nx,ny); ηv = fill(η0,nx+1,ny+1) + G = fill(G0,nx,ny); Gv = fill(G0,nx+1,ny+1) + @. G[xc^2 + yc'^2 < radi^2] = Gi + @. Gv[xv^2 + yv'^2 < radi^2] = Gi + η_e = G.*dt; η_ev = Gv.*dt + @. η_ve = 1.0/(1.0/η + 1.0/η_e) + @. η_vev = 1.0/(1.0/ηv + 1.0/η_ev) + @. η_vep = 1.0/(1.0/η + 1.0/η_e) + @. η_vepv = 1.0/(1.0/ηv + 1.0/η_ev) + # action + t = 0.0; evo_t = Float64[]; evo_τxx = Float64[]; niter = 0 + for it = 1:nt + τxx_o .= τxx; τyy_o .= τyy; τxy_o .= τxy + err = 2εnl; iter = 0 + while err > εnl && iter < maxiter + if !use_vep + η_vem[2:end-1,2:end-1] .= maxloc(η_ve) ; bc2!(η_vem) + η_vevm[2:end-1,2:end-1] .= maxloc(η_vev); bc2!(η_vevm) + else + η_vem[2:end-1,2:end-1] .= maxloc(η_vep) ; bc2!(η_vem) + η_vevm[2:end-1,2:end-1] .= maxloc(η_vepv); bc2!(η_vevm) + end + @. dτ_ρ = vpdτ*max_lxy/Re/η_vem + @. dτ_ρv = vpdτ*max_lxy/Re/η_vevm + @. Gdτ = vpdτ^2/dτ_ρ/(r+2.0) + @. Gdτv = vpdτ^2/dτ_ρv/(r+2.0) + @. η_ve_τ = 1.0/(1.0/η + 1.0/η_e + 1.0/Gdτ) + @. η_ve_τv = 1.0/(1.0/ηv + 1.0/η_ev + 1.0/Gdτv) + # pressure + ∇V .= diff(Vx, dims=1)./dx .+ diff(Vy, dims=2)./dy + @. Pr -= r*Gdτ*∇V + # strain rates + Exx .= diff(Vx, dims=1)./dx + Eyy .= diff(Vy, dims=2)./dy + Exy[2:end-1,2:end-1] .= 0.5.*(diff(Vx[2:end-1,:], dims=2)./dy .+ diff(Vy[:,2:end-1], dims=1)./dx) + # viscoelastic strain rates + @. Exx_e = Exx + τxx_o/2.0/η_e + @. Eyy_e = Eyy + τyy_o/2.0/η_e + @. Exy_e = Exy + τxy_o/2.0/η_ev + # viscoelastic pseudo-transient strain rates + @. Exx_τ = Exx_e + τxx/2.0/Gdτ + @. Eyy_τ = Eyy_e + τyy/2.0/Gdτ + @. Exy_τ = Exy_e + τxy/2.0/Gdτv + # stress update + @. τxx = 2.0*η_ve_τ *Exx_τ + @. τyy = 2.0*η_ve_τ *Eyy_τ + @. τxy = 2.0*η_ve_τv*Exy_τ + @. τxyc = 2.0*η_ve_τ*Exyc_τ + # stress and strain rate invariants + @. τii = sqrt(0.5*(τxx^2 + τyy^2) + τxyc*τxyc) + @. Eii = sqrt(0.5*(Exx_τ^2 + Eyy_τ^2) + Exyc_τ*Exyc_τ) + # yield function + @. F = τii - τ_y - Pr.*sinϕ + @. λ = max(F,0.0)/(η_ve_τ + η_reg) + @. dQdTxx = 0.5*τxx /τii + @. dQdTyy = 0.5*τyy /τii + @. dQdTxy = τxyc/τii + # plastic correction + @. τxx = 2.0*η_ve_τ *(Exx_τ - λ*dQdTxx) + @. τyy = 2.0*η_ve_τ *(Eyy_τ - λ*dQdTyy) + @. τxyc = 2.0*η_ve_τ *(Exyc_τ - 0.5*λ*dQdTxy) + τxy[2:end-1,2:end-1] .= 2.0 .* η_ve_τv[2:end-1,2:end-1].*(Exy_τ[2:end-1,2:end-1] .- 0.5 .* av(λ.*dQdTxy)) + @. τii = sqrt(0.5*(τxx^2 + τyy^2) + τxyc*τxyc) + @. Fchk = τii - τ_y - Pr*sinϕ - λ*η_reg + @. η_vep = τii / 2.0 / Eii * 19.3 + η_vepv[2:end-1,2:end-1] .= av(η_vep); bc2!(η_vep) + # velocity update + dVx .= av_xa(dτ_ρ) .* (.-diff(Pr, dims=1)./dx .+ diff(τxx, dims=1)./dx .+ diff(τxy[2:end-1,:], dims=2)./dy) + dVy .= av_ya(dτ_ρ) .* (.-diff(Pr, dims=2)./dy .+ diff(τyy, dims=2)./dy .+ diff(τxy[:,2:end-1], dims=1)./dx .+ av_ya(ρg)) + @. Vx[2:end-1,:] = Vx[2:end-1,:] + dVx + @. Vy[:,2:end-1] = Vy[:,2:end-1] + dVy + if iter % nchk == 0 + Rx .= .-diff(Pr, dims=1)./dx .+ diff(τxx, dims=1)./dx .+ diff(τxy[2:end-1,:], dims=2)./dy + Ry .= .-diff(Pr, dims=2)./dy .+ diff(τyy, dims=2)./dy .+ diff(τxy[:,2:end-1], dims=1)./dx .+ av_ya(ρg) + norm_Rx = norm(Rx)/sqrt(length(Rx)); norm_Ry = norm(Ry)/sqrt(length(Ry)); norm_∇V = norm(∇V)/sqrt(length(∇V)) + err = maximum([norm_Rx, norm_Ry, norm_∇V]) + @printf("it = %d, iter = %d, err = %1.2e norm[Rx=%1.2e, Ry=%1.2e, ∇V=%1.2e] (Fchk=%1.2e) \n", it, iter, err, norm_Rx, norm_Ry, norm_∇V, maximum(Fchk)) + end + iter += 1; niter += 1 + end + t += dt; push!(evo_t, t); push!(evo_τxx, maximum(τxx)) + p1 = heatmap(xc,yc,τii',aspect_ratio=1,xlims=(-lx/2,lx/2),ylims=(-ly/2,ly/2),title="τii") + # p3 = heatmap(xc,yc,η_vep',aspect_ratio=1,xlims=(-lx/2,lx/2),ylims=(-ly/2,ly/2),title="τii") + p2 = plot(evo_t, evo_τxx , legend=false, xlabel="time", ylabel="max(τxx)", linewidth=0, markershape=:circle, framestyle=:box, markersize=3) + plot!(evo_t, 2.0.*ebg.*η0.*(1.0.-exp.(.-evo_t.*G0./η0)), linewidth=2.0) # analytical solution for VE loading + plot!(evo_t, 2.0.*ebg.*η0.*ones(size(evo_t)), linewidth=2.0) # viscous flow stress + display(plot(p1,p2)) + end + println(niter) + return +end +# action +Stokes2D_vep()