示例#1
0
def test_main():
    flex = gflex.F2D()

    flex.Quiet = False

    flex.Method = 'FD'  # Solution method: * FD (finite difference)
    #                  * SAS (superposition of analytical solutions)
    #                  * SAS_NG (ungridded SAS)
    flex.PlateSolutionType = 'vWC1994'  # van Wees and Cloetingh (1994)
    # The other option is 'G2009': Govers et al. (2009)
    flex.Solver = 'direct'  # direct or iterative
    # convergence = 1E-3 # convergence between iterations, if an iterative solution
    # method is chosen

    flex.g = 9.8  # acceleration due to gravity
    flex.E = 65E9  # Young's Modulus
    flex.nu = 0.25  # Poisson's Ratio
    flex.rho_m = 3300.  # MantleDensity
    flex.rho_fill = 0.  # InfiillMaterialDensity

    flex.Te = 35000. * np.ones(
        (50, 50))  # Elastic thickness [m] -- scalar but may be an array
    flex.Te[:, -3:] = 0.
    flex.qs = np.zeros((50, 50))  # Template array for surface load stresses
    flex.qs[10:40, 10:40] += 1E6  # Populating this template
    flex.dx = 5000.  # grid cell size, x-oriented [m]
    flex.dy = 5000.  # grid cell size, y-oriented [m]
    # Boundary conditions can be:
    # (FD): 0Slope0Shear, 0Moment0Shear, 0Displacement0Slope, Mirror, or Periodic
    # For SAS or SAS_NG, NoOutsideLoads is valid, and no entry defaults to this
    flex.BC_W = '0Displacement0Slope'  # west boundary condition
    flex.BC_E = '0Moment0Shear'  # east boundary condition
    flex.BC_S = '0Displacement0Slope'  # south boundary condition
    flex.BC_N = '0Displacement0Slope'  # north boundary condition

    # latitude/longitude solutions are exact for SAS, approximate otherwise
    #latlon = # true/false: flag to enable lat/lon input. Defaults False.
    #PlanetaryRadius = # radius of planet [m], for lat/lon solutions

    flex.initialize()
    flex.run()
    flex.finalize()

    # If you want to plot the output
    #flex.plotChoice='both'
    # An output file for deflections could also be defined here
    # flex.wOutFile =
    flex.output()  # Plots and/or saves output, or does nothing, depending on
    # whether flex.plotChoice and/or flex.wOutFile have been set
    # TO OBTAIN OUTPUT DIRECTLY IN PYTHON, you can assign the internal variable,
    # flex.w, to another variable -- or as an element in a list if you are looping
    # over many runs of gFlex:
    deflection = flex.w
示例#2
0
 def start_gflex_and_assign_default_variables(self):
   import gflex
   self.flex = gflex.F2D()
   self.flex.Quiet = False
   self.flex.Method = 'FD'
   self.flex.PlateSolutionType = 'vWC1994'
   self.flex.Solver = 'direct'
   self.flex.g = 9.8 # acceleration due to gravity
   self.flex.E = 65E9 # Young's Modulus
   self.flex.nu = 0.25 # Poisson's Ratio
   self.flex.rho_m = 3300. # MantleDensity
   self.flex.rho_fill = 0. # InfiillMaterialDensity
   self.flex.BC_W = '0Displacement0Slope' # west boundary condition
   self.flex.BC_E = '0Displacement0Slope' # east boundary condition
   self.flex.BC_S = '0Displacement0Slope' # south boundary condition
   self.flex.BC_N = '0Displacement0Slope' # north boundary condition
   self.flex.north = None
   self.flex.south = None
   self.flex.west = None
   self.flex.east = None
   self.flex.dx = None
   self.flex.dy = None
