getfem-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Getfem-commits] (no subject)


From: Yves Renard
Subject: [Getfem-commits] (no subject)
Date: Wed, 3 Jan 2018 04:39:57 -0500 (EST)

branch: master
commit a464152f7d4b7585a8a9425523d66b47b7f2d38d
Author: Yves Renard <address@hidden>
Date:   Wed Jan 3 10:39:42 2018 +0100

    minor fixes
---
 interface/tests/python/demo_dynamic_contact_1D.py | 141 ++++++++++++++--------
 1 file changed, 94 insertions(+), 47 deletions(-)

diff --git a/interface/tests/python/demo_dynamic_contact_1D.py 
b/interface/tests/python/demo_dynamic_contact_1D.py
index 53ecdf6..12515b4 100644
--- a/interface/tests/python/demo_dynamic_contact_1D.py
+++ b/interface/tests/python/demo_dynamic_contact_1D.py
@@ -30,46 +30,58 @@
 import getfem as gf
 import numpy as np
 import matplotlib.pyplot as plt
-import time # time.sleep(6)
+import time, os, sys
 
 # Numerical parameters
-NX = 100              # Number of elements
+NX = 20               # Number of elements
 T = 9                 # Simulation time
 dt = 0.001            # Time step
-u_degree = 1          # Degree of the finite element method for u
+u_degree = 2          # Degree of the finite element method for u
 
-gamma0_N = 0.5        # Nitsche parameter gamma
+gamma0_N = 1          # Nitsche parameter gamma
 theta_N =  0          # Nitsche parameter theta
 
-gamma0_P = 0.5        # Penalization parameter
+gamma0_P = 10          # Penalization parameter
 
 beta = 0.             # Newmark parameter beta
 gamma = 0.5           # Newmark parameter gamma
 
-e_PS = 1.0            # Restitution coefficient for Paoli-Schatzman scheme
+e_PS = 0.             # Restitution coefficient for Paoli-Schatzman scheme
 
-version = 0           # 0 = pure Signorini contact
+version = 3           # 0 = pure Signorini contact
                       # 1 = pure Signorini contact with Paoli-Schatzman scheme
                       # 2 = penalized contact
                       # 3 = Nitsche's method
 
-mass_matrix_type = 2  # 0 = standard mass matrix
+lump_mass_matrix = 0  # 0 = standard mass matrix
+                      # 1 = basic lumped mass matrix
+
+mass_matrix_type = 0  # 0 = standard mass matrix
                       # 1 = redistributed mass matrix
                       # 2 = singular dynamic mass matrix
 
-# Plot parameters
+
+# Output parameters
 dtplot = 0.05         # Time step for intermediate plots
 do_inter_plot = False # Intermediate plots or not
 do_final_plot = True  # Final plots or not
+output_directory = './expe_num'
+root_filename = 'dyn1d'
+do_export_in_files = False;
+
+
+# Read optional parameters on the command line 
+for i in range(1,len(sys.argv)): exec(sys.argv[i])
 
 # Deduced parameters
 h = 1./NX
 TT = np.arange(0, T+dt, dt)
 NT = TT.size
 dt_max_approx = h/(2* u_degree);
-if (version == 2): dt_max_approx = min(dt_max_approx, h/(20*gamma0_P))
+if (version == 2): dt_max_approx = min(dt_max_approx, 2*h/(gamma0_P))
+if (version == 3): dt_max_approx = min(dt_max_approx, 2*h/(gamma0_N))
 print 'Approximative dt_max for CFL :', dt_max_approx
-if (dt > dt_max_approx): print 'Time step too large'; exit(1)
+if (beta == 0 and dt > dt_max_approx): print 'Time step too large'; exit(1)
 
 
 # Exact solution. The solution is periodic of period 3
@@ -108,8 +120,6 @@ def uExact(x, t, d = 0):
 def linsolve(M, B): # Call Superlu to solve a sparse linear system
     return (((gf.linsolve_superlu(M, B))[0]).T)[0]
 
-
-
 # Mesh
 m=gf.Mesh('cartesian', np.arange(0,1+1./NX,1./NX))
 
@@ -148,6 +158,12 @@ md.set_variable('u', U0); md.set_variable('v', V0)
 
 # Mass and stiffness matrices
 M = gf.asm_generic(mim, 2, 'u*Test_u', -1, md)
