コード例 #1
0
ファイル: geodynamics.py プロジェクト: squireg/underworld2
    def _set_mesh(self):

        minCoord = tuple([nd(val) for val in self.minCoord])
        maxCoord = tuple([nd(val) for val in self.maxCoord])

        self.mesh = uw.mesh.FeMesh_Cartesian(elementType=self.elementType,
                                             elementRes=self.elementRes,
                                             minCoord=minCoord,
                                             maxCoord=maxCoord,
                                             periodic=self.periodic)
コード例 #2
0
ファイル: geodynamics.py プロジェクト: squireg/underworld2
 def __init__(self, name="User defined", func=None):
     self.name = name
     if not isinstance(func, dict):
         self.fn = fn.misc.constant(nd(func))
     else:
         dictVals = func
         self.coefs = dictVals["coefficients"]
         self._nd_coefs = {
             key: nd(val)
             for key, val in self.coefs.iteritems()
         }
         self.fn = rheology.Functions[dictVals["Type"]]
コード例 #3
0
ファイル: geodynamics.py プロジェクト: squireg/underworld2
    def _set_density(self):
        densityMap = {}
        for material in self.materials:
            if self.temperature:
                densityMap[material.index] = nd(material.density) * (
                    1.0 - nd(material.thermalExpansivity) *
                    (self.temperature - nd(self.Tref)))
            else:
                densityMap[material.index] = nd(material.density)

        self.densityFn = fn.branching.map(fn_key=self.material,
                                          mapping=densityMap)
コード例 #4
0
ファイル: geodynamics.py プロジェクト: squireg/underworld2
    def _set_viscosity(self):

        ViscosityMap = {}
        BGViscosityMap = {}
        for material in self.materials:
            backgroundViscosity = material.viscosity._get_effective_viscosity(
                self.pressure, self.strainRate, self.temperature,
                self.solutionExist)

            ViscosityMap[material.index] = self._viscosity_limiter(
                backgroundViscosity)

            BGViscosityMap[material.index] = ViscosityMap[material.index]

            if material.plasticity:
                eff_viscosity = material.plasticity._get_effective_viscosity(
                    self.plasticStrain, self.pressure,
                    self.strainRate_2ndInvariant, nd(self.strainRate_default))
                ViscosityMap[material.index] = self._viscosity_limiter(
                    fn.misc.min(eff_viscosity, backgroundViscosity))

        self.viscosityFn = fn.branching.map(fn_key=self.material,
                                            mapping=ViscosityMap)

        # Yielding
        backgroundViscosityFn = fn.branching.map(fn_key=self.material,
                                                 mapping=BGViscosityMap)
        SYconditions = [(self.viscosityFn < backgroundViscosityFn,
                         self.strainRate_2ndInvariant), (True, 0.0)]
        self.isYielding = fn.branching.conditional(SYconditions)

        return self.viscosityFn, self.isYielding
コード例 #5
0
ファイル: geodynamics.py プロジェクト: squireg/underworld2
    def set_temperatureBCs(self,
                           left=None,
                           right=None,
                           top=None,
                           bottom=None,
                           indexSets=[]):
        self.temperature = uw.mesh.MeshVariable(mesh=self.mesh, nodeDofCount=1)
        self._temperatureDot = uw.mesh.MeshVariable(mesh=self.mesh,
                                                    nodeDofCount=1)
        self.temperature.data[...] = nd(self.Tref)
        self._temperatureDot.data[...] = 0.

        indices = [self.mesh.specialSets["Empty"]]
        if left is not None:
            self.temperature.data[self.leftWall.data] = nd(left)
            indices[0] += self.leftWall
        if right is not None:
            self.temperature.data[self.rightWall.data] = nd(right)
            indices[0] += self.rightWall
        if top is not None:
            self.temperature.data[self.topWall.data] = nd(top)
            indices[0] += self.topWall
        if bottom is not None:
            self.temperature.data[self.bottomWall.data] = nd(bottom)
            indices[0] += self.bottomWall

        for indexSet, temp in indexSets:
            self.temperature.data[indexSet.data] = nd(temp)
            indices[0] += indexSet

        self._temperatureBCs = uw.conditions.DirichletCondition(
            variable=self.temperature, indexSetsPerDof=indices)
