"Direct solvers and multiple MPI processes are not currently supported."
            )
        else:
            print(
                "escript was not built with support for direct solvers, aborting."
            )
    elif not escript.hasFeature('gmsh'):
        print("This example requires gmsh, aborting.")
    else:
        # Instantiate an MT_2D object with required & optional parameters:
        obj_mt2d = mt2d.MT_2D(domain,
                              mode,
                              freq_def,
                              tags,
                              rho,
                              rho_1d,
                              ifc_1d,
                              xstep=xstep,
                              zstep=zstep,
                              maps=None,
                              plot=True)

        # Solve for fields, apparent resistivity and phase:
        mt2d_fields, arho_2d, aphi_2d = obj_mt2d.pdeSolve()

        #
        print(datetime.datetime.now() - startTime)
        print("Done!")

else:  # no finley
    print("Finley module not available.")
示例#2
0
    def test_comm1(self):
        # ---
        # Initialisations
        # ---

        # Get timing:
        startTime = datetime.datetime.now()

        # Mode (TE includes air-layer, whereas TM does not):
        mode = 'TE'

        # Read the mesh file and define the 'finley' domain:
        #mesh_file = "mesh/commemi-1/commemi1_te.fly"
        #domain = finley.ReadMesh(mesh_file)
        #mesh_file = "mesh/commemi-1/commemi1_te.msh"
        #domain = finley.ReadGmsh(mesh_file, numDim=2)
        domain = generateCommemi1Mesh()

        # Sounding frequencies (in Hz):
        freq_def = {"high": 1.0e+1, "low": 1.0e+1, "step": 1}
        # Frequencies will be mapped on a log-scale from
        # 'high' to 'low' with 'step' points per decade.
        # (also only one frequency must be passed via dict)

        # Step sizes for sampling along vertical and horizontal axis (in m):
        xstep = 100
        zstep = 250

        # ---
        # Resistivity model
        # ---

        # Resistivity values assigned to tagged regions (in Ohm.m):
        rho = [
            1.0e+14,  # 0: air
            100.0,  # 1: host
            0.5  # 2: anomaly
        ]

        # Tags must match those in the file:
        tags = ["domain_air", "domain_host", "domain_anomaly"]

        # ---
        # Layer definitions for 1D response at boundaries.
        # ---

        # List with resistivity values for left and right boundary.
        rho_1d_left = [rho[0], rho[1]]
        rho_1d_rght = [rho[0], rho[1]]

        # Associated interfaces for 1D response left and right (must match the mesh file).
        ifc_1d_left = [20000, 0, -20000]
        ifc_1d_rght = [20000, 0, -20000]

        # Save in dictionary with layer interfaces and resistivities left and right:
        ifc_1d = {"left": ifc_1d_left, "right": ifc_1d_rght}
        rho_1d = {"left": rho_1d_left, "right": rho_1d_rght}

        # ---
        # Adjust parameters here for TM mode
        # ---

        # Simply delete first element from lists:
        if mode.upper() == 'TM':
            tags.pop(0)
            rho.pop(0)
            rho_1d['left'].pop(0)
            rho_1d['right'].pop(0)
            ifc_1d['left'].pop(0)
            ifc_1d['right'].pop(0)

        # ---
        # Run MT_2D
        # ---

        # Class options:
        mt2d.MT_2D._solver = "DIRECT"  #"ITERATIVE" #"CHOLEVSKY" #"CGLS " #"BICGSTAB" #"DIRECT" "ITERATIVE"
        mt2d.MT_2D._debug = False

        # Instantiate an MT_2D object with required & optional parameters:
        obj_mt2d = mt2d.MT_2D(domain,
                              mode,
                              freq_def,
                              tags,
                              rho,
                              rho_1d,
                              ifc_1d,
                              xstep=xstep,
                              zstep=zstep,
                              maps=None,
                              plot=False)

        # Solve for fields, apparent resistivity and phase:
        mt2d_fields, arho_2d, aphi_2d = obj_mt2d.pdeSolve()

        #import random

        #mt2d_fields[0]['real']+=random.random()
        #mt2d_fields[0]['imag']+=50*random.random()

        #print(arho_2d[0][0])
        #for i in range(len(aphi_2d[0])):
        #aphi_2d[0][i]+=(50*random.random())

        #for i in range(len(arho_2d[0])):
        #arho_2d[0][i]-=17.8*(random.random())

        # ---
        # User defined plots
        # ---

        from scipy.interpolate import InterpolatedUnivariateSpline

        # Setup abscissas/Ordinates for escript data:
        x = numpy.array(obj_mt2d.loc.getX())[:, 0]
        y0 = numpy.array(obj_mt2d.loc.getValue(arho_2d[0]))
        y1 = numpy.array(obj_mt2d.loc.getValue(aphi_2d[0]))

        # Values from Weaver -- Model 2D-1 (EP, T=0.1, z=0), see Zhdanov et al, 1997,
        # "Methods for modelling electromagnetic fields. Results from COMMEMI -- the
        # international project on the comparison of modelling results for electromag-
        # netic induction", Journal of Applied Geophysics, 133-271
        rte = [8.07, 14.10, 51.50, 95.71, 104.00, 100.00,
               100.00]  # TE rho_a (3 Canada)
        rtm = [9.86, 46.40, 94.80, 98.30, 99.70, 100.00,
               100.00]  # TM rho_a (3 Canada)
        if mode.lower() == 'te':
            ra = rte
        else:
            ra = rtm
        # Associated stations shifted to match escript coordinates:
        xs = numpy.array([0, 500, 1000, 2000, 4000, 8000, 16000
                          ]) + x.max() / 2.0

        # Setup interpolation to get values at specified stations (for comparison):
        fi = InterpolatedUnivariateSpline(x, y0)
        # Save escript values at comparison points in text file:
        # re-enable to allow comparisons
        #numpy.savetxt("commemi1_"+mode.lower()+".dat", numpy.column_stack((xs,fi(xs))), fmt='%g')

        # X plot-limits:
        x0lim = [2000, 38000]
        y1lim = [0, 120]
        y2lim = [40, 85]

        # Plot labels:
        title = '    escript COMMEMI-1 MT-2D ' + '(' + mode.upper(
        ) + ')' + ' freq: ' + str(obj_mt2d.frequencies[0]) + ' Hz'
        ylbl0 = r'resistivity $(\Omega m)$'
        ylbl1 = r'phase $(\circ)$'
        xlbl1 = 'X (m)'
        # Setup the plot window with app. res. on top and phase on bottom:
        if HAVE_MPL:
            f, ax = pyplot.subplots(2,
                                    figsize=(3.33, 3.33),
                                    dpi=1200,
                                    facecolor='w',
                                    edgecolor='k',
                                    sharex=True)  # Mind shared axis
            f.subplots_adjust(hspace=0.1,
                              top=0.95,
                              left=0.135,
                              bottom=0.125,
                              right=0.975)
            f.suptitle(title, y=0.99, fontsize=8)  #

            # Top: apparent resistivity and points from Weaver for comparison:
            ax[0].plot(x, y0, color='red', label='escript')
            ax[0].plot(xs,
                       ra,
                       linestyle='',
                       markersize=3,
                       marker='o',
                       color='blue',
                       label='Weaver')
            ax[0].grid(b=True, which='both', color='grey', linestyle=':')
            ax[0].set_ylabel(ylbl0)
            ax[0].yaxis.set_label_coords(-0.082, 0.5)
            # Plot limits:
            ax[0].set_xlim(x0lim)
            ax[0].set_ylim(y1lim)

            # Bottom: phase on linear plot
            ax[1].plot(x, y1, color='blue')
            ax[1].grid(b=True, which='both', color='grey', linestyle=':')
            ax[1].set_xlabel(xlbl1)
            ax[1].set_ylabel(ylbl1)
            # Plot limits:
            ax[1].set_xlim(x0lim)
            ax[1].set_ylim(y2lim)

            # ask matplotlib for the plotted objects and their labels
            lna, la = ax[0].get_legend_handles_labels()
            ax[0].legend(lna,
                         la,
                         bbox_to_anchor=(0.675, 0.325),
                         loc=2,
                         borderaxespad=0.,
                         prop={'size': 8},
                         frameon=False)

            pyplot.ticklabel_format(style='sci',
                                    axis='x',
                                    scilimits=(0, 0),
                                    useMathText=True)
            ax[0].xaxis.major.formatter._useMathText = True
            pyplot.rc('font', **{'size': 8, 'family': 'sans-serif'})
            # Uncomment to inspect visually
            #f.savefig("commemi1_"+mode.lower()+".png", dpi=1200)

        # Now let's see if the points match
        # First, we need to find correspondance between xs and x
        indices = []
        for i in range(len(xs)):
            mindiff = 40000
            mindex = 0
            for j in range(len(x)):
                if abs(xs[i] - x[j]) < mindiff:
                    mindiff = abs(xs[i] - x[j])
                    mindex = j
            indices.append(mindex)

        # The following are very simple checks based on the visual shape of the correct result
        maxdiff = 0
        for i in range(len(indices)):
            if abs(y0[indices[i]] - ra[i]) > maxdiff:
                maxdiff = abs(y0[indices[i]] - ra[i])

        # Threshold is pretty arbitrary
        self.assertLess(maxdiff, 5)  # "Mismatch with reference data"

        c = 0
        for y in y1:
            if y < 46:
                c += 1

        self.assertLess(74, escript.Lsup(y1))  # "Peak of bottom plot is off."
        self.assertLess(escript.Lsup(y1), 81)  # "Peak of bottom plot is off."

        self.assertLess(0.78,
                        c / len(y1))  # "Bottom plot has too many high points"
        self.assertLess(c / len(y1),
                        0.8)  # "Bottom plot has too many high points"

        #
        print(datetime.datetime.now() - startTime)
        print("Done!")