示例#3
0
    def __init__(self,
                 grid,
                 Youngs_modulus=6.5e11,
                 Poissons_ratio=0.25,
                 rho_mantle=3300.,
                 rho_fill=0.,
                 elastic_thickness=35000.,
                 BC_W='0Displacement0Slope',
                 BC_E='0Displacement0Slope',
                 BC_N='0Displacement0Slope',
                 BC_S='0Displacement0Slope',
                 g=9.81,
                 **kwds):
        """Constructor for Wickert's gFlex in Landlab."""
        assert RasterModelGrid in inspect.getmro(grid.__class__)
        if NO_GFLEX:
            raise ImportError(
                "gFlex not installed! For installation instructions see " +
                "gFlex on GitHub: https://github.com/awickert/gFlex")
        BC_options = ('0Displacement0Slope', '0Moment0Shear', '0Slope0Shear',
                      'Periodic')

        # instantiate the module:
        self.flex = gflex.F2D()
        flex = self.flex

        # set up the grid variables:
        self._grid = grid
        flex.dx = grid.dx
        flex.dy = grid.dy

        # we assume these properties are fixed in this relatively
        # straightforward implementation, but they can still be set if you
        # want:
        try:
            flex.Method = kwds['Method']
        except KeyError:
            flex.Method = 'FD'
        try:
            flex.PlateSolutionType = kwds['PlateSolutionType']
        except KeyError:
            flex.PlateSolutionType = 'vWC1994'
        try:
            flex.Solver = kwds['Solver']
        except KeyError:
            flex.Solver = 'direct'
        try:
            quiet = kwds['Quiet']
        except KeyError:
            flex.Quiet = True
        else:
            flex.Quiet = bool(quiet)

        flex.E = float(Youngs_modulus)
        flex.nu = float(Poissons_ratio)
        flex.rho_m = float(rho_mantle)
        flex.rho_fill = float(rho_fill)
        flex.g = float(g)
        flex.BC_W = BC_W
        flex.BC_E = BC_E
        flex.BC_S = BC_S
        flex.BC_N = BC_N
        for i in (flex.BC_E, flex.BC_W, flex.BC_N, flex.BC_S):
            assert i in BC_options

        if BC_W == 'Periodic':
            assert BC_E == 'Periodic'
        if BC_E == 'Periodic':
            assert BC_W == 'Periodic'
        if BC_N == 'Periodic':
            assert BC_S == 'Periodic'
        if BC_S == 'Periodic':
            assert BC_N == 'Periodic'

        Te_in = elastic_thickness
        try:
            flex.Te = float(Te_in)
        except ValueError:
            try:
                flex.Te = grid.at_node[Te_in].view().reshape(grid.shape)
            except TypeError:
                flex.Te = Te_in.view().reshape(grid.shape)
            self._input_var_names.add(Te_in)
            self._output_var_names.add(Te_in)

        # set up the link between surface load stresses in the gFlex component
        # and the LL grid field:
        flex.qs = grid.at_node['surface_load__stress'].view().reshape(
            grid.shape)

        # create a holder for the "pre-flexure" state of the grid, to allow
        # updating of elevs:
        self.pre_flex = np.zeros(grid.number_of_nodes, dtype=float)

        # create the primary output field:
        self.grid.add_zeros('lithosphere__vertical_displacement',
                            at='node',
                            dtype=float,
                            noclobber=False)