コード例 #6
0
ファイル: geodynamics.py プロジェクト: squireg/underworld2
    def add_material(self,
                     vertices=None,
                     reset=False,
                     name="unknown",
                     shape=None,
                     top=None,
                     bottom=None):

        if reset:
            self.materials = []

        if vertices:
            vertices = [(nd(x), nd(y)) for x, y in vertices]
        mat = Material(
            name=name,
            vertices=vertices,
            diffusivity=self.global_thermal_diffusivity,
            capacity=self.global_thermal_capacity,
            thermalExpansivity=self.global_thermal_expansivity,
            radiogenicHeatProd=self.global_radiogenic_heat_production,
            shape=shape,
            minX=nd(self.minCoord[0]),
            maxX=nd(self.maxCoord[0]),
            top=nd(top),
            bottom=nd(bottom))
        mat.indices = self._get_material_indices(mat)
        self.materials.reverse()
        self.materials.append(mat)
        self.materials.reverse()
        self._fill_model()

        return mat
コード例 #7
0
ファイル: geodynamics.py プロジェクト: squireg/underworld2
    def set_velocityBCs(self,
                        left=None,
                        right=None,
                        top=None,
                        bottom=None,
                        indexSets=[]):

        indices = [self.mesh.specialSets["Empty"]] * self.mesh.dim
        if left is not None:
            for dim in range(self.mesh.dim):
                if left[dim] is not None:
                    self.velocity.data[self.leftWall.data, dim] = nd(left[dim])
                    indices[dim] += self.leftWall
        if right is not None:
            for dim in range(self.mesh.dim):
                if right[dim] is not None:
                    self.velocity.data[self.rightWall.data,
                                       dim] = nd(right[dim])
                    indices[dim] += self.rightWall
        if top is not None:
            for dim in range(self.mesh.dim):
                if top[dim] is not None:
                    self.velocity.data[self.topWall.data, dim] = nd(top[dim])
                    indices[dim] += self.topWall
        if bottom is not None:
            for dim in range(self.mesh.dim):
                if bottom[dim] is not None:
                    self.velocity.data[self.bottomWall.data,
                                       dim] = nd(bottom[dim])
                    indices[dim] += self.bottomWall

        for indexSet, temp in indexSets:
            for dim in range(self.mesh.dim):
                if indexSet[dim] is not None:
                    self.velocity.data[indexSet.data, dim] = nd(indexSet[dim])
                    indices[dim] += indexSet

        self._velocityBCs = uw.conditions.DirichletCondition(
            variable=self.velocity, indexSetsPerDof=indices)
コード例 #8
0
ファイル: geodynamics.py プロジェクト: squireg/underworld2
    def _get_effective_viscosity(self, pressure, strainRate, temperature,
                                 solutionExist):
        if isinstance(self.fn, fn.misc.constant):
            return self.fn

        # Need to generalize that
        R = nd(8.3144621 * u.joule / u.mole / u.degK)
        return self.fn(R=R,
                       strainRateFn=strainRate,
                       pressureFn=pressure,
                       temperatureFn=temperature,
                       solutionExist=solutionExist,
                       **self._nd_coefs)
コード例 #9
0
ファイル: geodynamics.py プロジェクト: squireg/underworld2
    def solve_temperature_steady_state(self):
        DiffusivityMap = {}
        for material in self.materials:
            DiffusivityMap[material.index] = nd(material.diffusivity)

        self.DiffusivityFn = fn.branching.map(fn_key=self.material,
                                              mapping=DiffusivityMap)

        HeatProdMap = {}
        for material in self.materials:
            HeatProdMap[material.index] = nd(material.radiogenicHeatProd) / (
                nd(material.density) * nd(material.capacity))

        self.HeatProdFn = fn.branching.map(fn_key=self.material,
                                           mapping=HeatProdMap)

        heatequation = uw.systems.SteadyStateHeat(
            temperatureField=self.temperature,
            fn_diffusivity=self.DiffusivityFn,
            fn_heating=self.HeatProdFn,
            conditions=self._temperatureBCs)
        heatsolver = uw.systems.Solver(heatequation)
        heatsolver.solve(nonLinearIterate=True)
コード例 #10
0
ファイル: geodynamics.py プロジェクト: squireg/underworld2
    def run_for(self, endTime=None, checkpoint=None):
        self.time = 0.
        units = endTime.units
        endTime = self.time + nd(endTime)
        step = 0

        next_checkpoint = None
        if checkpoint:
            next_checkpoint = self.time + nd(checkpoint)

        while self.time < endTime:
            self.solve()

            if self.time == next_checkpoint:
                self.checkpointID += 1
                self.checkpoint()
                next_checkpoint += nd(checkpoint)

            # Whats the longest we can run before reaching the end of the model
            # or a checkpoint?
            # Need to generalize that
            dt = self.swarm_advector.get_max_dt()

            if self.temperature:
                dt = min(dt, self.advdiffSystem.get_max_dt())

            if checkpoint:
                dt = min(dt, next_checkpoint - self.time)

            self._dt = min(dt, endTime - self.time)
            uw.barrier()

            self.update()

            step += 1
            if checkpoint or step % 1 == 0:
                print "Time: ", str(sca.Dimensionalize(self.time, units))
