Example #1
0
class Well(object):
   """
   generic well
   
   :var WATER: phase identifier for water well
   :var GAS: phase identifier for gas well
   """
   WATER="Water"
   GAS="Gas"
   def __init__(self, name, domain, Q=[0.], schedule=[0.], phase="Water", BHP_limit=1.*U.atm, X0=[0.,0.,0.], *args, **kwargs):
       """
       set up well 
       """
       if not len(schedule) == len(Q):
           raise ValueError("length of schedule and Q must match.")
       self.__schedule=schedule
       self.__Q = Q
       self.__phase=phase
       self.__BHP_limit=BHP_limit
       self.name=name
       self.domain=domain
       self.locator=Locator(DiracDeltaFunctions(self.domain),X0[:self.domain.getDim()])
       self.X0=self.locator.getX()
       
   def getLocation(self):
       return self.X0      

   def getProductivityIndex(self):
       """
       returns the productivity index of the well.
       typically a Gaussian profile around the location of the well.
       
       :note: needs to be overwritten
       """
       raise NotImplementedError
   
   def getFlowRate(self,t):
      """
      returns the flow rate
      """
      out=0.
      for i in range(len(self.__schedule)):
         if t <= self.__schedule[i]:
             out=self.__Q[i]
             break
      return out
         
   def getBHPLimit(self):
      """
      return bottom-hole pressure limit
      
      :note: needs to be overwritten
      """
      return self.__BHP_limit
      
   def getPhase(self):
      """
      returns the pahse the well works on
      """
      return self.__phase
Example #2
0
class Well(object):
   """
   generic well
   
   :var WATER: phase identifier for water well
   :var GAS: phase identifier for gas well
   """
   WATER="Water"
   GAS="Gas"
   def __init__(self, name, domain, Q=[0.], schedule=[0.], phase="Water", BHP_limit=1.*U.atm, X0=[0.,0.,0.], *args, **kwargs):
       """
       set up well 
       """
       if not len(schedule) == len(Q):
           raise ValueError("length of schedule and Q must match.")
       self.__schedule=schedule
       self.__Q = Q
       self.__phase=phase
       self.__BHP_limit=BHP_limit
       self.name=name
       self.domain=domain
       self.locator=Locator(DiracDeltaFunctions(self.domain),X0[:self.domain.getDim()])
       self.X0=self.locator.getX()
       
   def getLocation(self):
       return self.X0      

   def getProductivityIndex(self):
       """
       returns the productivity index of the well.
       typically a Gaussian profile around the location of the well.
       
       :note: needs to be overwritten
       """
       raise NotImplementedError
   
   def getFlowRate(self,t):
      """
      returns the flow rate
      """
      out=0.
      for i in range(len(self.__schedule)):
         if t <= self.__schedule[i]:
             out=self.__Q[i]
             break
      return out
         
   def getBHPLimit(self):
      """
      return bottom-hole pressure limit
      
      :note: needs to be overwritten
      """
      return self.__BHP_limit
      
   def getPhase(self):
      """
      returns the pahse the well works on
      """
      return self.__phase
Example #3
0
def subsample(u, nx=50, ny=50):
    """
    subsamples ```u``` over an ```nx``` x ```ny``` grid
    and returns ``numpy`` arrays for the values and locations
    used for subsampling.
    """
    xx = u.getDomain().getX()  # points of the domain
    x0 = inf(xx[0])
    y0 = inf(xx[1])
    dx = (sup(xx[0]) - x0) / nx  # x spacing
    dy = (sup(xx[1]) - y0) / ny  # y spacing
    grid = []
    for j in range(0, ny - 1):
        for i in range(0, nx - 1):
            grid.append([x0 + dx / 2 + dx * i, y0 + dy / 2 + dy * j])
    uLoc = Locator(u.getFunctionSpace(), grid)
    subu = uLoc(u)  # get data of u at sample points closests to grid points
    usublocs = uLoc.getX()  #returns actual locations from data
    return np.array(usublocs), np.array(subu)
Example #4
0
def subsample(u, nx=50, ny=50):
    """
    subsamples ```u``` over an ```nx``` x ```ny``` grid
    and returns ``numpy`` arrays for the values and locations
    used for subsampling.
    """
    xx=u.getDomain().getX()  # points of the domain
    x0=inf(xx[0])         
    y0=inf(xx[1])
    dx = (sup(xx[0])-x0)/nx # x spacing
    dy = (sup(xx[1])-y0)/ny # y spacing
    grid = [ ] 
    for j in range(0,ny-1):
        for i in range(0,nx-1):
               grid.append([x0+dx/2+dx*i,y0+dy/2+dy*j])
    uLoc = Locator(u.getFunctionSpace(),grid)
    subu= uLoc(u) # get data of u at sample points closests to grid points
    usublocs = uLoc.getX() #returns actual locations from data
    return np.array(usublocs), np.array(subu)
    if s > 0:
       rho=(1-m)*rho+m*1./s
    else:
       rho=(1-m)*rho+m*0. # arbitray number as air_layer is backed out in TM mode.
       
    z_top, m_top=z_top-l, m2
    