示例#4
0
def main():
    """
    Superposition of analytical solutions in gFlex for flexural isostasy in
    GRASS GIS
    """

    options, flags = grass.parser()
    # if just interface description is requested, it will not get to this point
    # so gflex will not be needed

    # GFLEX
    # try to import gflex only after we know that
    # we will actually do the computation
    try:
        import gflex
    except:
        print("")
        print("MODULE IMPORT ERROR.")
        print(
            "In order to run r.flexure or g.flexure, you must download and install"
        )
        print("gFlex. The most recent development version is available from")
        print("https://github.com/awickert/gFlex")
        print("Installation instructions are available on the page.")
        grass.fatal("Software dependency must be installed.")

    ##########
    # SET-UP #
    ##########

    # This code is for 2D flexural isostasy
    flex = gflex.F2D()
    # And show that it is coming from GRASS GIS
    flex.grass = True

    # Method
    flex.Method = 'SAS_NG'

    # Parameters that are often changed for the solution
    ######################################################

    # x, y, q
    flex.x, flex.y = get_points_xy(options['input'])
    # xw, yw: gridded output
    if len(
            grass.parse_command('g.list',
                                type='vect',
                                pattern=options['output'])):
        if not grass.overwrite():
            grass.fatal("Vector map '" + options['output'] +
                        "' already exists. Use '--o' to overwrite.")
    # Just check raster at the same time if it exists
    if len(
            grass.parse_command('g.list',
                                type='rast',
                                pattern=options['raster_output'])):
        if not grass.overwrite():
            grass.fatal("Raster map '" + options['raster_output'] +
                        "' already exists. Use '--o' to overwrite.")
    grass.run_command('v.mkgrid',
                      map=options['output'],
                      type='point',
                      overwrite=grass.overwrite(),
                      quiet=True)
    grass.run_command('v.db.addcolumn',
                      map=options['output'],
                      columns='w double precision',
                      quiet=True)
    flex.xw, flex.yw = get_points_xy(
        options['output'])  # gridded output coordinates
    vect_db = grass.vector_db_select(options['input'])
    col_names = np.array(vect_db['columns'])
    q_col = (col_names == options['column'])
    if np.sum(q_col):
        col_values = np.array(list(vect_db['values'].values())).astype(float)
        flex.q = col_values[:, q_col].squeeze(
        )  # Make it 1D for consistency w/ x, y
    else:
        grass.fatal("provided column name, " + options['column'] +
                    " does not match\nany column in " + options['q0'] + ".")
    # Elastic thickness
    flex.Te = float(options['te'])
    if options['te_units'] == 'km':
        flex.Te *= 1000
    elif options['te_units'] == 'm':
        pass
    else:
        grass.fatal(
            "Inappropriate te_units. How? Options should be limited by GRASS.")
    flex.rho_fill = float(options['rho_fill'])

    # Parameters that often stay at their default values
    ######################################################
    flex.g = float(options['g'])
    flex.E = float(options['ym']
                   )  # Can't just use "E" because reserved for "east", I think
    flex.nu = float(options['nu'])
    flex.rho_m = float(options['rho_m'])

    # Set verbosity
    if grass.verbosity() >= 2:
        flex.Verbose = True
    if grass.verbosity() >= 3:
        flex.Debug = True
    elif grass.verbosity() == 0:
        flex.Quiet = True

    # Check if lat/lon and let user know if verbosity is True
    if grass.region_env()[6] == '3':
        flex.latlon = True
        flex.PlanetaryRadius = float(
            grass.parse_command('g.proj', flags='j')['+a'])
        if flex.Verbose:
            print("Latitude/longitude grid.")
            print("Based on r_Earth = 6371 km")
            print(
                "Computing distances between load points using great circle paths"
            )

    ##########
    # SOLVE! #
    ##########

    flex.initialize()
    flex.run()
    flex.finalize()

    # Now to use lower-level GRASS vector commands to work with the database
    # table and update its entries
    # See for help:
    # http://nbviewer.ipython.org/github/zarch/workshop-pygrass/blob/master/02_Vector.ipynb
    w = vector.VectorTopo(options['output'])
    w.open('rw')  # Get ready to read and write
    wdb = w.dblinks[0]
    wtable = wdb.table()
    col = int((np.array(
        wtable.columns.names()) == 'w').nonzero()[0])  # update this column
    for i in range(1, len(w) + 1):
        # ignoring 1st column: assuming it will be category (always true here)
        wnewvalues = list(w[i].attrs.values())[1:col] + tuple(
            [flex.w[i - 1]]) + list(w[i].attrs.values())[col + 1:]
        wtable.update(key=i, values=wnewvalues)
    wtable.conn.commit()  # Save this
    w.close(build=False)  # don't build here b/c it is always verbose
    grass.run_command('v.build', map=options['output'], quiet=True)

    # And raster export
    # "w" vector defined by raster resolution, so can do direct v.to.rast
    # though if this option isn't selected, the user can do a finer-grained
    # interpolation, which shouldn't introduce much error so long as these
    # outputs are spaced at << 1 flexural wavelength.
    if options['raster_output']:
        grass.run_command('v.to.rast',
                          input=options['output'],
                          output=options['raster_output'],
                          use='attr',
                          attribute_column='w',
                          type='point',
                          overwrite=grass.overwrite(),
                          quiet=True)
        # And create a nice colormap!
        grass.run_command('r.colors',
                          map=options['raster_output'],
                          color='differences',
                          quiet=True)