コード例 #11
0
ファイル: geodynamics.py プロジェクト: squireg/underworld2
    def init_advection_diffusion(self):
        DiffusivityMap = {}
        for material in self.materials:
            DiffusivityMap[material.index] = nd(material.diffusivity)

        self.DiffusivityFn = fn.branching.map(fn_key=self.material,
                                              mapping=DiffusivityMap)

        HeatProdMap = {}
        for material in self.materials:
            HeatProdMap[material.index] = (
                nd(material.radiogenicHeatProd) /
                (nd(material.density) * nd(material.capacity)))

        self.HeatProdFn = fn.branching.map(fn_key=self.material,
                                           mapping=HeatProdMap)

        self.advdiffSystem = uw.systems.AdvectionDiffusion(
            self.temperature,
            self._temperatureDot,
            velocityField=self.velocity,
            fn_diffusivity=self.DiffusivityFn,
            fn_sourceTerm=self.HeatProdFn,
            conditions=[self._temperatureBCs])
コード例 #12
0
velocity = 1. * u.centimeter / u.year

KL = 1e3 * u.meter
Kt = KL / velocity
KT = tempMax
KM = bodyforce * KL**2 * Kt**2
K = 1. * u.mole
lengthScale = 1e3

sca.scaling["[length]"] = KL
sca.scaling["[time]"] = Kt
sca.scaling["[mass]"] = KM
sca.scaling["[temperature]"] = KT
sca.scaling["[substance]"] = K

gravity = nd(9.81 * u.meter / u.second**2)
R = nd(8.3144621 * u.joule / u.mole / u.degK)

elementType = "Q1/dQ0"

resX = 128
resY = 64
materialA = 0
materialB = 1
mesh = uw.mesh.FeMesh_Cartesian(elementType=(elementType),
                                elementRes=(resX, resY),
                                periodic=[False, False])

#if(LoadFromFile == False):
minX = nd(-0.5 * u.kilometer)
maxX = nd(0.5 * u.kilometer)
コード例 #13
0
ファイル: geodynamics.py プロジェクト: squireg/underworld2
    def __init__(self,
                 elementRes,
                 minCoord,
                 maxCoord,
                 gravity,
                 periodic=(False, False),
                 elementType="Q1/dQ0",
                 swarmLayout=None,
                 Tref=273.15 * u.degK,
                 name="undefined",
                 outputDir="outputs"):

        self.name = name
        self.outputDir = outputDir
        self.checkpointID = 0
        self._checkpoint = None
        self.checkpoint = None

        self.minViscosity = 1e19 * u.pascal * u.second
        self.maxViscosity = 1e25 * u.pascal * u.second

        self.gravity = tuple([nd(val) for val in gravity])
        self.Tref = Tref
        self.elementType = elementType
        self.elementRes = elementRes
        self.minCoord = minCoord
        self.maxCoord = maxCoord
        self.periodic = periodic

        self._set_mesh()

        # Add common fields
        self.temperature = None
        self.pressure = uw.mesh.MeshVariable(mesh=self.mesh.subMesh,
                                             nodeDofCount=1)
        self.velocity = uw.mesh.MeshVariable(mesh=self.mesh,
                                             nodeDofCount=self.mesh.dim)

        self.swarm = uw.swarm.Swarm(mesh=self.mesh, particleEscape=True)

        if swarmLayout is not None:
            self._swarmLayout = swarmLayout
        else:
            self._swarmLayout = uw.swarm.layouts.GlobalSpaceFillerLayout(
                swarm=self.swarm, particlesPerCell=25)

        self.swarm.populate_using_layout(layout=self._swarmLayout)
        self.swarm_population_control = uw.swarm.PopulationControl(
            self.swarm,
            aggressive=True,
            splitThreshold=0.15,
            maxDeletions=2,
            maxSplits=10,
            particlesPerCell=20)

        self.swarm_advector = uw.systems.SwarmAdvector(
            swarm=self.swarm, velocityField=self.velocity, order=self.mesh.dim)

        # symmetric component of the gradient of the flow velocity.
        self.strainRate_default = 1.0e-15 / u.second
        self.solutionExist = fn.misc.constant(False)
        self.strainRate = fn.tensor.symmetric(self.velocity.fn_gradient)
        self.strainRate_2ndInvariant = fn.tensor.second_invariant(
            self.strainRate)

        # Force initialisation to zero
        self.pressure.data[...] = 0.
        self.velocity.data[...] = 0.

        # Add Common Swarm Variables
        self.material = self.swarm.add_variable(dataType="int", count=1)
        self.plasticStrain = self.swarm.add_variable(dataType="double",
                                                     count=1)
        self.plasticStrain.data[...] = 0.0

        self.materials = []
        self._defaultMaterial = 0

        self.leftWall = self.mesh.specialSets["MinI_VertexSet"]
        self.topWall = self.mesh.specialSets["MaxJ_VertexSet"]
        self.bottomWall = self.mesh.specialSets["MinJ_VertexSet"]
        self.rightWall = self.mesh.specialSets["MaxI_VertexSet"]

        if self.mesh.dim > 2:
            self.frontWall = self.mesh.specialSets["MinK_VertexSet"]
            self.backWall = self.mesh.specialSets["MaxK_VertexSet"]

        self.time = 0.0

        # global variables
        self.global_thermal_diffusivity = None
        self.global_thermal_capacity = None
        self.global_thermal_expansivity = None
        self.global_radiogenic_heat_production = None

        self._lecodeRefMaterial = None