示例#3
0
    def test_comm4(self):
        # ---
        # Initialisations
        # ---

        # Get timing:
        startTime = datetime.datetime.now()

        # Mode (TE includes air-layer, whereas TM does not):
        mode = 'TE'

        # Read the mesh file and define the 'finley' domain: 
        #mesh_file = "mesh/commemi-4/commemi4_tm.msh"
        #domain = finley.ReadGmsh(mesh_file, numDim=2)
        domain = generateCommemi4Mesh()

        #mesh_file = "mesh/commemi-4/commemi4_tm.fly"
        #domain = finley.ReadMesh(mesh_file)

        # Sounding frequencies (in Hz):
        freq_def = {"high":1.0e+0,"low":1.0e-0,"step":1}
        # Frequencies will be mapped on a log-scale from
        # 'high' to 'low' with 'step' points per decade.
        # (also only one frequency must be passed via dict)

        # Step sizes for sampling along vertical and horizontal axis (in m):
        xstep=100
        zstep=100



        # ---
        # Resistivity model
        # ---

        # Resistivity values assigned to tagged regions (in Ohm.m):
        rho  = [
                1.0e+14, # 0: air     1.0e-30
                25.0   , # 1: lyr1    0.04
                10.0   , # 2: slab    0.1
                2.5    , # 3: basin   0.4
                1000.0 , # 4: lyr2    0.001
                5.0      # 5: lyr3    0.2
            ]

        # Tags must match those in the file:
        tags = ["air", "lyr1", "slab", "basin", "lyr2", "lyr3"]

        # Optional user defined map of resistivity:
        def f4(x,z,r): return escript.sqrt(escript.sqrt(x*x+z*z))/r
        maps = [None, None, None, None, f4, None]



        # ---
        # Layer definitions for 1D response at boundaries.
        # ---

        # List with resistivity values for left and right boundary.
        rho_1d_left  = [ rho[0], rho[1], rho[2], rho[4], rho[5] ]
        rho_1d_rght  = [ rho[0], rho[1], rho[3], rho[4], rho[5] ]

        # Associated interfaces for 1D response left and right (must match the mesh file).
        ifc_1d_left = [ 50000, 0, -500, -2000, -25000, -50000]
        ifc_1d_rght = [ 50000, 0, -500, -1000, -25000, -50000]

        # Save in dictionary with layer interfaces and resistivities left and right:
        ifc_1d = {"left":ifc_1d_left , "right":ifc_1d_rght}
        rho_1d = {"left":rho_1d_left , "right":rho_1d_rght}



        # ---
        # Adjust parameters here for TM mode
        # ---

        # Simply delete first element from lists:
        if mode.upper() == 'TM':
            tags.pop(0)
            rho.pop(0)
            rho_1d['left'].pop(0)
            rho_1d['right'].pop(0)
            ifc_1d['left'].pop(0)
            ifc_1d['right'].pop(0)
            if maps is not None:
                maps.pop(0)



        # ---
        # Run MT_2D
        # ---

        # Class options:
        mt2d.MT_2D._solver = "DIRECT" #"ITERATIVE" #"CHOLEVSKY" #"CGLS " #"BICGSTAB" #"DIRECT" "ITERATIVE"
        mt2d.MT_2D._debug   = False

        # Instantiate an MT_2D object with required & optional parameters:
        obj_mt2d = mt2d.MT_2D(domain, mode, freq_def, tags, rho, rho_1d, ifc_1d,
                xstep=xstep ,zstep=zstep, maps=None, plot=False)

        # Solve for fields, apparent resistivity and phase:
        mt2d_fields, arho_2d, aphi_2d = obj_mt2d.pdeSolve()
        
        
        #import random

        #mt2d_fields[0]['real']+=random.random()
        #mt2d_fields[0]['imag']+=50*random.random()

        #print(arho_2d[0][0])
        #for i in range(len(aphi_2d[0])):
            #aphi_2d[0][i]+=(50*random.random())

        #for i in range(len(arho_2d[0])):
            #arho_2d[0][i]-=7*(random.random())    
        

        # ---
        # User defined plots
        # ---

        # Setup abscissas/Ordinates for escript data:
        x  = numpy.array( obj_mt2d.loc.getX() )[:,0]
        y0 = numpy.array( obj_mt2d.loc.getValue(arho_2d[0]) )
        y1 = numpy.array( obj_mt2d.loc.getValue(aphi_2d[0]) )

        # Sort these arrays and delete any duplicates to prevent the call to 
        # InterpolatedUnivariateSpline below from returning an error
        indices = numpy.argsort(x,kind='quicksort')
        x = x[indices]
        y0 = y0[indices]
        y1 = y1[indices]
        indices = numpy.unique(x,return_index=True)
        x = x[indices[1]]
        y0 = y0[indices[1]]
        y1 = y1[indices[1]]

        # Zhdanov et al, 1997, -- Model 2D-1 Table B.33. Model2D-4 (T=1.0, z=0), see 
        # "Methods for modelling electromagnetic fields. Results from COMMEMI -- the
        # international project on the comparison of modelling results for electromag-
        # netic induction", Journal of Applied Geophysics, 133-271
        rte = [12.70, 12.00, 8.80, 6.84, 6.67, 6.25] # TE rho_a (3 Canada)   
        rtm = [11.40, 11.50, 9.03, 6.78, 6.80, 5.71] # TM rho_a (3 Canada) 
        if mode.lower() == 'te':
            ra = rte
        else:
            ra = rtm  
        # Associated stations shifted to match escript coordinates:
        xs = numpy.array( [-10, -7, -6, -5, 2, 5] )*1000 + x.max()/2.0

        # Setup interpolation to get values at specified stations (for comparison):
        fi = InterpolatedUnivariateSpline(x, y0)
        # Save esscript values at comparison points in text file:
        # uncomment to investigate
        #numpy.savetxt("mesh/commemi-4/commemi4_"+mode.lower()+".dat", numpy.column_stack((xs,fi(xs))), fmt='%g')

        # X plot-limits:
        x0lim = [2000,38000]
        #y1lim = [0,120]
        #y2lim = [40,85]
        
        # Plot labels:
        title = '    escript COMMEMI-4 MT-2D ' + '(' + mode.upper() + ')' + ' freq: ' + str(obj_mt2d.frequencies[0]) + ' Hz'
        ylbl0 = r'resistivity $(\Omega m)$'
        ylbl1 = r'phase $(\circ)$'
        xlbl1 = 'X (m)'
        if HAVE_MPL:
            # Setup the plot window with app. res. on top and phase on bottom:
            f, ax = pyplot.subplots(2, figsize=(3.33,3.33), dpi=1200,
                    facecolor='w', edgecolor='k', sharex=True) # Mind shared axis
            f.subplots_adjust(hspace=0.1, top=0.95, left=0.135, bottom=0.125, right=0.975)  
            f.suptitle(title, y=0.99,fontsize=8) # 
                
            # Top: apparent resistivity and points from Weaver for comparison:
            ax[0].plot(x, y0, color='red',  label = 'escript')
            ax[0].plot(xs,ra, linestyle='', markersize=3, marker='o',
                    color='blue', label = 'Weaver') 
            ax[0].grid(b=True, which='both', color='grey',linestyle=':')
            ax[0].set_ylabel( ylbl0)
            ax[0].yaxis.set_label_coords(-0.082, 0.5)
            # Plot limits:
            ax[0].set_xlim(x0lim)      
            #ax[0].set_ylim(y1lim)    

            # Bottom: phase on linear plot
            ax[1].plot(x,y1, color='blue')
            ax[1].grid(b=True, which='both', color='grey',linestyle=':')
            ax[1].set_xlabel( xlbl1 )
            ax[1].set_ylabel( ylbl1 )
            # Plot limits:
            ax[1].set_xlim(x0lim)      
            #ax[1].set_ylim(y2lim)     

            # ask matplotlib for the plotted objects and their labels
            lna, la = ax[0].get_legend_handles_labels()
            ax[0].legend(lna, la, bbox_to_anchor=(0.02, 0.325), loc=2,
                    borderaxespad=0.,prop={'size':8}, frameon=False)

            pyplot.ticklabel_format(style='sci', axis='x', scilimits=(0,0),
                    useMathText=True)
            ax[0].xaxis.major.formatter._useMathText = True
            pyplot.rc('font', **{'size': 8,'family':'sans-serif'})
        #uncomment to allow visual inspection
        #f.savefig("mesh/commemi-4/commemi4_"+mode.lower()+".png", dpi=1200)

        # Now let's see if the points match
        # First, we need to find correspondance between xs and x
        indices=[]
        for i in range(len(xs)):
            mindiff=40000
            mindex=0
            for j in range(len(x)):
                if abs(xs[i]-x[j]) < mindiff: 
                    mindiff=abs(xs[i]-x[j])
                    mindex=j
            indices.append(mindex)
            
        # The following are very simple checks based on the visual shape of the correct result        
        maxdiff=0
        for i in range(len(indices)):
            if abs(y0[indices[i]]-ra[i])>maxdiff:
                maxdiff=abs(y0[indices[i]]-ra[i])
            
        if maxdiff>5:           #Threshold is pretty arbitrary
            raise RuntimeError("Mismatch with reference data")

        c=0
        for y in y1:
            if y<46:
                c+=1

        if not (62 < escript.Lsup(y1) < 64):
            raise RuntimeError("Peak of bottom plot is off.")
            
        if not (0.61 < c/len(y1) < 0.65):
            print(c/len(y1))
            raise RuntimeError("Bottom plot has too many high points")

        #
        print("Runtime:", datetime.datetime.now()-startTime)
        print("Done!")