示例#5
0
    def buildGrid(self, nx, ny, youngMod, mantleDensity, sedimentDensity,
                    elasticT, elasticT2, Boundaries, xyTIN, ftime):
        """
        gFlex initialisation function.

        Args:
            nx: number of points along the X axis
            ny: number of points along the Y axis
            youngMod: Young's modulus
            mantleDensity: mantle density
            sedimentDensity: sediment density
            elasticT: elastic thickness. Can be scalar or an array
            elasticT2: initial elastic thickness.
            Boundaries: list of string describing boundary conditions for West, East, South and North.
            xyTIN: numpy float-type array containing the coordinates for each nodes in the TIN 
            ftime: flexure time step
        """
        # Build the flexural grid
        self.nx = nx
        self.ny = ny
        self.xyTIN = xyTIN
        xmin, xmax = min(self.xyTIN[:,0]), max(self.xyTIN[:,0])
        ymin, ymax = min(self.xyTIN[:,1]), max(self.xyTIN[:,1])
        self.xgrid = numpy.linspace(xmin,xmax,num=self.nx)
        self.ygrid = numpy.linspace(ymin,ymax,num=self.ny)
        self.xi, self.yi = numpy.meshgrid(self.xgrid, self.ygrid)
        self.xyi = numpy.dstack([self.xi.flatten(), self.yi.flatten()])[0]
        self.ftime = ftime

        # Call gFlex instance
        self.flex = gflex.F2D()
        flex = self.flex

        # Set-up the grid variable
        self.flex.dx = self.xgrid[1]-self.xgrid[0]
        self.flex.dy = self.ygrid[1]-self.ygrid[0]
        self.ball = math.sqrt(0.25*(self.flex.dx*self.flex.dx + self.flex.dy*self.flex.dy))
        tindx = self.xyTIN[1,0] - self.xyTIN[0,0]
        self.searchpts = max(int(self.flex.dx*self.flex.dy/(tindx*tindx)),4)

        # Solution method finite difference
        self.flex.Method = 'FD'
        self.flex.Quiet = True

        # van Wees and Cloetingh (1994)
        self.flex.PlateSolutionType = 'vWC1994'
        self.flex.Solver = 'direct'

        # Acceleration due to gravity
        self.flex.g = 9.8
        # Poisson's Ratio
        self.flex.nu = 0.25
        # Infill Material Density
        self.flex.rho_fill = 0.
        # Young's Modulus
        self.flex.E = youngMod
        # Mantle Density
        self.flex.rho_m = mantleDensity
        # Sediment Density
        self.rho_s = sedimentDensity
        # Sea Water Density
        self.rho_w = 1029.0
        # Elastic thickness [m]
        if isinstance(elasticT, str):
            TeMap = pandas.read_csv(elasticT, sep=r'\s+', engine='c', header=None,
                na_filter=False, dtype=numpy.float, low_memory=False)
            self.Te = numpy.reshape(TeMap.values, (self.ny, self.nx))
        elif elasticT2 is None:
            self.Te = elasticT * numpy.ones((self.ny, self.nx))
        else:
            self.Te = elasticT2 * numpy.ones((self.ny, self.nx))
            self.Te1 = elasticT

        # Surface load stresses
        self.flex.qs = numpy.zeros((self.ny, self.nx), dtype=float)

        # Boundary conditions
        self.flex.BC_W = Boundaries[0]
        self.flex.BC_E = Boundaries[1]
        self.flex.BC_S = Boundaries[2]
        self.flex.BC_N = Boundaries[3]

        # State of the previous flexural grid used for updating current
        # flexural displacements.
        self.previous_flex = numpy.zeros((self.ny, self.nx), dtype=float)

        self.tree = cKDTree(self.xyTIN)
        #self.Acell = Acell

        return