print("sigma =", sigma)
print("rho =", rho)
#
# ... create Locator to get impedance at position of observations:
#
stationX=np.linspace(OFFSET_STATION, WIDTH-OFFSET_STATION, num=NUM_STATION, endpoint=True)
loc=Locator(ReducedFunction(domain), [ (s, DEPTH-DEPTH_STATIONS) for s in stationX])

print("position of observation stations %s:"%(NUM_STATION//2,), loc.getX()[NUM_STATION//2]) # moved to the next element center!!!
#================================================================================================
FRQ=1./PERIODS
#================================================================================================
print("Start TM mode ...")
model=MT2DTMModel(domain, airLayer=DEPTH-L_AIR)
model.setResistivity(rho, rho_boundary=1/SIGMA0) # rho can be interpolated to the boundary (e.g. when conductivity is given on node) rho_boundary can be omited. 

# collects app. rho and phase for the frequencies:
arho_TM=[]
phase_TM=[]

for frq in FRQ:
    Zyx = model.getImpedance(f=frq)
    arho=model.getApparentResitivity(frq, Zyx)
    phi=model.getPhase(frq, Zyx)
Example #6
0
    for l in range(len(layers)):
        m=whereNonPositive(z-z_top)*wherePositive(z-(z_top-layers[l]))
        V_P = V_P     * (1-m)  + v_P[l]  * m
        V_S = V_S     * (1-m)  + v_S[l]  * m
        Delta = Delta * (1-m)  + delta[l]* m
        Eps = Eps     * (1-m)  + eps[l]  * m
        Tilt = Tilt   * (1-m)  + tilt[l] * m
        Rho = Rho     * (1-m)  + rho[l]  * m
        z_top-=layers[l]

    sw=TTIWave(domain, V_P, V_S, wl, src_tags[0], source_vector = src_dir,
                    eps=Eps, delta=Delta, rho=Rho, theta=Tilt,
                    absorption_zone=absorption_zone, absorption_cut=1e-2, lumping=lumping)

    srclog=Locator(domain, [ (r , depth) for r in receiver_line ] )
    grploc=[ (x[0], 0.) for x in srclog.getX() ]

    tracer_x=SimpleSEGYWriter(receiver_group=grploc, source=srcloc, sampling_interval=sampling_interval, text='x-displacement')
    tracer_z=SimpleSEGYWriter(receiver_group=grploc, source=srcloc, sampling_interval=sampling_interval, text='z-displacement')

    if not tracer_x.obspy_available():
        print("\nWARNING: obspy not available, SEGY files will not be written\n")
    elif getMPISizeWorld() > 1:
        print("\nWARNING: SEGY files cannot be written with multiple processes\n")

    t=0.
    mkDir('output')
    n=0
    k_out=0
    print("calculation starts @ %s"%(time.asctime(),))
    while t < t_end:
class TestSeismic2D(unittest.TestCase):
    # grid spacing in
    DX = 10.
    NEx = 200
    Order = 2
    VP = 2000
    NE_PML = 40  # PML thickness in term of number of elements
    NE_STATION0 = 70  # first station offset in term of number of elements
    Amplitude = 1
    S0 = 1000
    TESTTOL = 1e-2

    def setUp(self):
        Width = self.DX * self.NEx
        Center = self.NEx // 2 * self.DX
        self.domain = Rectangle(self.NEx,
                                self.NEx,
                                l0=Width,
                                l1=Width,
                                diracPoints=[(Center, Center)],
                                diracTags=["src"],
                                order=self.Order,
                                fullOrder=True)
        numStation = (self.NEx // 2 - 3 - self.NE_STATION0 - 1)
        stations = [((self.NE_STATION0 + i) * self.DX, Center)
                    for i in range(numStation)]
        self.loc = Locator(Solution(self.domain), stations)
        self.source = Scalar(0j, DiracDeltaFunctions(self.domain))
        self.source.setTaggedValue("src", self.Amplitude)
        self.sourceX = (Center, Center)

    def tearDown(self):
        del self.domain
        del self.loc
        del self.source
        del self.sourceX

    def test_RadialWaveLowF(self):
        Frequency = 0.01
        k = Frequency / self.VP * 2 * np.pi
        assert k * self.DX < 1
        L_PML = self.DX * self.NE_PML
        pml_condition = PMLCondition(sigma0=self.S0,
                                     Lleft=[L_PML, L_PML],
                                     Lright=[L_PML, L_PML],
                                     m=4)
        # sonic wave model
        wave = SonicWaveInFrequencyDomain(self.domain,
                                          vp=self.VP,
                                          pml_condition=pml_condition)
        wave.setFrequency(Frequency)
        # set source and get wave response:
        u = wave.getWave(self.source)

        r = np.array([
            sqrt((x[0] - self.sourceX[0])**2 + (x[1] - self.sourceX[1])**2)
            for x in self.loc.getX()
        ])
        uu2 = -scipy.special.hankel2(0, k * r) * 1j / 4
        uu = np.array(self.loc(u))
        errorA = max(abs(uu2 - uu))
        A = max(abs(uu2))
        self.assertLessEqual(errorA, A * self.TESTTOL)

    def test_RadialWaveMediumF(self):
        Frequency = 1.
        k = Frequency / self.VP * 2 * np.pi
        assert k * self.DX < 1
        L_PML = self.DX * self.NE_PML
        pml_condition = PMLCondition(sigma0=self.S0,
                                     Lleft=[L_PML, L_PML],
                                     Lright=[L_PML, L_PML],
                                     m=4)
        # sonic wave model
        wave = SonicWaveInFrequencyDomain(self.domain,
                                          vp=self.VP,
                                          pml_condition=pml_condition)
        wave.setFrequency(Frequency)
        # set source and get wave response:
        u = wave.getWave(self.source)

        r = np.array([
            sqrt((x[0] - self.sourceX[0])**2 + (x[1] - self.sourceX[1])**2)
            for x in self.loc.getX()
        ])
        uu2 = -scipy.special.hankel2(0, k * r) * 1j / 4
        uu = np.array(self.loc(u))
        errorA = max(abs(uu2 - uu))
        A = max(abs(uu2))
        self.assertLessEqual(errorA, A * self.TESTTOL)

    def test_RadialWaveHighF(self):
        Frequency = 10.
        k = Frequency / self.VP * 2 * np.pi
        assert k * self.DX < 1
        L_PML = self.DX * self.NE_PML
        pml_condition = PMLCondition(sigma0=self.S0,
                                     Lleft=[L_PML, L_PML],
                                     Lright=[L_PML, L_PML],
                                     m=4)
        # sonic wave model
        wave = SonicWaveInFrequencyDomain(self.domain,
                                          vp=self.VP,
                                          pml_condition=pml_condition)
        wave.setFrequency(Frequency)
        # set source and get wave response:
        u = wave.getWave(self.source)

        r = np.array([
            sqrt((x[0] - self.sourceX[0])**2 + (x[1] - self.sourceX[1])**2)
            for x in self.loc.getX()
        ])
        uu2 = -scipy.special.hankel2(0, k * r) * 1j / 4
        uu = np.array(self.loc(u))
        errorA = max(abs(uu2 - uu))
        A = max(abs(uu2))
        self.assertLessEqual(errorA, A * self.TESTTOL)
Example #8
0
# save to file:
saveSilo("solution",
         velocity=vp,
         amplitude=amps,
         phase=phase,
         pmlzone=pml_condition.getPMLMask(domain))
print("solution saved to file ...")

# get the amplitude and phase at geophones:
import matplotlib.pyplot as plt

fig = plt.gcf()
ax1 = plt.gca()

geophoneX = [x[0] for x in geophones.getX()]
color = 'tab:red'
ax1.set_xlabel('offset')
ax1.set_ylabel('amplitude', color=color)
ax1.plot(geophoneX, geophones(amps), color=color)
ax1.tick_params(axis='y', labelcolor=color)

ax2 = ax1.twinx()  # instantiate a second axes that shares the same x-axis

color = 'tab:blue'
ax2.set_ylabel('phase [deg]',
               color=color)  # we already handled the x-label with ax1
ax2.plot(geophoneX, geophones(phase), color=color, marker=".")
ax2.tick_params(axis='y', labelcolor=color)

fig.tight_layout()  # otherwise the right y-label is slightly clipped
Example #9
0
    sw = TTIWave(domain,
                 V_P,
                 V_S,
                 wl,
                 src_tags[0],
                 source_vector=src_dir,
                 eps=Eps,
                 delta=Delta,
                 rho=Rho,
                 theta=Tilt,
                 absorption_zone=absorption_zone,
                 absorption_cut=1e-2,
                 lumping=lumping)

    srclog = Locator(domain, [(r, depth) for r in receiver_line])
    grploc = [(x[0], 0.) for x in srclog.getX()]

    tracer_x = SimpleSEGYWriter(receiver_group=grploc,
                                source=srcloc,
                                sampling_interval=sampling_interval,
                                text='x-displacement')
    tracer_z = SimpleSEGYWriter(receiver_group=grploc,
                                source=srcloc,
                                sampling_interval=sampling_interval,
                                text='z-displacement')

    if not tracer_x.obspy_available():
        print(
            "\nWARNING: obspy not available, SEGY files will not be written\n")
    elif getMPISizeWorld() > 1:
        print(