tMatplotlib works as optional dependency, fix plotting calls, add verbose option - sphere - GPU-based 3D discrete element method algorithm with optional fluid coupling
 (HTM) git clone git://src.adamsgaard.dk/sphere
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) LICENSE
       ---
 (DIR) commit 3b2239705ebb3dff84425256a5d90456ba28fe5a
 (DIR) parent 6ec51c0ddd515f3381c79c72e4d0666da6231197
 (HTM) Author: Anders Damsgaard <anders@adamsgaard.dk>
       Date:   Mon,  2 Sep 2019 06:06:55 +0200
       
       Matplotlib works as optional dependency, fix plotting calls, add verbose option
       
       Diffstat:
         M python/sphere.py                    |     216 +++++++++++++++++++++++--------
       
       1 file changed, 162 insertions(+), 54 deletions(-)
       ---
 (DIR) diff --git a/python/sphere.py b/python/sphere.py
       t@@ -1,25 +1,30 @@
        #!/usr/bin/env python
        import math
        import numpy
       -import matplotlib
       -matplotlib.use('Agg')
       -import matplotlib.pyplot as plt
       -import matplotlib.collections
       -matplotlib.rcParams.update({'font.size': 7, 'font.family': 'serif'})
       -matplotlib.rc('text', usetex=True)
       -matplotlib.rcParams['text.latex.preamble'] = [r"\usepackage{amsmath}"]
       -from matplotlib.font_manager import FontProperties
       +try:
       +    import matplotlib
       +    matplotlib.use('Agg')
       +    import matplotlib.pyplot as plt
       +    import matplotlib.collections
       +    matplotlib.rcParams.update({'font.size': 7, 'font.family': 'serif'})
       +    matplotlib.rc('text', usetex=True)
       +    matplotlib.rcParams['text.latex.preamble'] = [r"\usepackage{amsmath}"]
       +    from matplotlib.font_manager import FontProperties
       +    py_mpl = True
       +except ImportError:
       +    print('Info: Could not find "matplotlib" python module. ' +
       +          'Plotting functionality will be unavailable')
       +    py_mpl = False
        import subprocess
        import pickle as pl
        try:
            import vtk
       +    py_vtk = True
        except ImportError:
       -    print('Warning: Could not find "vtk" python module. ' +
       +    print('Info: Could not find "vtk" python module. ' +
                  'Fluid VTK calls will be unavailable')
            print('Consider installing with `pip install --user vtk`')
            py_vtk = False
       -else:
       -    py_vtk = True
        
        numpy.seterr(all='warn', over='raise')
        
       t@@ -1931,7 +1936,7 @@ class sim:
                :type verbose: bool
                '''
        
       -        if py_vtk == False:
       +        if not py_vtk:
                    print('Error: vtk module not found, cannot writeVTKforces.')
                    return
        
       t@@ -2051,7 +2056,7 @@ class sim:
                :param verbose: Show diagnostic information (default = True)
                :type verbose: bool
                '''
       -        if py_vtk == False:
       +        if not py_vtk:
                    print('Error: vtk module not found, cannot writeFluidVTK.')
                    return
        
       t@@ -2202,7 +2207,7 @@ class sim:
                :type resolution: int
                '''
        
       -        if py_vtk == False:
       +        if not py_vtk:
                    print('Error: vtk module not found, cannot show scene.')
                    return
        
       t@@ -2398,7 +2403,7 @@ class sim:
                            + str(psd) + '). Valid values are \'uni\' or \'logn\'')
        
                # Show radii as histogram
       -        if histogram:
       +        if histogram and py_mpl:
                    fig = plt.figure(figsize=(8,8))
                    figtitle = 'Particle size distribution, {0} particles'.format(\
                            self.np)
       t@@ -4672,7 +4677,7 @@ class sim:
                    fh.write('module load cuda/6.0\n')
                    fh.write('module load python/2.7.4\n')
                    fh.write('module load numpy/1.7.1/python.2.7.4\n')
       -            fh.write('module load matplotlib/1.7.1/python.2.7.4\n')
       +            #fh.write('module load matplotlib/1.7.1/python.2.7.4\n')
                    fh.write('echo "`whoami`@`hostname`\n')
                    fh.write('echo "Start at `date`\n')
                    fh.write('nvidia-smi\n')
       t@@ -5113,7 +5118,7 @@ class sim:
        
        
                plt.figure(figsize=[4,4])
       -        ax = plt.subplot(111, polar=True, axisbg='w')
       +        ax = plt.subplot(111, polar=True)
                ax.scatter(strikelist, diplist, c='k', marker='+')
                ax.set_rmax(90)
                ax.set_rticks([])
       t@@ -5131,6 +5136,9 @@ class sim:
                :param graphics_format: Save the plot in this format
                :type graphics_format: str
                '''
       +        if not py_mpl:
       +            print('Error: matplotlib module not found, cannot bondsRose.')
       +            return
                # loop through these contacts and find the strike and dip of the
                # contacts
                strikelist = [] # strike direction of the normal vector, [0:360[
       t@@ -5170,7 +5178,7 @@ class sim:
                        strikelist.append(2.0*numpy.pi - math.acos(dx/dhoriz))
        
                plt.figure(figsize=[4,4])
       -        ax = plt.subplot(111, polar=True, axisbg='w')
       +        ax = plt.subplot(111, polar=True)
                ax.scatter(strikelist, diplist, c='k', marker='+')
                ax.set_rmax(90)
                ax.set_rticks([])
       t@@ -5219,6 +5227,9 @@ class sim:
                :param graphics_format: Save the plot in this format
                :type graphics_format: str
                '''
       +        if not py_mpl:
       +            print('Error: matplotlib module not found, cannot sheardisp.')
       +            return
        
                # Bin data and error bars for alternative visualization
                h_total = numpy.max(self.x[:,2]) - numpy.min(self.x[:,2])
       t@@ -5267,6 +5278,10 @@ class sim:
                    the porosity in
                :type zslices: int
                '''
       +        if not py_mpl:
       +            print('Error: matplotlib module not found, cannot sheardisp.')
       +            return
       +
                porosity, depth = self.porosity(zslices)
        
                plt.figure(figsize=[4, 4])
       t@@ -5318,6 +5333,10 @@ class sim:
                :type verbose: bool
                '''
        
       +        if not py_mpl:
       +            print('Error: matplotlib module not found (thinsection_x1x3).')
       +            return
       +
                if x2 == 'center' :
                    x2 = (self.L[1] - self.origo[1]) / 2.0
        
       t@@ -5597,8 +5616,12 @@ class sim:
                :param graphics_format: Save the plot in this format
                :type graphics_format: str
                '''
       -        self.writebin(verbose=False)
        
       +        if not py_mpl:
       +            print('Error: matplotlib module not found (plotContacts).')
       +            return
       +
       +        self.writebin(verbose=False)
        
                subprocess.call("cd .. && ./forcechains -f txt input/" + self.sid \
                        + ".bin > python/contacts-tmp.txt", shell=True)
       t@@ -5662,7 +5685,7 @@ class sim:
                    j += 1
        
                fig = plt.figure(figsize=figsize)
       -        ax = plt.subplot(111, polar=True, axisbg='white')
       +        ax = plt.subplot(111, polar=True)
                cs = ax.scatter(strikelist, 90. - diplist, marker='o',
                        c=forcemagnitude,
                        s=forcemagnitude/f_n_max*40.,
       t@@ -5779,14 +5802,13 @@ class sim:
                            graphics_format,\
                            transparent=False)
        
       -
       -
                plt.close()
        
                if return_data:
                    return data, strikelist, diplist, forcemagnitude, alpha, f_n_max
        
       -    def plotFluidPressuresY(self, y = -1, graphics_format = 'png'):
       +    def plotFluidPressuresY(self, y = -1, graphics_format = 'png',
       +                            verbose = True):
                '''
                Plot fluid pressures in a plane normal to the second axis.
                The plot is saved in the current folder with the format
       t@@ -5797,26 +5819,37 @@ class sim:
                :type y: int
                :param graphics_format: Save the plot in this format
                :type graphics_format: str
       +        :param verbose: Print output filename after saving
       +        :type verbose: bool
        
                See also: :func:`writeFluidVTK()` and :func:`plotFluidPressuresZ()`
                '''
        
       +        if not py_mpl:
       +            print('Error: matplotlib module not found (plotFluidPressuresY).')
       +            return
       +
                if y == -1:
                    y = self.num[1]/2
        
                plt.figure(figsize=[8,8])
                plt.title('Fluid pressures')
       -        imgplt = plt.imshow(self.f_rho[:,y,:].T, origin='lower')
       +        imgplt = plt.imshow(self.p_f[:,y,:].T, origin='lower')
                imgplt.set_interpolation('nearest')
                #imgplt.set_interpolation('bicubic')
                #imgplt.set_cmap('hot')
                plt.xlabel('$x_1$')
                plt.ylabel('$x_3$')
                plt.colorbar()
       -        plt.savefig('p_f-' + self.sid + \
       -                '-y' + str(y) + '.' + graphics_format, transparent=False)
       +        filename = 'p_f-' + self.sid + '-y' + str(y) + '.' + graphics_format
       +        plt.savefig(filename, transparent=False)
       +        if verbose:
       +            print('saved to ' + filename)
       +        plt.clf()
       +        plt.close()
        
       -    def plotFluidPressuresZ(self, z = -1, graphics_format = 'png'):
       +    def plotFluidPressuresZ(self, z = -1, graphics_format = 'png',
       +                            verbose = True):
                '''
                Plot fluid pressures in a plane normal to the third axis.
                The plot is saved in the current folder with the format
       t@@ -5827,26 +5860,37 @@ class sim:
                :type z: int
                :param graphics_format: Save the plot in this format
                :type graphics_format: str
       +        :param verbose: Print output filename after saving
       +        :type verbose: bool
        
                See also: :func:`writeFluidVTK()` and :func:`plotFluidPressuresY()`
                '''
        
       +        if not py_mpl:
       +            print('Error: matplotlib module not found (plotFluidPressuresZ).')
       +            return
       +
                if z == -1:
                    z = self.num[2]/2
        
                plt.figure(figsize=[8,8])
                plt.title('Fluid pressures')
       -        imgplt = plt.imshow(self.f_rho[:,:,z].T, origin='lower')
       +        imgplt = plt.imshow(self.p_f[:,:,z].T, origin='lower')
                imgplt.set_interpolation('nearest')
                #imgplt.set_interpolation('bicubic')
                #imgplt.set_cmap('hot')
                plt.xlabel('$x_1$')
                plt.ylabel('$x_2$')
                plt.colorbar()
       -        plt.savefig('p_f-' + self.sid + \
       -                '-z' + str(z) + '.' + graphics_format, transparent=False)
       +        filename = 'p_f-' + self.sid + '-z' + str(z) + '.' + graphics_format
       +        plt.savefig(filename, transparent=False)
       +        if verbose:
       +            print('saved to ' + filename)
       +        plt.clf()
       +        plt.close()
        
       -    def plotFluidVelocitiesY(self, y = -1, graphics_format = 'png'):
       +    def plotFluidVelocitiesY(self, y = -1, graphics_format = 'png',
       +                             verbose = True):
                '''
                Plot fluid velocities in a plane normal to the second axis.
                The plot is saved in the current folder with the format
       t@@ -5857,10 +5901,16 @@ class sim:
                :type y: int
                :param graphics_format: Save the plot in this format
                :type graphics_format: str
       +        :param verbose: Print output filename after saving
       +        :type verbose: bool
        
                See also: :func:`writeFluidVTK()` and :func:`plotFluidVelocitiesZ()`
                '''
        
       +        if not py_mpl:
       +            print('Error: matplotlib module not found (plotFluidVelocitiesY).')
       +            return
       +
                if y == -1:
                    y = self.num[1]/2
        
       t@@ -5868,7 +5918,7 @@ class sim:
                plt.figure(figsize=[8,8])
        
                plt.subplot(131)
       -        imgplt = plt.imshow(self.f_v[:,y,:,0].T, origin='lower')
       +        imgplt = plt.imshow(self.v_f[:,y,:,0].T, origin='lower')
                imgplt.set_interpolation('nearest')
                #imgplt.set_interpolation('bicubic')
                #imgplt.set_cmap('hot')
       t@@ -5878,7 +5928,7 @@ class sim:
                plt.colorbar(orientation = 'horizontal')
        
                plt.subplot(132)
       -        imgplt = plt.imshow(self.f_v[:,y,:,1].T, origin='lower')
       +        imgplt = plt.imshow(self.v_f[:,y,:,1].T, origin='lower')
                imgplt.set_interpolation('nearest')
                #imgplt.set_interpolation('bicubic')
                #imgplt.set_cmap('hot')
       t@@ -5888,7 +5938,7 @@ class sim:
                plt.colorbar(orientation = 'horizontal')
        
                plt.subplot(133)
       -        imgplt = plt.imshow(self.f_v[:,y,:,2].T, origin='lower')
       +        imgplt = plt.imshow(self.v_f[:,y,:,2].T, origin='lower')
                imgplt.set_interpolation('nearest')
                #imgplt.set_interpolation('bicubic')
                #imgplt.set_cmap('hot')
       t@@ -5897,10 +5947,15 @@ class sim:
                plt.ylabel('$x_3$')
                plt.colorbar(orientation = 'horizontal')
        
       -        plt.savefig('v_f-' + self.sid + \
       -                '-y' + str(y) + '.' + graphics_format, transparent=False)
       +        filename = 'v_f-' + self.sid + '-y' + str(y) + '.' + graphics_format
       +        plt.savefig(filename, transparent=False)
       +        if verbose:
       +            print('saved to ' + filename)
       +        plt.clf()
       +        plt.close()
        
       -    def plotFluidVelocitiesZ(self, z = -1, graphics_format = 'png'):
       +    def plotFluidVelocitiesZ(self, z = -1, graphics_format = 'png',
       +                             verbose = True):
                '''
                Plot fluid velocities in a plane normal to the third axis.
                The plot is saved in the current folder with the format
       t@@ -5911,9 +5966,14 @@ class sim:
                :type z: int
                :param graphics_format: Save the plot in this format
                :type graphics_format: str
       +        :param verbose: Print output filename after saving
       +        :type verbose: bool
        
                See also: :func:`writeFluidVTK()` and :func:`plotFluidVelocitiesY()`
                '''
       +        if not py_mpl:
       +            print('Error: matplotlib module not found (plotFluidVelocitiesZ).')
       +            return
        
                if z == -1:
                    z = self.num[2]/2
       t@@ -5922,7 +5982,7 @@ class sim:
                plt.figure(figsize=[8,8])
        
                plt.subplot(131)
       -        imgplt = plt.imshow(self.f_v[:,:,z,0].T, origin='lower')
       +        imgplt = plt.imshow(self.v_f[:,:,z,0].T, origin='lower')
                imgplt.set_interpolation('nearest')
                #imgplt.set_interpolation('bicubic')
                #imgplt.set_cmap('hot')
       t@@ -5932,7 +5992,7 @@ class sim:
                plt.colorbar(orientation = 'horizontal')
        
                plt.subplot(132)
       -        imgplt = plt.imshow(self.f_v[:,:,z,1].T, origin='lower')
       +        imgplt = plt.imshow(self.v_f[:,:,z,1].T, origin='lower')
                imgplt.set_interpolation('nearest')
                #imgplt.set_interpolation('bicubic')
                #imgplt.set_cmap('hot')
       t@@ -5942,7 +6002,7 @@ class sim:
                plt.colorbar(orientation = 'horizontal')
        
                plt.subplot(133)
       -        imgplt = plt.imshow(self.f_v[:,:,z,2].T, origin='lower')
       +        imgplt = plt.imshow(self.v_f[:,:,z,2].T, origin='lower')
                imgplt.set_interpolation('nearest')
                #imgplt.set_interpolation('bicubic')
                #imgplt.set_cmap('hot')
       t@@ -5951,11 +6011,14 @@ class sim:
                plt.ylabel('$x_2$')
                plt.colorbar(orientation = 'horizontal')
        
       -        plt.savefig('v_f-' + self.sid + \
       -                '-z' + str(z) + '.' + graphics_format, transparent=False)
       -
       +        filename = 'v_f-' + self.sid + '-z' + str(z) + '.' + graphics_format
       +        plt.savefig(filename, transparent=False)
       +        if verbose:
       +            print('saved to ' + filename)
       +        plt.clf()
       +        plt.close()
        
       -    def plotFluidDiffAdvPresZ(self, graphics_format = 'png'):
       +    def plotFluidDiffAdvPresZ(self, graphics_format = 'png', verbose = True):
                '''
                Compare contributions to the velocity from diffusion and advection,
                assuming the flow is 1D along the z-axis, phi = 1, and dphi = 0. This
       t@@ -5966,7 +6029,12 @@ class sim:
        
                :param graphics_format: Save the plot in this format
                :type graphics_format: str
       +        :param verbose: Print output filename after saving
       +        :type verbose: bool
                '''
       +        if not py_mpl:
       +            print('Error: matplotlib module not found (plotFluidDiffAdvPresZ).')
       +            return
        
                # The v_z values are read from self.v_f[0,0,:,2]
                dz = self.L[2]/self.num[2]
       t@@ -6016,8 +6084,11 @@ class sim:
                plt.grid()
        
                plt.tight_layout()
       -        plt.savefig('../output/{}-diff_adv-t={:.2e}s-mu={:.2e}Pa-s.{}'.format(\
       -                self.sid, self.time_current[0], self.mu[0], graphics_format))
       +        filename = '../output/{}-diff_adv-t={:.2e}s-mu={:.2e}Pa-s.{}'.format(
       +                self.sid, self.time_current[0], self.mu[0], graphics_format)
       +        plt.savefig(filename)
       +        if verbose:
       +            print('saved to ' + filename)
                plt.clf()
                plt.close(fig)
        
       t@@ -6042,7 +6113,7 @@ class sim:
                        1.0e-16)
                return self.Re
        
       -    def plotLoadCurve(self, graphics_format='png'):
       +    def plotLoadCurve(self, graphics_format='png', verbose=True):
                '''
                Plot the load curve (log time vs. upper wall movement).  The plot is
                saved in the current folder with the file name
       t@@ -6054,7 +6125,13 @@ class sim:
        
                :param graphics_format: Save the plot in this format
                :type graphics_format: str
       +        :param verbose: Print output filename after saving
       +        :type verbose: bool
                '''
       +        if not py_mpl:
       +            print('Error: matplotlib module not found (plotLoadCurve).')
       +            return
       +
                t = numpy.empty(self.status())
                H = numpy.empty_like(t)
                sb = sim(self.sid, fluid=self.fluid)
       t@@ -6105,7 +6182,10 @@ class sim:
                plt.axhline(y = self.H100, color='gray')
                plt.axvline(x = self.t50, color='red')
                plt.grid()
       -        plt.savefig(self.sid + '-loadcurve.' + graphics_format)
       +        filename = self.sid + '-loadcurve.' + graphics_format
       +        plt.savefig(filename)
       +        if verbose:
       +            print('saved to ' + filename)
                plt.clf()
                plt.close(fig)
        
       t@@ -6120,7 +6200,7 @@ class sim:
                self.conv = numpy.loadtxt('../output/' + self.sid + '-conv.log',
                        dtype=numpy.int32)
        
       -    def plotConvergence(self, graphics_format='png'):
       +    def plotConvergence(self, graphics_format='png', verbose=True):
                '''
                Plot the convergence evolution in the CFD solver. The plot is saved
                in the output folder with the file name
       t@@ -6128,9 +6208,15 @@ class sim:
        
                :param graphics_format: Save the plot in this format
                :type graphics_format: str
       +        :param verbose: Print output filename after saving
       +        :type verbose: bool
        
                See also: :func:`convergence()`
                '''
       +        if not py_mpl:
       +            print('Error: matplotlib module not found (plotConvergence).')
       +            return
       +
                fig = plt.figure()
                self.convergence()
        
       t@@ -6139,7 +6225,10 @@ class sim:
                plt.ylabel('Jacobi iterations')
                plt.plot(self.conv[:,0], self.conv[:,1])
                plt.grid()
       -        plt.savefig(self.sid + '-conv.' + graphics_format)
       +        filename = self.sid + '-conv.' + graphics_format
       +        plt.savefig(filename)
       +        if verbose:
       +            print('saved to ' + filename)
                plt.clf()
                plt.close(fig)
        
       t@@ -6169,7 +6258,13 @@ class sim:
                :type plotstyle: str
                :param outformat: File format of the output plot
                :type outformat: str
       +        :param verbose: Print output filename after saving
       +        :type verbose: bool
                '''
       +        if not py_mpl:
       +            print('Error: matplotlib module not found (plotSinFunction).')
       +            return
       +
                fig = plt.figure(figsize=[8,6])
                steps_left = (self.time_total[0] - self.time_current[0]) \
                        /self.time_file_dt[0]
       t@@ -6182,7 +6277,8 @@ class sim:
                plt.tight_layout()
                filename = self.sid + '-sin.' + outformat
                plt.savefig(filename)
       -        print(filename)
       +        if verbose:
       +            print(filename)
                plt.clf()
                plt.close(fig)
        
       t@@ -6204,7 +6300,7 @@ class sim:
                self.w_sigma0_A[0] = A
                self.w_sigma0_f[0] = f
        
       -        if plot:
       +        if plot and py_mpl:
                    self.plotSinFunction(self.w_sigma0[0], A, f, phi=0.0,
                            xlabel='$t$ [s]', ylabel='$\\sigma_0$ [Pa]')
        
       t@@ -6251,13 +6347,18 @@ class sim:
                '''
                self.setFluidPressureModulation(A = 0.0, f = 0.0)
        
       -    def plotPrescribedFluidPressures(self, graphics_format='png'):
       +    def plotPrescribedFluidPressures(self, graphics_format='png',
       +                                     verbose=True):
                '''
                Plot the prescribed fluid pressures through time that may be
                modulated through the class parameters p_mod_A, p_mod_f, and p_mod_phi.
                The plot is saved in the output folder with the file name
                '<simulation id>-pres.<graphics_format>'.
                '''
       +        if not py_mpl:
       +            print('Error: matplotlib module not found ' +
       +                  '(plotPrescribedFluidPressures).')
       +            return
        
                fig = plt.figure()
                conv = numpy.loadtxt('../output/' + self.sid + '-conv.log')
       t@@ -6272,7 +6373,10 @@ class sim:
                        numpy.sin(2.0*numpy.pi*self.p_mod_f*t + self.p_mod_phi)
                plt.plot(t, p, '.-')
                plt.grid()
       -        plt.savefig('../output/' + self.sid + '-pres.' + graphics_format)
       +        filename = '../output/' + self.sid + '-pres.' + graphics_format
       +        plt.savefig(filename)
       +        if verbose:
       +            print('saved to ' + filename)
                plt.clf()
                plt.close(fig)
        
       t@@ -6480,6 +6584,10 @@ class sim:
                lastfile = self.status()
                sb = sim(sid = self.sid, np = self.np, nw = self.nw, fluid = self.fluid)
        
       +        if not py_mpl:
       +            print('Error: matplotlib module not found (visualize).')
       +            return
       +
                ### Plotting
                if outformat != 'txt':
                    if figsize: