Пример #1
0
    def __init__(self,
                 swarm=None,
                 materialIndexField=None,
                 air=None,
                 sediment=None,
                 threshold=None):

        self.materialIndexField = materialIndexField
        self.swarm = swarm
        self.threshold = nd(threshold)

        materialMap = {}
        for material in air:
            materialMap[material.index] = 1.0

        isAirMaterial = fn.branching.map(fn_key=materialIndexField,
                                         mapping=materialMap,
                                         fn_default=0.0)

        sedimentation = [
            (((isAirMaterial > 0.5) & (fn.input()[1] < nd(threshold))),
             sediment[0].index), (True, materialIndexField)
        ]
        erosion = [(((isAirMaterial < 0.5) & (fn.input()[1] > nd(threshold))),
                    sediment[0].index), (True, materialIndexField)]

        self._fn1 = fn.branching.conditional(belowthreshold)
        self._fn2 = fn.branching.conditional(belowthreshold)
Пример #2
0
def fn_Tukey_window(r, centre, width, top, bottom):
    """ Define a tuckey window

    A Tukey window is a rectangular window with the first and last r/2
    percent of the width equal to parts of a cosine.
    see tappered cosine function

    """

    centre = nd(centre)
    width = nd(width)
    top = nd(top)
    bottom = nd(bottom)

    x = fn.input()[0]
    y = fn.input()[1]

    start = centre - 0.5 * width
    xx = (x - start) / width
    x_conditions = [
        ((0. <= xx) & (xx < r / 2.0),
         0.5 * (1.0 + fn.math.cos(2. * np.pi / r * (xx - r / 2.0)))),
        ((r / 2.0 <= xx) & (xx < 1.0 - r / 2.0), 1.0),
        ((1.0 - r / 2.0 <= xx) & (xx <= 1.0),
         0.5 * (1. + fn.math.cos(2. * np.pi / r * (xx + r / 2.0)))),
        (True, 0.0)
    ]

    x_conditions = fn.branching.conditional(x_conditions)

    y_conditions = fn.branching.conditional([((y >= bottom) & (y <= top), 1.0),
                                             (True, 0.0)])
    return x_conditions * y_conditions
Пример #3
0
 def _init_shape(self):
     center = tuple(nd(x) for x in list(self.center))
     r1 = nd(self.r1)
     r2 = nd(self.r2)
     coord = fn.input() - center
     self._fn = (fn.math.dot(coord, coord) < r2**2) & (fn.math.dot(
         coord, coord) > r1**2)
Пример #4
0
 def _fn(self):
     center = tuple(nd(x) for x in list(self.center))
     r1 = nd(self.r1)
     r2 = nd(self.r2)
     coord = fn.input() - center
     return (fn.math.dot(coord, coord) < r2**2) & (fn.math.dot(
         coord, coord) > r1**2)
Пример #5
0
    def __init__(self, center, radius):
        """Create a Disk shape

        Parameters
        ----------

        center : center of the disk
        radius : radius of the disk

        Returns
        -------

        An UWGeodynamics Shape
        """
        self.center = center
        self.radius = radius
        self.top = center[1] + self.radius
        self.bottom = center[1] - self.radius

        center = tuple(nd(x) for x in list(self.center))
        radius = nd(self.radius)
        coord = fn.input() - center
        self._fn = fn.math.dot(coord, coord) < radius**2
        super(Disk, self).__init__(argument_fns=None)
        self._fncself = self._fn._fncself
Пример #6
0
    def __init__(self, center, r1, r2):
        """Create an Annulus shape

        Parameters
        ----------

        center : center of the annulus
        r1 : Internal radius
        r2 : External radius

        Returns
        -------

        An UWGeodynamics Shape object
        """
        self.center = center
        self.r1 = r1
        self.r2 = r2
        self.bottom = center[1] - self.r2
        self.top = center[1] + self.r2

        center = tuple(nd(x) for x in list(self.center))
        r1 = nd(self.r1)
        r2 = nd(self.r2)
        coord = fn.input() - center
        self._fn = (fn.math.dot(coord, coord) < r2**2) & (fn.math.dot(
            coord, coord) > r1**2)
        super(Annulus, self).__init__(argument_fns=None)
        self._fncself = self._fn._fncself
Пример #7
0
 def _init_shape(self):
     coord = fn.input()
     if (self.minY is not None) and (self.maxY is not None):
         self._fn = ((coord[2] <= nd(self.top)) &
                     (coord[2] >= nd(self.bottom)))
     else:
         self._fn = ((coord[1] <= nd(self.top)) &
                     (coord[1] >= nd(self.bottom)))
Пример #8
0
def post_hook():
    coords = fn.input()
    zz = coords[0] / (GEO.nd(Model.maxCoord[0]) - GEO.nd(Model.minCoord[0]))
    fact = fn.math.pow(
        fn.math.tanh(zz * 20.0) + fn.math.tanh(
            (1.0 - zz) * 20.0) - fn.math.tanh(20.0), 4)
    Model.plasticStrain.data[:] = Model.plasticStrain.data[:] * fact.evaluate(
        Model.swarm)
Пример #9
0
    def _create_function(self):

        # Create wall function
        operator = self.wall_operators[self._wall]
        axis = self.wall_direction_axis[self._wall]
        pos = self.wall_init_pos[self._wall]
        condition = [(operator(fn.input()[axis],
                               (self._time * self.velocityFn + nd(pos))),
                      True), (True, False)]

        return fn.branching.conditional(condition)
Пример #10
0
 def _fn(self):
     coord = fn.input()
     if (self.minY is not None) and (self.maxY is not None):
         func = ((coord[1] <= nd(self.maxY)) & (coord[1] >= nd(self.minY)) &
                 (coord[0] <= nd(self.maxX)) & (coord[0] >= nd(self.minX)) &
                 (coord[2] <= nd(self.top)) & (coord[2] >= nd(self.bottom)))
     else:
         func = ((coord[1] <= nd(self.top)) & (coord[1] >= nd(self.bottom))
                 & (coord[0] <= nd(self.maxX)) &
                 (coord[0] >= nd(self.minX)))
     return func
Пример #11
0
def post_hook():
    """
    Stop any brittle yielding near the edges of the model
    """
    coords = fn.input()
    zz = (coords[0] - GEO.nd(Model.minCoord[0])) / (GEO.nd(Model.maxCoord[0]) -
                                                    GEO.nd(Model.minCoord[0]))
    fact = fn.math.pow(
        fn.math.tanh(zz * 20.0) + fn.math.tanh(
            (1.0 - zz) * 20.0) - fn.math.tanh(20.0), 4)
    Model.plasticStrain.data[:] = Model.plasticStrain.data[:] * fact.evaluate(
        Model.swarm)
Пример #12
0
    def _fn(self):
        coords = fn.input()
        new_coords = coords - self.origin
        func = fn.math.dot(self.normal, new_coords)

        # True if below, False if above
        if not self.reverse:
            conditions = [(func <= 0., True), (func > 0., False)]
        else:
            conditions = [(func >= 0., True), (func < 0., False)]

        return fn.branching.conditional(conditions)
Пример #13
0
def post_hook():
    """
    Stop any brittle yielding near the edges of the model
    """
    coords = fn.input()
    zz = (coords[0] - GEO.nd(Model.minCoord[0])) / (GEO.nd(Model.maxCoord[0]) - GEO.nd(Model.minCoord[0]))
    fact = fn.math.pow(fn.math.tanh(zz*20.0) + fn.math.tanh((1.0-zz)*20.0) - fn.math.tanh(20.0), 4)
    Model.plasticStrain.data[:] = Model.plasticStrain.data[:] * fact.evaluate(Model.swarm)

    """
    Check spacing for when sedimentation should turn off
    # This solution was provided by: https://stackoverflow.com/a/38008452
    """
    rank = uw.rank()
    root = 0

    # get all the moho tracers that are on our CPU, in x sorted order
    moho_tracers = Model.passive_tracers["Moho"]  # Need this for restart safety
    local_array = numpy.sort(moho_tracers.swarm.particleCoordinates.data[:,0])
    sendbuf = numpy.array(local_array)

    # We have to figure out how many particles each CPU has, and let the root
    # cpu know
    sendcounts = numpy.array(MPI.COMM_WORLD.gather(len(sendbuf), root))

    if rank == root:
        # prepare to receive all this data
        recvbuf = numpy.empty(sum(sendcounts), dtype=float)
    else:
        recvbuf = None

    # Gather up all the data and put it in recvbuf
    MPI.COMM_WORLD.Gatherv(sendbuf=sendbuf, recvbuf=(recvbuf, sendcounts), root=root)
    if rank == root:
        # find the biggest gap in the X direction in the moho_tracers
        diff = numpy.max(numpy.diff(numpy.sort(recvbuf)))  # recvbuf is the array of all particles
    else:
        diff = None

    # Now that we know the biggest gap, tell all the other CPUs
    diff = MPI.COMM_WORLD.bcast(diff, root=0)
    biggest_gap = GEO.Dimensionalize(diff, u.km)
    uw.barrier()
    print(uw.rank(), "Biggest gap in tracers", biggest_gap)

    if biggest_gap > gap_to_stop_sedi:
        print("Sedimentation turned: OFF at {}".format(Model.time))
        threshold = -10 * u.kilometers
    else:
        print("Sedimentation turned: ON")
        threshold = -1 * u.kilometers

    Model.surfaceProcesses = GEO.surfaceProcesses.SedimentationThreshold(air=[air], sediment=[sediment], threshold=threshold)
Пример #14
0
    def _init_model(self):

        materialField = self.Model.materialField

        materialMap = {}
        for material in self.air:
            materialMap[material.index] = 1.0

        isAirMaterial = fn.branching.map(fn_key=materialField,
                                         mapping=materialMap,
                                         fn_default=0.0)

        belowthreshold = [(((isAirMaterial < 0.5) & (fn.input()[1] > nd(self.threshold))), self.air[0].index),
                          (True, materialField)]

        self._fn = fn.branching.conditional(belowthreshold)
Пример #15
0
    def __init__(self, mesh, starttime, endtime, dt):

        #init the parent class

        nx.DiGraph.__init__(self)
        ################################

        self.times = np.arange(starttime, endtime, dt)
        #self.add_node('times', times=self.times)
        self.plateIdUsedList = []
        self.plateIdDefaultList = list(np.arange(1, 101))
        self.plateDummyId = -99

        #mesh and coordinate functions
        self.mesh = mesh
        self._coordinate = fn.input()
        self._xFn = self._coordinate[0]
Пример #16
0
    def __init__(self, normal, origin=None, reverse=False):
        """ HalfSpace

        Parameters:
        -----------

        normal: A vector defining the normal to the plan.
        origin: Origin
        reverse: by default, particles tested against this class are
                 assigned "True" if they lay on or below the plan.
                 You can reverse than behavior by setting reverse=True.

        Returns:
        --------

        A UWGeodynamics Shape object.

        """

        if isinstance(normal, (tuple, list)):
            self.normal = fn.misc.constant([float(nd(val)) for val in normal])
        else:
            raise ValueError("{0} must be a list or tuple".format(normal))

        if isinstance(origin, (tuple, list)):
            self.origin = fn.misc.constant([float(nd(val)) for val in origin])
        else:
            self.origin = fn.misc.constant([0.] * len(normal))

        self.reverse = reverse

        coords = fn.input()
        new_coords = coords - self.origin
        func = fn.math.dot(self.normal, new_coords)

        # True if below, False if above
        if not self.reverse:
            conditions = [(func <= 0., True), (func > 0., False)]
        else:
            conditions = [(func >= 0., True), (func < 0., False)]

        self._fn = fn.branching.conditional(conditions)
        super(HalfSpace, self).__init__(argument_fns=None)
        self._fncself = self._fn._fncself
Пример #17
0
    def __init__(self, top, bottom, minX=0., maxX=0., minY=None, maxY=None):
        """Create a Box Shape

        Parameters
        ----------

        top : Top of the Box
        bottom : Bottom of the Box
        minX : Minimum extent of the Box along the x-axis
        maxX : Maximum extent of the Box along the x-axis

        Only in 3D:

        minY : Minimum extent of the Box along the y-axis
        maxY : Maximum extent of the Box along the y-axis

        Returns
        -------
        """
        self.top = top
        self.bottom = bottom
        self.minX = minX
        self.maxX = maxX
        self.minY = minY
        self.maxY = maxY

        coord = fn.input()
        if (self.minY is not None) and (self.maxY is not None):
            func = ((coord[1] <= nd(self.maxY)) &
                    (coord[1] >= nd(self.minY)) &
                    (coord[0] <= nd(self.maxX)) &
                    (coord[0] >= nd(self.minX)) &
                    (coord[2] <= nd(self.top)) &
                    (coord[2] >= nd(self.bottom)))
        else:
            func = ((coord[1] <= nd(self.top)) &
                    (coord[1] >= nd(self.bottom)) &
                    (coord[0] <= nd(self.maxX)) &
                    (coord[0] >= nd(self.minX)))
        self._fn = func
        super(Box, self).__init__(argument_fns=None)
        self._fncself = self._fn._fncself
Пример #18
0
    def __init__(self, top, bottom):
        """Create a 2D Layer object

        Parameters
        ----------

        top : top of the layer
        bottom : bottom of the layer

        Returns
        -------

        AN UWGeodynamics Shape object
        """
        self.top = top
        self.bottom = bottom

        coord = fn.input()
        self._fn = ((coord[1] <= nd(self.top)) & (coord[1] >= nd(self.bottom)))
        super(Layer, self).__init__(argument_fns=None)
        self._fncself = self._fn._fncself
Пример #19
0
 def muEff(self):
     coord = fn.input()
     return (self._eta0 * fn.math.exp(self._gamma *
                                      (coord[-1] - self._reference)))
Пример #20
0
temperatureDotField = uw.mesh.MeshVariable(
    mesh=mesh, nodeDofCount=1)  #create this only if Adv-diff
diffusivityFn = fn.misc.constant(1.)

# In[12]:

velocityField.data[:] = 0.
pressureField.data[:] = 0.
temperatureField.data[:] = 0.
initialtemperatureField.data[:] = 0.

# In[13]:

#Uw geometry shortcuts

coordinate = fn.input()
depthFn = mesh.maxCoord[1] - coordinate[1]  #a function providing the depth

xFn = coordinate[0]  #a function providing the x-coordinate
yFn = coordinate[1]

# ## Swarm

# In[14]:

swarm = uw.swarm.Swarm(mesh=mesh, particleEscape=True)
materialVariable = swarm.add_variable(dataType="int", count=1)

layout = uw.swarm.layouts.PerCellRandomLayout(swarm=swarm,
                                              particlesPerCell=int(md.ppc))
swarm.populate_using_layout(layout=layout)  # Now use it to populate.
Пример #21
0
# #Material properties
# 

# In[18]:

#Make variables required for plasticity

secinvCopy = fn.tensor.second_invariant( 
                    fn.tensor.symmetric( 
                        velocityField.gradientFn ))


# In[19]:

coordinate = fn.input()


# In[20]:

newvisc


# In[21]:

#Remember to use floats everywhere when setting up functions

#Linear viscosities
#viscosityl1 = fn.math.exp(math.log(ETA_T)*-1*temperatureField)
#viscosityl1 = fn.math.exp((math.log(ETA_T)*-1*temperatureField) + (math.log(ETA_T)*-1*0.64))
viscosityl1 = newvisc*fn.math.exp(math.log(ETA_T)*-1*temperatureField)
Пример #22
0
 def _fn(self):
     coord = fn.input()
     func = ((coord[2] <= nd(self.top)) & (coord[2] >= nd(self.bottom)))
     return func