コード例 #14
0
ファイル: geodynamics.py プロジェクト: squireg/underworld2
 def _viscosity_limiter(self, viscosityFn):
     maxViscosity = fn.misc.constant(nd(self.maxViscosity))
     minViscosity = fn.misc.constant(nd(self.minViscosity))
     maxBound = fn.misc.min(viscosityFn, maxViscosity)
     minMaxBound = fn.misc.max(maxBound, minViscosity)
     return minMaxBound
コード例 #15
0
ファイル: geodynamics.py プロジェクト: squireg/underworld2
 def _get_friction(self, plasticStrain):
     self.friction = self.frictionFn(
         plasticStrain,
         FrictionCoef=nd(self.coefs["FrictionCoef"]),
         FrictionCoefSw=nd(self.coefs["FrictionCoefSw"]))
コード例 #16
0
ファイル: geodynamics.py プロジェクト: squireg/underworld2
 def _get_cohesion(self, plasticStrain):
     self.cohesion = self.cohesionFn(plasticStrain,
                                     Cohesion=nd(self.coefs["Cohesion"]),
                                     CohesionSw=nd(
                                         self.coefs["CohesionSw"]))
コード例 #17
0
def update():
    # get timestep and advect particles
    dt = advector.get_max_dt()

    if (Elasticity == True):
        if dt > (dt_e / 3.):
            dt = dt_e / 3.
            print dt_e / time_factor
            print dt / time_factor
    print dt / time_factor
    advector.integrate(dt)
    adv_deform1.integrate(dt)
    adv_deform2.integrate(dt)
    '''
    with mesh.deform_mesh( isRegular=True ):
        mesh.data[:,0] += mesh_vels[:]*dt

    newtime = time + dt
    # recalc mesh exten
    newminX = minX - meshV * newtime
    newmaxX = maxX + meshV * newtime
    '''

    # particle population control
    pop_control.repopulate()

    # smoothed stress history for use in (t + 1) timestep
    if (Elasticity == True):
        phi = dt / dt_e
        stressDropUnit = [
            nd(1e6 * u.pascal),
            nd(1e6 * u.pascal),
            nd(1e6 * u.pascal)
        ]
        stressMapFn_data = stressMapFn.evaluate(swarm)
        ## reduce stress by 1 MPa once it reaches yielding point
        #swarmYield = viscosityMapFn.evaluate(swarm) > viscosityFn.evaluate(swarm)
        #stressMapFn_data2 = np.where(swarmYield,stressMapFn_data-stressDropUnit, stressMapFn_data )
        #previousStress.data[:] = ( phi*stressMapFn_data2[:] + ( 1.-phi )*previousStress.data[:] )
        previousStress.data[:] = (phi * stressMapFn_data[:] +
                                  (1. - phi) * previousStress.data[:])

    # update plastic strain
    swarmYield = viscosityMapFn.evaluate(swarm) > viscosityFn.evaluate(swarm)

    swarmStrainRateInv = strainRate_2ndInvariantFn.evaluate(swarm)

    plasticStrainIncrement = dt * np.where(swarmYield, swarmStrainRateInv, 0.0)
    plasticStrain.data[:] += plasticStrainIncrement
    plasticStrain0.data[:] = plasticStrainIncrement
    '''
    for index, coord in enumerate(swarm.particleCoordinates.data):
        x = coord[0]
      
        if (x < minX+0.05 or x > maxX-0.05):
            plasticStrain.data[index] = 0.
    '''
    #newmeshV = (math.sin(newtime/nd(10000*u.year)*3.1415926))*nd(1e-14/u.second)*newmaxX
    #newmeshV = nd(0*1e-14/u.second)*newmaxX
    #if step < 250:
    #   newmeshV = nd(5e-14/u.second)*newmaxX

    return time + dt, step + 1