示例#6
0
    def __init__(
        self,
        grid,
        Youngs_modulus=6.5e11,
        Poissons_ratio=0.25,
        rho_mantle=3300.0,
        rho_fill=0.0,
        elastic_thickness=35000.0,
        Method="FD",
        Solver="direct",
        PlateSolutionType="vWC1994",
        quiet=True,
        BC_W="0Displacement0Slope",
        BC_E="0Displacement0Slope",
        BC_N="0Displacement0Slope",
        BC_S="0Displacement0Slope",
        g=scipy.constants.g,
    ):
        """Constructor for Wickert's gFlex in Landlab."""
        super(gFlex, self).__init__(grid)

        assert isinstance(grid, RasterModelGrid)

        if NO_GFLEX:
            raise ImportError(
                "gFlex not installed! For installation instructions see " +
                "gFlex on GitHub: https://github.com/awickert/gFlex")
        BC_options = (
            "0Displacement0Slope",
            "0Moment0Shear",
            "0Slope0Shear",
            "Periodic",
        )

        # instantiate the module:
        self._flex = gflex.F2D()
        flex = self._flex

        # set up the grid variables:

        flex.dx = grid.dx
        flex.dy = grid.dy

        # we assume these properties are fixed in this relatively
        # straightforward implementation, but they can still be set if you
        # want:
        flex.Method = Method
        flex.PlateSolutionType = PlateSolutionType
        flex.Solver = Solver
        flex.Quiet = quiet

        flex.E = float(Youngs_modulus)
        flex.nu = float(Poissons_ratio)
        flex.rho_m = float(rho_mantle)
        flex.rho_fill = float(rho_fill)
        flex.g = float(g)
        flex.BC_W = BC_W
        flex.BC_E = BC_E
        flex.BC_S = BC_S
        flex.BC_N = BC_N
        for i in (flex.BC_E, flex.BC_W, flex.BC_N, flex.BC_S):
            assert i in BC_options

        if BC_W == "Periodic":
            assert BC_E == "Periodic"
        if BC_E == "Periodic":
            assert BC_W == "Periodic"
        if BC_N == "Periodic":
            assert BC_S == "Periodic"
        if BC_S == "Periodic":
            assert BC_N == "Periodic"

        Te_in = elastic_thickness
        try:
            flex.Te = float(Te_in)
        except ValueError:
            try:
                flex.Te = grid.at_node[Te_in].view().reshape(grid.shape)
            except TypeError:
                flex.Te = Te_in.view().reshape(grid.shape)
            self._input_var_names.add(Te_in)
            self._output_var_names.add(Te_in)

        # set up the link between surface load stresses in the gFlex component
        # and the LL grid field:
        flex.qs = grid.at_node["surface_load__stress"].view().reshape(
            grid.shape)

        # create a holder for the "pre-flexure" state of the grid, to allow
        # updating of elevs:
        self._pre_flex = np.zeros(grid.number_of_nodes, dtype=float)

        # create the primary output field:
        self._grid.add_zeros(
            "lithosphere_surface__elevation_increment",
            at="node",
            dtype=float,
            clobber=True,
        )
示例#7
0
#! /usr/bin/env python

import gflex
import numpy as np
from matplotlib import pyplot as plt

flex = gflex.F2D()

flex.Quiet = False

flex.Method = 'FD' # Solution method: * FD (finite difference)
                   #                  * SAS (superposition of analytical solutions)
                   #                  * SAS_NG (ungridded SAS)
flex.PlateSolutionType = 'vWC1994' # van Wees and Cloetingh (1994)
                                   # The other option is 'G2009': Govers et al. (2009)
flex.Solver = 'direct' # direct or iterative
# convergence = 1E-3 # convergence between iterations, if an iterative solution
                     # method is chosen

flex.g = 9.8 # acceleration due to gravity
flex.E = 65E9 # Young's Modulus
flex.nu = 0.25 # Poisson's Ratio
flex.rho_m = 3300. # MantleDensity
flex.rho_fill = 0. # InfiillMaterialDensity