Пример #23
0
 def _fn(self):
     center = tuple(nd(x) for x in list(self.center))
     radius = nd(self.radius)
     coord = fn.input() - center
     return fn.math.dot(coord, coord) < radius**2
Пример #24
0

# ### Material distribution in the domain.
# 
# 

# In[11]:

# Initialise the 'materialVariable' data to represent different materials. 
materialV = 0 # viscoplastic
materialW = 1 # weak
materialA = 2 # accommodation layer a.k.a. Sticky Air

# The particle coordinates will be the input to the function evaluate (see final line in this cell).
# We get proxy for this now using the input() function.
coord = fn.input()

# Setup the conditions list for the following conditional function. Where the
# z coordinate (coordinate[1]) is less than the perturbation, set to lightIndex.
conditions = [ (                                  coord[1] > thicknessV , materialA ),
               ( ((coord[1] < dWeak) & (coord[0]**2. < (dWeak**2.)/4.)) , materialW ),
               (                                                   True , materialV ) ]

# The actual function evaluation. Here the conditional function is evaluated at the location
# of each swarm particle. The results are then written to the materialVariable swarm variable.
materialVariable.data[:] = fn.branching.conditional( conditions ).evaluate(swarm)


# Define the density function
# ---
# In[ ]:

# **Define the rheology**

# In[21]:
print '*** define rheology ***'
# strain rate invariant
strainRateFn = fn.tensor.symmetric(velocityField.fn_gradient)
strainRate_2ndInvariantFn = fn.tensor.second_invariant(strainRateFn)
strainRate_2ndInvariantFn_scaled = strainRate_2ndInvariantFn * (kappa / (
    (boxHeight * 1e6)**2))

# In[22]:

# hydrostatice pressure
yCoord = fn.input()[1] * 1e6
z_hat = -1.0 * (yCoord)
P_stat = rho0 * g * z_hat

# In[23]:

# adiabatic gradiet to temperature solution, 0.5 K/km
Tm = (z_hat / 1e3) * 0.5 + (temperatureField * deltaTemp) + Temp_Min

# In[24]:

# limiters
eta_max = 1e24  # Pa.s, maximum viscosity
eta_min = 1e19  # Pa.s, minimum viscosity

# In[25]:
Пример #26
0
 def _init_shape(self):
     center = tuple(nd(x) for x in list(self.center))
     radius = nd(self.radius)
     coord = fn.input() - center
     self._fn = fn.math.dot(coord, coord) < radius**2
Пример #27
0
    def __init__(self, sealevel, water_material=None):

        self.condition = fn.input()[1] < nd(sealevel)
        self.result = water_material.index
Пример #28
0
#
#

# In[16]:

# Initialise the 'materialVariable' data to represent different materials.
material1 = 1  # viscoplastic
material0 = 0  # accommodation layer a.k.a. Sticky Air
material2 = 2  # Under layer

materialVariable.data[:] = 0.

# The particle coordinates will be the input to the function evaluate (see final line in this cell).
# We get proxy for this now using the input() function.

coord = fn.input()

# Setup the conditions list for the following conditional function. Where the
# z coordinate (coordinate[1]) is less than the perturbation, set to lightIndex.

#notchWidth = (1./32.) * md.notch_fac

notchCond = operator.and_(
    coord[1] < ndp.asthenosphere + ndp.notchWidth,
    operator.and_(coord[0] < ndp.notchWidth, coord[0] > -1. * ndp.notchWidth))

mu = ndp.notchWidth
sig = 0.25 * ndp.notchWidth
gausFn1 = ndp.notchWidth * fn.math.exp(-1. * (coord[0] - mu)**2 /
                                       (2 * sig**2)) + ndp.asthenosphere
mu = -1. * ndp.notchWidth