+if (lump_mass_matrix == 1):
+    assert (u_degree == 1), "Sorry, basic lump only for affine elements"
+    for j in range(0, Ndof):
+        for i in range(1, u_degree+1):
+            if (j+i < Ndof): M[j,j] += M[j,j+i]; M[j,j+i] = 0.;
+            if (j-i >= 0): M[j,j] += M[j,j-i]; M[j,j-i] = 0.;
 K = gf.asm_generic(mim, 2, 'Grad_u*Grad_Test_u', -1, md)
 
 # Dirichlet condition on the top
@@ -157,8 +173,8 @@ M[Ndof-1,Ndof-1] = 1.; K[Ndof-1,Ndof-1] = 1.;
 M2 = gf.Spmat('copy', M);
 
 if (mass_matrix_type == 1): # Redistributed mass matrix
-    M[1,1] += M[0,0];
-    for i in range(0, u_degree+1):
+    M[1,1] += M[0,0]; M[0,0] = 0.;
+    for i in range(1, u_degree+1):
         M[i,i] += M[i,0]; M[0,i] = M[i,0] = 0.
     M2 = gf.Spmat('copy', M); M2[0,0] = 1.
 elif (mass_matrix_type == 2): # Singular dynamic mass matrix
@@ -196,7 +212,7 @@ elif (version == 3):   # Nitsche contact
     K_N2.scale(dt*dt*beta);
     K_N_C = gf.Spmat('add', K_N, K_N2)
     asstr_Nitsche = '(t_N/g_N)*Grad_u*Grad_Test_u ' \
-              + '+(1/g_N)*neg_part(g_N*u+Grad_u)*(g_N*Test_u+t_N*Grad_Test_u)'
+             + '+(1/g_N)*neg_part(g_N*u+Grad_u)*(g_N*Test_u+t_N*Grad_Test_u)'
 else: assert(false), "Unvalid version"
               
 # Misc initializations
@@ -212,11 +228,11 @@ store_UH1 = np.zeros(NT); store_UH1_ex = np.zeros(NT)
 store_u0  = np.zeros(NT); store_u0_ex  = np.zeros(NT)
 store_v0  = np.zeros(NT); store_v0_ex  = np.zeros(NT)
 store_s0  = np.zeros(NT); store_s0_ex  = np.zeros(NT)
-fem_nodes = mfu.basic_dof_nodes();
+fem_nodes = mfu.basic_dof_nodes(); s0 = s1 = ux = 0.;
 
 # Time steps
 for nit in range(0, NT):
-    t = TT[nit]; 
+    t = TT[nit];
 
     if (t > 0.):
         if (beta == 0): # Newmark Explicit scheme (beta = 0)
@@ -234,14 +250,14 @@ for nit in range(0, NT):
                         + 'pure Signorini contact and standard mass matrix'
             elif (version == 1): # Pure Signorini contact with P.-S. scheme
                 if (mass_matrix_type >= 1):
-                    U1[0] = max((e_PS/2.)*Um1[0]/(1.-e_PS/2.), -a) / K[0,0];
-                    s1 = min((e_PS/2.)*Um1[0]/(1.-e_PS/2.), -a);
+                    U1[0] = max(-e_PS*Um1[0], -a) / K[0,0];
+                    s1 = min(-e_PS*Um1[0], -a);
                 else:
                     s1 = 0;
-                    if ((1.-e_PS/2.)*U1[0] + (e_PS/2.)*Um1[0] < 0):
+                    if ((1./(1.+e_PS))*U1[0] + (e_PS/(1.+e_PS))*Um1[0] < 0):
                         U1_0 = np.copy(U1);
                         B=M.mult(U0)+dt*M.mult(V0)-(dt*dt/2.)*K.mult(U0)
-                        B0 = np.copy(B); B0[0] = (e_PS/2.)*Um1[0]/(1.-e_PS/2.);
+                        B0 = np.copy(B); B0[0] = -e_PS*Um1[0];
                         U1=linsolve(K_N_C, B0)
                         F=M.mult(U1)-B; s1 = -F[0]/(dt*dt)
                         V1 += (U1-U1_0)/dt
@@ -262,7 +278,7 @@ for nit in range(0, NT):
                         U1[0] = -a / K_Nitsche2[0,0]
                 md.set_variable('u', U1); ux = 
md.interpolation('Grad_u',[0.],m)
                 Fc = gf.asm_generic(mim, 1, asstr_Nitsche, GAMMAC, md)