flex.Te = 35000.*np.ones((50, 50)) # Elastic thickness [m] -- scalar but may be an array
flex.Te[:,-3:] = 0.
flex.qs = np.zeros((50, 50)) # Template array for surface load stresses
flex.qs[10:40, 10:40] += 1E6 # Populating this template
flex.dx = 5000. # grid cell size, x-oriented [m]
flex.dy = 5000. # grid cell size, y-oriented [m]
示例#8
0
def main():
    """
    Gridded flexural isostatic solutions
    """

    options, flags = grass.parser()
    # if just interface description is requested, it will not get to this point
    # so gflex will not be needed

    # GFLEX
    # try to import gflex only after we know that
    # we will actually do the computation
    try:
        import gflex
    except:
        print("")
        print("MODULE IMPORT ERROR.")
        print("In order to run r.flexure or g.flexure, you must download and install")
        print("gFlex. The most recent development version is available from")
        print("https://github.com/awickert/gFlex.")
        print("Installation instructions are available on the page.")
        grass.fatal("Software dependency must be installed.")

    # This code is for 2D flexural isostasy
    flex = gflex.F2D()
    # And show that it is coming from GRASS GIS
    flex.grass = True

    # Flags
    latlon_override = flags["l"]

    # Inputs
    # Solution selection
    flex.Method = options["method"]
    if flex.Method == "FD":
        flex.Solver = options["solver"]
        if flex.Solver:
            flex.ConvergenceTolerance = options["tolerance"]
        # Always use the van Wees and Cloetingh (1994) solution type.
        # It is the best.
        flex.PlateSolutionType = "vWC1994"
    # Parameters that are often changed for the solution
    qs = options["input"]
    flex.qs = garray.array()
    flex.qs.read(qs)
    # Elastic thickness
    try:
        flex.Te = float(options["te"])
    except:
        flex.Te = garray.array()  # FlexureTe is the one that is used by Flexure
        flex.Te.read(options["te"])
        flex.Te = np.array(flex.Te)
    if options["te_units"] == "km":
        flex.Te *= 1000
    elif options["te_units"] == "m":
        pass
    # No "else"; shouldn't happen
    flex.rho_fill = float(options["rho_fill"])
    # Parameters that often stay at their default values
    flex.g = float(options["g"])
    flex.E = float(
        options["ym"]
    )  # Can't just use "E" because reserved for "east", I think
    flex.nu = float(options["nu"])
    flex.rho_m = float(options["rho_m"])
    # Solver type and iteration tolerance
    flex.Solver = options["solver"]
    flex.ConvergenceTolerance = float(options["tolerance"])
    # Boundary conditions
    flex.BC_N = options["northbc"]
    flex.BC_S = options["southbc"]
    flex.BC_W = options["westbc"]
    flex.BC_E = options["eastbc"]

    # Set verbosity
    if grass.verbosity() >= 2:
        flex.Verbose = True
    if grass.verbosity() >= 3:
        flex.Debug = True
    elif grass.verbosity() == 0:
        flex.Quiet = True

    # First check if output exists
    if len(grass.parse_command("g.list", type="rast", pattern=options["output"])):
        if not grass.overwrite():
            grass.fatal(
                "Raster map '"
                + options["output"]
                + "' already exists. Use '--o' to overwrite."
            )

    # Get grid spacing from GRASS
    # Check if lat/lon and proceed as directed
    if grass.region_env()[6] == "3":
        if latlon_override:
            if flex.Verbose:
                print("Latitude/longitude grid.")
                print("Based on r_Earth = 6371 km")
                print("Setting y-resolution [m] to 111,195 * [degrees]")
            flex.dy = grass.region()["nsres"] * 111195.0
            NSmid = (grass.region()["n"] + grass.region()["s"]) / 2.0
            dx_at_mid_latitude = (
                (3.14159 / 180.0) * 6371000.0 * np.cos(np.deg2rad(NSmid))
            )
            if flex.Verbose:
                print(
                    "Setting x-resolution [m] to "
                    + "%.2f" % dx_at_mid_latitude
                    + " * [degrees]"
                )
            flex.dx = grass.region()["ewres"] * dx_at_mid_latitude
        else:
            grass.fatal("Need the '-l' flag to enable lat/lon solution approximation.")
    # Otherwise straightforward
    else:
        flex.dx = grass.region()["ewres"]
        flex.dy = grass.region()["nsres"]

    # CALCULATE!
    flex.initialize()
    flex.run()
    flex.finalize()

    # Write to GRASS
    # Create a new garray buffer and write to it
    outbuffer = garray.array()  # Instantiate output buffer
    outbuffer[...] = flex.w
    outbuffer.write(
        options["output"], overwrite=grass.overwrite()
    )  # Write it with the desired name
    # And create a nice colormap!
    grass.run_command(
        "r.colors", map=options["output"], color="differences", quiet=True
    )
示例#9
0
    def initialize(self, grid, params):
        """
        grid must be a landlab RasterModelGrid to use gFlex.

        params may be a dictionary of input parameters, or a standard Landlab
        input text file.

        gFlex requires:
        * E, Young's modulus
        * nu, Poisson's ratio
        * rho_m, the mantle density
        * rho_fill, the infill material density
        * Te, the elastic thickness. Can be scalar or an nnodes-long array.
            If you want an array, supply a grid field name where the data can
            be found.
        * BC_W, BC_E, BC_S, BC_N, strings describing the boundary conditions.
            Choose from ('Dirichlet0', '0Moment0Shear', 'Periodic').


        gFlex can take as options:
        * g, the gravitational acceleration (defaults to 9.81)

        gFlex takes as input fields:
        * surface_load__stress

        gFlex modifies/returns:
        * topographic__elevation (if it exists already)
        * lithosphere__vertical_displacement


        """
        assert RasterModelGrid in inspect.getmro(grid.__class__)
        BC_options = ('Dirichlet0', '0Moment0Shear', '0Slope0Shear',
                      'Periodic')

        if type(params) == str:
            input_dict = ModelParameterDictionary(params)
        else:
            assert type(params) == dict
            input_dict = params

        #instantiate the module:
        self.flex = gflex.F2D()
        flex = self.flex

        #set up the grid variables:
        self._grid = grid
        flex.dx = grid.dx
        flex.dy = grid.dy

        #we assume these properties are fixed in this relatively
        #straightforward implementation, but they can still be set if you want:
        try:
            flex.Method = input_dict['Method']
        except KeyError:
            flex.Method = 'FD'
        try:
            flex.PlateSolutionType = input_dict['PlateSolutionType']
        except KeyError:
            flex.PlateSolutionType = 'vWC1994'
        try:
            flex.Solver = input_dict['Solver']
        except KeyError:
            flex.Solver = 'direct'
        try:
            quiet = input_dict['Quiet']
        except KeyError:
            flex.Quiet = True
        else:
            flex.Quiet = bool(quiet)

        flex.E = float(input_dict['E'])
        flex.nu = float(input_dict['nu'])
        flex.rho_m = float(input_dict['rho_m'])
        flex.rho_fill = float(input_dict['rho_fill'])
        try:
            flex.g = input_dict['g']
        except KeyError:
            flex.g = 9.81
        flex.BC_W = input_dict['BC_W']
        flex.BC_E = input_dict['BC_E']
        flex.BC_S = input_dict['BC_S']
        flex.BC_N = input_dict['BC_N']
        for i in (flex.BC_E, flex.BC_W, flex.BC_N, flex.BC_S):
            assert i in BC_options

        Te_in = input_dict['Te']
        try:
            flex.Te = float(Te_in)
        except ValueError:
            flex.Te = grid.at_node[Te_in].view().reshape(
                (grid.number_of_node_rows, grid.number_of_node_columns))
            self._input_var_names.add(Te_in)
            self._output_var_names.add(Te_in)

        #set up the link between surface load stresses in the gFlex component and the LL grid field:
        flex.qs = grid.at_node['surface_load__stress'].view().reshape(
            (grid.number_of_node_rows, grid.number_of_node_columns))

        #create a holder for the "pre-flexure" state of the grid, to allow updating of elevs:
        self.pre_flex = np.zeros(grid.number_of_nodes, dtype=float)