-                s1 = min(0,(gamma0_P/h)*U1[0]+ux)
+                s1 = min(0.,(gamma0_N/h)*U1[0]+ux)
             FF = linsolve(M2, Fc-K.mult(U1))
             V1 += dt*gamma*FF;
             if (mass_matrix_type >= 1): V1[0] = (U1[0] - U0[0])/dt
@@ -276,8 +292,8 @@ for nit in range(0, NT):
                     Fc1 = (K_N.mult(U1) - B)/(beta*dt*dt); s1 = -Fc1[0]
                 else: Fc1 = 0.*Fc; s1 = 0
             elif (version == 1): # Pure Signorini contact with P.-S. scheme
-                if ((1.-2*e_PS)*U1[0] + 2*e_PS*Um1[0] < 0):
-                    B2 = np.copy(B); B2[0]=(e_PS/2.)*Um1[0]/(1.-e_PS/2.);
+                if ((1./(1.+e_PS))*U1[0] + (e_PS/(1.+e_PS))*Um1[0] < 0):
+                    B2 = np.copy(B); B2[0]= -e_PS*Um1[0];
                     U1 = linsolve(K_N_C, B2)
                     Fc1 = (K_N.mult(U1) - B)/(dt*dt); s1 = -Fc1[0]
                     MV1 += dt*Fc1
@@ -294,7 +310,7 @@ for nit in range(0, NT):
                     U1 = linsolve(K_N_C, B); md.set_variable('u', U1);
                     ux = md.interpolation('Grad_u',[0.],m)
                 Fc1 = (K_N.mult(U1) - B)/(beta*dt*dt)
-                s1 = min(0,(gamma0_N/h)*U1[0]+ux)
+                s1 = min(0.,(gamma0_N/h)*U1[0]+ux)
             MA1 = Fc1-K.mult(U1);
             MV1 += dt*((1.-gamma)*MA0 + gamma*MA1);
             V1 = linsolve(M2, MV1); V1[Ndof-1] = 0.
@@ -315,12 +331,15 @@ for nit in range(0, NT):
     E = (np.vdot(MMV0, V0) + np.vdot(KU0, U0))*0.5
     if (version == 2): # Energy stored in the penalized contact
         E += (gamma0_P/h)*pow(min(0., U0[0]),2)/2
+    if (version == 3): # Nitsche Energy
+        E += (0.5*theta_N)*(h/gamma0_N)*(s0*s0-ux*ux);
     
     # Store the data to be ploted at the end
     store_u0[nit] = U0[0]; store_u0_ex[nit] = uExact(0., t)
     store_v0[nit] = V0[0]; store_v0_ex[nit] = uExact(0., t, 2)
     store_s0[nit] = s0
-    store_s0_ex[nit] = uExact(0., t, 1); store_E[nit] = E
+    store_s0_ex[nit] = uExact(0., t, 1);
+    store_E[nit] = E;
     store_VL2_ex[nit] = gf.compute_L2_norm(mfu, Vex, mim)
     store_UL2_ex[nit] = gf.compute_L2_norm(mfu, Uex, mim)
     store_UH1_ex[nit] = gf.compute_H1_norm(mfu, Uex, mim)
@@ -328,7 +347,7 @@ for nit in range(0, NT):
     store_UL2[nit] = gf.compute_L2_norm(mfu, U0-Uex, mim)
     store_UH1[nit] = gf.compute_H1_norm(mfu, U0-Uex, mim)
 
-    print "Time ", t, "/", T, " Energy :", store_E[nit]
+    print ("Time %6f"% t), "/", T, " Energy :", store_E[nit]
         
     # Draw the approximated and exact solutions
     if (do_inter_plot and t >= tplot):
@@ -357,24 +376,57 @@ for nit in range(0, NT):
 
     
 # print the main relative errors