示例#10
0
    def buildGrid(self, nx, ny, youngMod, mantleDensity, sedimentDensity,
                  elasticT, Boundaries, xyTIN):
        """
        gFlex initialisation function.

        Parameters
        ----------
        variable : nx, ny
            Number of points along the X and Y axis

        variable : youngMod
            Young's modulus

        variable : mantleDensity
            Mantle density

        variable : sedimentDensity
            Sediment density

        variable : elasticT
            The elastic thickness. Can be scalar or an array

        variable : Boundaries
            List of string describing boundary conditions for West, East, South and North
            Choose from '0Slope0Shear', 'Dirichlet0', '0Displacement0Slope',
                        '0Moment0Shear', 'Periodic', 'Mirror'

        variable : xyTIN
            Numpy float-type array containing the coordinates for each nodes in the TIN (in m2)
        """
        # Build the flexural grid
        self.nx = nx
        self.ny = ny
        self.xyTIN = xyTIN
        xmin, xmax = min(self.xyTIN[:, 0]), max(self.xyTIN[:, 0])
        ymin, ymax = min(self.xyTIN[:, 1]), max(self.xyTIN[:, 1])
        self.xgrid = numpy.linspace(xmin, xmax, num=self.nx)
        self.ygrid = numpy.linspace(ymin, ymax, num=self.ny)
        self.xi, self.yi = numpy.meshgrid(self.xgrid, self.ygrid)
        self.xyi = numpy.dstack([self.xi.flatten(), self.yi.flatten()])[0]

        # Call gFlex instance
        self.flex = gflex.F2D()
        flex = self.flex

        # Set-up the grid variable
        self.flex.dx = self.xgrid[1] - self.xgrid[0]
        self.flex.dy = self.ygrid[1] - self.ygrid[0]
        self.ball = math.sqrt(
            0.25 * (self.flex.dx * self.flex.dx + self.flex.dy * self.flex.dy))
        tindx = self.xyTIN[1, 0] - self.xyTIN[0, 0]
        self.searchpts = max(
            int(self.flex.dx * self.flex.dy / (tindx * tindx)), 4)
        '''
        area = numpy.zeros((self.nx, self.ny))
        area.fill(self.flex.dx*self.flex.dy)
        area[0,:] = 0.5 * self.flex.dx*self.flex.dy
        area[self.nx-1,:] = 0.5 * self.flex.dx*self.flex.dy
        area[:,0] = 0.5 * self.flex.dx*self.flex.dy
        area[:,self.ny-1] = 0.5 * self.flex.dx*self.flex.dy
        area[0,0] = 0.25 * self.flex.dx*self.flex.dy
        area[self.nx-1,0] = area[0,0]
        area[0,self.ny-1] = area[0,0]
        area[self.nx-1,self.ny-1] = area[0,0]
        self.Area = area.flatten()
        '''

        # Solution method finite difference
        self.flex.Method = 'FD'
        self.flex.Quiet = True

        # van Wees and Cloetingh (1994)
        self.flex.PlateSolutionType = 'vWC1994'
        self.flex.Solver = 'direct'

        # Acceleration due to gravity
        self.flex.g = 9.8
        # Poisson's Ratio
        self.flex.nu = 0.25
        # Infill Material Density
        self.flex.rho_fill = 0.
        # Young's Modulus
        self.flex.E = youngMod
        # Mantle Density
        self.flex.rho_m = mantleDensity
        # Sediment Density
        self.rho_s = sedimentDensity
        # Sea Water Density
        self.rho_w = 1029.0
        # Elastic thickness [m]
        if isinstance(elasticT, basestring):
            TeMap = pandas.read_csv(elasticT,
                                    sep=r'\s+',
                                    engine='c',
                                    header=None,
                                    na_filter=False,
                                    dtype=numpy.float,
                                    low_memory=False)
            self.Te = numpy.reshape(TeMap.values, (self.ny, self.nx))
        else:
            self.Te = elasticT * numpy.ones((self.ny, self.nx))

        # Surface load stresses
        self.flex.qs = numpy.zeros((self.ny, self.nx), dtype=float)

        # Boundary conditions
        self.flex.BC_W = Boundaries[0]
        self.flex.BC_E = Boundaries[1]
        self.flex.BC_S = Boundaries[2]
        self.flex.BC_N = Boundaries[3]

        # State of the previous flexural grid used for updating current
        # flexural displacements.
        self.previous_flex = numpy.zeros((self.ny, self.nx), dtype=float)

        self.tree = cKDTree(self.xyTIN)
        #self.Acell = Acell

        return