-Err = np.amax(store_UL2) / np.amax(store_UL2_ex)
-print 'L^\intfy(0,T,L^2)-norm of the error on u: ', Err
-Err = np.amax(store_UH1) / np.amax(store_UH1_ex)
-print 'L^\intfy(0,T,H^1)-norm of the error on u: ', Err
-Err = np.amax(store_VL2) / np.amax(store_VL2_ex)
-print 'L^\intfy(0,T,L^2)-norm of the error on v: ', Err
+LinfL2u = np.amax(store_UL2) / np.amax(store_UL2_ex)
+print 'L^\intfy(0,T,L^2)-norm of the error on u: ', LinfL2u
+LinfH1u = np.amax(store_UH1) / np.amax(store_UH1_ex)
+print 'L^\intfy(0,T,H^1)-norm of the error on u: ', LinfH1u
+LinfL2v = np.amax(store_VL2) / np.amax(store_VL2_ex)
+print 'L^\intfy(0,T,L^2)-norm of the error on v: ', LinfL2v
 Nor = np.sqrt(np.sum(np.square(store_UL2_ex))*dt)
-Err = np.sqrt(np.sum(np.square(store_UL2))*dt) / Nor
-print 'L^2(0,T,L^2)-norm of the error on u: ', Err
+L2L2u = np.sqrt(np.sum(np.square(store_UL2))*dt) / Nor
+print 'L^2(0,T,L^2)-norm of the error on u: ', L2L2u
 Nor = np.sqrt(np.sum(np.square(store_UH1_ex))*dt)
-Err = np.sqrt(np.sum(np.square(store_UH1))*dt) / Nor
-print 'L^2(0,T,H^1)-norm of the error on u: ', Err
+L2H1u = np.sqrt(np.sum(np.square(store_UH1))*dt) / Nor
+print 'L^2(0,T,H^1)-norm of the error on u: ', L2H1u
 Nor = np.sqrt(np.sum(np.square(store_VL2_ex))*dt)
-Err = np.sqrt(np.sum(np.square(store_VL2))*dt) / Nor
-print 'L^2(0,T)-norm of the error on v: ', Err
+L2L2v = np.sqrt(np.sum(np.square(store_VL2))*dt) / Nor
+print 'L^2(0,T)-norm of the error on v: ', L2L2v
 Nor = np.sqrt(np.sum(np.square(store_s0_ex))*dt)
-Err = np.sqrt(np.sum(np.square(store_s0-store_s0_ex))*dt) / Nor
-print 'L^2(0,T)-norm of the error on contact stress: ', Err
+L2sn = np.sqrt(np.sum(np.square(store_s0-store_s0_ex))*dt) / Nor
+print 'L^2(0,T)-norm of the error on contact stress: ', L2sn
+
+
+if (do_export_in_files):
+    if (not os.path.exists(output_directory)):
+        os.makedirs(output_directory)
+
+    # Parameter file
+    pf = open(output_directory+'/' + root_filename + '.params', 'w')
+    pf.write('NX = %d;' % NX);            pf.write('T = %g;' % T)
+    pf.write('dt = %g;' % dt);            pf.write('u_degree = %d;' % u_degree)
+    pf.write('gamma0_N = %g;' % gamma0_N);pf.write('theta_N =  %g;' % theta_N)
+    pf.write('gamma0_P = %g;' % gamma0_P);pf.write('beta = %g;' % beta)
+    pf.write('gamma = %g;' % gamma);      pf.write('e_PS = %g;' % e_PS);
+    pf.write('version = %d;' % version)
+    pf.write('mass_matrix_type = %d;' % mass_matrix_type)
+    pf.close()
+
+    # Export solutions
+    np.save(output_directory+'/' + root_filename + '.u0.npy', store_u0);
+    np.save(output_directory+'/' + root_filename + '.v0.npy', store_v0);
+    np.save(output_directory+'/' + root_filename + '.s0.npy', store_s0);
+    np.save(output_directory+'/' + root_filename + '.E.npy' , store_E );
+    
+    # write error norms
+    pf = open(output_directory+'/' + root_filename + '.err_norms', 'w')
+    pf.write('LinfL2u = %g;' % LinfL2u); pf.write('LinfH1u = %g;' % LinfH1u)
+    pf.write('LinfL2v = %g;' % LinfL2v); pf.write('L2L2u = %g;' % L2L2u)
+    pf.write('L2H1u = %g;' % L2H1u);     pf.write('L2L2v = %g;' % L2L2v)
+    pf.write('L2sn = %g;' % L2sn)
+    pf.close()
+    
+    
+
 
 
 if (do_final_plot):
@@ -417,8 +469,3 @@ if (do_final_plot):
     plt.ylabel('$L^2$-error on $v$'); plt.xlabel('t')
     
     plt.show()
-
-
-
-
-



reply via email to

[Prev in Thread] Current Thread [Next in Thread]