Ejemplo n.º 1
0
def test_failsafe_sweep():
    interpolate_expression = Expression('x[0]', degree=1)
    mesh = UnitSquareMesh(5, 5)
    V = FunctionSpace(mesh, "DG", 1)

    v = Function(V)
    v.assign(interpolate_expression)

    np_min, np_max = 1, 2
    np_failsafe = 4

    # Initialize particles
    x = RandomRectangle(Point(0.0, 0.0), Point(1., 1.)).generate([100, 100])
    s = assign_particle_values(x, interpolate_expression)
    # Broadcast to other procs
    x = comm.bcast(x, root=0)
    s = comm.bcast(s, root=0)

    property_idx = 1
    p = particles(x, [s], mesh)
    AD = AddDelete(p, np_min, np_max, [v])
    AD.do_sweep_failsafe(np_failsafe)

    # Must recover linear
    lstsq_rho = l2projection(p, V, property_idx)
    lstsq_rho.project(v.cpp_object())

    error = sqrt(
        assemble(
            (v - interpolate_expression) * (v - interpolate_expression) * dx))

    assert len(p.positions() == mesh.num_cells() * np_failsafe)
    assert error < 1e-12
Ejemplo n.º 2
0
def test_l2projection_bounded_3D(polynomial_order, lb, ub):
    xmin, ymin, zmin = 0., 0., 0.
    xmax, ymax, zmax = 1., 1., 1.
    nx = 10

    interpolate_expression = Ball(0.15, [0.5, 0.5, 0.5],
                                  degree=3,
                                  lb=lb,
                                  ub=ub)

    property_idx = 1
    mesh = BoxMesh(Point(xmin, ymin, zmin), Point(xmax, ymax, zmax), nx, nx,
                   nx)

    V = FunctionSpace(mesh, "DG", polynomial_order)

    x = RegularBox(Point(0., 0., 0.), Point(1., 1.,
                                            1.)).generate([100, 100, 100])
    s = assign_particle_values(x, interpolate_expression)

    # Just make a complicated particle, possibly with scalars and vectors mixed
    p = particles(x, [s], mesh)

    vh = Function(V)
    lstsq_rho = l2projection(p, V, property_idx)
    lstsq_rho.project(vh.cpp_object(), lb, ub)

    # Assert if it stays within bounds
    assert np.any(vh.vector().get_local() < ub + 1e-12)
    assert np.any(vh.vector().get_local() > lb - 1e-12)
def test_l2projection_bounded(polynomial_order, lb, ub):
    # Test l2 projection if it stays within bounds given by lb and ub
    interpolate_expression = SlottedDisk(radius=0.15,
                                         center=[0.5, 0.5],
                                         width=0.05,
                                         depth=0.,
                                         degree=3,
                                         lb=lb,
                                         ub=ub)

    xmin, xmax = 0., 1.
    ymin, ymax = 0., 1.

    property_idx = 5

    mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 40, 40)

    V = FunctionSpace(mesh, "DG", polynomial_order)

    x = RandomRectangle(Point(xmin, ymin), Point(xmax,
                                                 ymax)).generate([500, 500])
    s = assign_particle_values(x, interpolate_expression)

    # Just make a complicated particle, possibly with scalars and vectors mixed
    p = particles(x, [x, s, x, x, s], mesh)

    vh = Function(V)
    lstsq_rho = l2projection(p, V, property_idx)
    lstsq_rho.project(vh, lb, ub)

    # Assert if it stays within bounds
    assert np.all(vh.vector().get_local() < ub + 1e-12)
    assert np.all(vh.vector().get_local() > lb - 1e-12)
def test_l2projection(polynomial_order, in_expression):
    # Test l2 projection for scalar and vector valued expression
    interpolate_expression = Expression(in_expression, degree=3)

    xmin, xmax = 0., 1.
    ymin, ymax = 0., 1.

    property_idx = 5

    mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), 40, 40)

    if len(interpolate_expression.ufl_shape) == 0:
        V = FunctionSpace(mesh, "DG", polynomial_order)
    elif len(interpolate_expression.ufl_shape) == 1:
        V = VectorFunctionSpace(mesh, "DG", polynomial_order)

    v_exact = Function(V)
    v_exact.interpolate(interpolate_expression)

    x = RandomRectangle(Point(xmin, ymin), Point(xmax,
                                                 ymax)).generate([500, 500])
    s = assign_particle_values(x, interpolate_expression)

    # Just make a complicated particle, possibly with scalars and vectors mixed
    p = particles(x, [x, s, x, x, s], mesh)

    vh = Function(V)
    lstsq_rho = l2projection(p, V, property_idx)
    lstsq_rho.project(vh)

    error_sq = abs(assemble(dot(v_exact - vh, v_exact - vh) * dx))
    assert error_sq < 1e-15
Ejemplo n.º 5
0
def test_l2_projection_3D(polynomial_order, in_expression):
    xmin, ymin, zmin = 0.0, 0.0, 0.0
    xmax, ymax, zmax = 1.0, 1.0, 1.0
    nx = 25

    property_idx = 1
    mesh = BoxMesh(Point(xmin, ymin, zmin), Point(xmax, ymax, zmax), nx, nx,
                   nx)

    interpolate_expression = Expression(in_expression, degree=3)

    if len(interpolate_expression.ufl_shape) == 0:
        V = FunctionSpace(mesh, "DG", polynomial_order)
    elif len(interpolate_expression.ufl_shape) == 1:
        V = VectorFunctionSpace(mesh, "DG", polynomial_order)

    v_exact = Function(V)
    v_exact.assign(interpolate_expression)

    x = RandomBox(Point(0.0, 0.0, 0.0), Point(1.0, 1.0,
                                              1.0)).generate([4, 4, 4])
    s = assign_particle_values(x, interpolate_expression)

    # Just make a complicated particle, possibly with scalars and vectors mixed
    p = particles(x, [s], mesh)

    # Do AddDelete sweep
    AD = AddDelete(p, 13, 15, [v_exact])
    AD.do_sweep()

    vh = Function(V)
    lstsq_vh = l2projection(p, V, property_idx)
    lstsq_vh.project(vh.cpp_object())

    error_sq = abs(assemble(dot(v_exact - vh, v_exact - vh) * dx))
    if comm.Get_rank() == 0:
        assert error_sq < 1e-13
Ejemplo n.º 6
0
   def update(self,u,dt,p,remesh=True,remesh_elastic=False):
       """
       Update positions and properties of traces using 1st order Euler forward
       The RK 4 scheme is fourth order in space, but first order in time
       because we interpolate the velocities instead of solving for new
       velocities at each step
       """

       # Step 1, establish our function spaces for projections
       Q = self.mesh.Q      # Linear elements
       Q0 = FunctionSpace(self.mesh.mesh, "DG", 0) # Discontinuous elements

       epsII=self.epsII
       eta = self.eta
       eta_visc = self.eta_visc
       eta_plas = self.eta_plas

       Vdg = FunctionSpace(self.mesh.mesh, 'DG',1)


       # Variables to store strain and temp
       strain, temp = Function(Vdg), Function(Vdg)
       #lstsq_strain = l2projection(p, Vdg, 1) # First variable???
       #lstsq_strain.project_mpm(strain) # Projection is stored in phih0

       lstsq_temp = l2projection(p, Vdg, 2) # First variable???
       lstsq_temp.project(temp,253.15,273.15) # Projection is stored in phih0

       dt_min = 0.5*project(CellDiameter(self.mesh.mesh)/sqrt(dot(u, u)),Q0).compute_vertex_values()
       dt_m = np.minimum(dt,np.min(dt_min))


       #epsII = project(epsII,Vdg)
       p.interpolate(epsII,3)
       self.epsII = epsII

       (xp , pstrain , ptemp, pepsII) = (p. return_property(mesh , 0) ,
           p. return_property(mesh , 1) ,
           p. return_property(mesh , 2),
           p. return_property(mesh , 3))
       pepsII = np.maximum(pepsII,0.0)


       self.pepsII = pepsII
       self.ptemp = ptemp
       self.pstrain = pstrain
       #"""
       if self.method==1:

           deps_dt = Function(Vdg)
           deps_dt.vector()[:] = self.visc_func.strain_update(epsII.vector().get_local(),temp.vector().get_local(),strain.vector().get_local(),dt_m)
           deps_dt_eff = Function(Vdg)
           #if self.deps_dt == None:
           p.interpolate(deps_dt,1)
           pstrain_new = np.maximum(p. return_property(mesh , 1) + pstrain,0.0)
            #self.deps_dt = deps_dt

       # else:
       #     if self.deps_dt_old == None:
       #         deps_dt_old = interpolate(self.deps_dt,Vdg)
       #         deps_dt_eff.vector()[:]=1.5*deps_dt.vector().get_local()-0.5*deps_dt_old.vector().get_local()
       #         p.interpolate(deps_dt_eff,1)
       #         self.deps_dt = deps_dt
       #
       #         self.deps_dt_old = deps_dt_old
       #     else:
       #         if self.deps_dt_older==None:
       #             deps_dt_older = interpolate(self.deps_dt_old,Vdg)
       #             deps_dt_old = interpolate(self.deps_dt,Vdg)
       #             deps_dt_eff.vector()[:]=23./12*deps_dt.vector().get_local()-16./12*deps_dt_old.vector().get_local()+5./12*deps_dt_older.vector().get_local()
       #             p.interpolate(deps_dt_eff,1)
       #             self.deps_dt = deps_dt
       #             self.deps_dt_old = deps_dt_old
       #             self.deps_dt_older = deps_dt_older
       #         else:
       #             deps_dt_old = interpolate(self.deps_dt,Vdg)
       #             deps_dt_older = interpolate(self.deps_dt_old,Vdg)
       #             deps_dt_oldist = interpolate(self.deps_dt_older,Vdg)
       #             deps_dt_eff.vector()[:]=(55./24*deps_dt.vector().get_local()-59./24*deps_dt_old.vector().get_local()+37./24*deps_dt_older.vector().get_local() -9./24*deps_dt_oldist.vector().get_local())
       #             p.interpolate(deps_dt_eff,1)
       #             self.deps_dt = deps_dt
       #             self.deps_dt_old = deps_dt_old
       #             self.deps_dt_older = deps_dt_older

       else:
           pstrain_new = self.visc_func.update(pepsII,ptemp,pstrain,dt_m)
           pstrain_new = np.maximum(pstrain_new,0.0)

       #pstrain_new[xp[:,0]<1e3]=0.0
       p.change_property(pstrain_new,1)


       strain = Function(Vdg)
       lstsq_strain = l2projection(p, Vdg, 1) # First variable???
       lstsq_strain.project_mpm(strain) # Projection is stored in phih0
       #self.strain = strain


       print('Starting to remesh')
       if remesh == True:
           if remesh_elastic==False:
               #Temp = self.temp_model.advect_diffuse(T0,u,dt,self.scalar,self.boundary_parts,self.mesh.mesh)
               #self.Temp = Temp
               if self.calving_front == False:

                  # Update model mesh with new mesh
                  new_mesh=self.remesh(u,dt_m)
                  u_eff = u
                  print('Finished remeshing')
               else:
                  # Update mesh coordinates to new coordinates
                  u_elastic=self.remesh_elastic(u,dt_m)
                  #u_eff = u-u_elastic
                  #u_eff = project(u-u_elastic,self.vector2)
                  #Temp = self.temp_model.advect_diffuse(T0,u-u_elastic,dt,self.scalar,self.boundary_parts,self.mesh.mesh)
                  #self.Temp = Temp
                  ux,uz=u_elastic.split()


                  # Update mesh coordinates
                  coords = self.mesh.mesh.coordinates()
                  coords[:,0]=coords[:,0]+ux.compute_vertex_values()*dt_m
                  coords[:,1]=coords[:,1]+uz.compute_vertex_values()*dt_m

                  # And update bounding box tree
                  self.mesh.mesh.bounding_box_tree().build(self.mesh.mesh)
                  self.markBoundaries()
                  # Now remesh
                  new_mesh=self.mesh.remesh(max_length=self.mesh.length)
                  print('Finished remeshing')

               Qnew=FunctionSpace(new_mesh.mesh, "CG", 1)
               Tnew = Function(Qnew)
               self.set_mesh(new_mesh)
               length = self.mesh.length
           else:
               #xm,zm = self.tracers.get_coords()
               x,z = self.mesh.get_coords()
               xmax = np.max(x)
               u_elastic=self.remesh_elastic(u,dt_m)
               u_eff = u-u_elastic
               u_eff = project(u-u_elastic,self.vector2)
               ux,uz=u_elastic.split()


               # Update mesh coordinates
               coords = self.mesh.mesh.coordinates()
               coords[:,0]=coords[:,0]+ux.compute_vertex_values()*dt_m
               coords[:,1]=coords[:,1]+uz.compute_vertex_values()*dt_m

               # And update bounding box tree
               self.mesh.mesh.bounding_box_tree().build(self.mesh.mesh)
               self.markBoundaries()

               length = xmax*2.0
           #self.tracers.set_mesh(self.mesh)
       else:
           length = self.mesh.length


       self.tempModel.set_mesh(self.mesh.mesh)
       self.markBoundaries()
       #Temp = self.tempModel.update(u_eff,dt_m,self.boundary_parts)
       if self.u_k!=None:
           self.u_k = interpolate(self.u_k,self.vector2)




       self.strain = strain
       self.temp = temp
       self.epsII = epsII



       self.u_k = interpolate(self.u_k,self.vector2)
       #ap = advect_rk3(p, self.vector2, u, "open")
       #ap.do_step(dt_m)
       return dt_m
Ejemplo n.º 7
0
   def solve(self,p,dt=3600,tolerance=1e-6,relax_param=1.0):
       """
       Picard iteration to solve system of equations

       p is particles
       """

       # Normal vector
       z_vector = interpolate(Constant((0.0, 1.0)), self.vector2) # Vertical vector pointing upwards

       # Normal and tangent unit vectors
       N = FacetNormal(self.mesh.mesh)
       normE = as_vector([N[0], N[1]])
       tanE = as_vector([-N[1], N[0]])

       # Mark boundaries and subdomains
       self.markBoundaries()

       #Define functio space for viscosity coefficients???
       Q = self.mesh.Q

       # Extract strain and temperature as mesh functions
       # Function spaces -- should be defined once??
       Vdg = FunctionSpace(self.mesh.mesh, 'DG',1)
       Vcg = FunctionSpace(self.mesh.mesh, 'DG',1)

       # Variables to store strain and temp
       strain, temp = Function(Vdg), Function(Vcg)

       lstsq_temp = l2projection(p, Vcg, 2)
       lstsq_temp.project(temp)

       lstsq_strain = l2projection(p, Vdg, 1) # First variable???
       lstsq_strain.project_mpm(strain) # Projection is stored in phih0





       temp = self.tempModel.Temp
       u_old = Function(self.vector2)
       if self.u_k != None:
           u_k = self.u_k
           u_old.assign(u_k)
       else:
           u_k = interpolate(Constant((1E-15, 1E-15)), self.vector2)

       (q,v) = TestFunctions(self.system)
       (p, u) = TrialFunctions(self.system)

       err_rel = 1.0               # error measure ||u-u_k|| and ||p-p_k||
       count = 0                   # iteration counter
       maxit = self.maxit          # number of iterations allowed

       visc=self.visc_func



       #Q=FunctionSpace(self.mesh.mesh, "CG", 2)
       temp=interpolate(temp,Q)
       epsII=self.effective_strain_rate_squared(u_k,Q)
       eta = visc(epsII ,temp,strain,Q)
       eta_visc = self.visc_func.ductile_visc(epsII ,temp,Q)


       # Time step needs to be a Constant to avoid recompiling every time step

       water_drag = Constant(self.water_drag*self.rho_w/material.time_factor**2)*sqrt(dot(u_k,u_k))

       # Set friction coefficient
       m = self.m
       u_b = dot(tanE,u_k)
       u_b_norm = sqrt(u_b**2)
       Neff = Constant(1.0) # Don't use effective pressure in sliding law . . . for now
       tau_y = self.visc_func.cohes(strain,Q)
       friction = Neff*Constant(self.friction/material.time_factor**m)*(sqrt(u_b_norm**2 + 1e-16**2))**(m-1)
       friction = (1./friction + u_b_norm/tau_y)**(-1.0)

       lateral_drag = Constant(self.lateral_drag/material.time_factor**m)*(sqrt(u_k**2 + 1e-16**2))**(m-1)
       lateral_drag = (1./lateral_drag + sqrt(dot(u_k,u_k))/self.visc_func.yield_strength)**(-1.0)


       bcs = self.BCS
       dt_step = Constant(dt)
       elastic = Constant(self.elastic_coeff_rock)
       stokes = inner(Constant(self.rho_i/material.time_factor)*(u-u_old)/dt_step,v)*dx \
             + inner(2*eta*epsilon(u), epsilon(v))*dx \
             - inner(nabla_div(v), p)*dx \
             + inner(nabla_div(u), q)*dx \
             + inner(self.below_sea_level*self.rho_w*self.g*dot((dt_step*u)*np.abs(N[1]), z_vector)*z_vector, v)*self.DS(5) \
             + inner(elastic*dot((dt_step*u), normE), dot(v,normE))*self.DS(1) \
             + inner(self.water_pressure*normE, v)*self.DS(5) \
             + inner((self.GROUND_PRESSURE_SCALAR+self.water_pressure)*normE, v)*self.DS(1) \
             + inner(dot(v, tanE), friction*dot(u, tanE))*self.DS(1) \
             + inner(self.below_sea_level*water_drag*u, v)*self.DS(5) \
             + inner(self.water_pressure*normE, v)*self.DS(6) \
             + inner(self.below_sea_level*self.rho_w*self.g*dot((dt_step*u)*np.abs(N[1]), z_vector)*z_vector, v)*self.DS(6) \
             + inner(self.below_sea_level*water_drag*u, v)*self.DS(6) \
             + inner(v,lateral_drag*u)*dx \
             + inner(self.buttressing, v[0])*self.DS(6) \
             - inner(self.f, v)*dx \


       # Solves problem . . . .
       w = Function(self.system)
       problem = LinearVariationalProblem(lhs(stokes), rhs(stokes), w, bcs)
       solver = LinearVariationalSolver(problem)
       prm = solver.parameters
       info(prm, False)
       prm['linear_solver']            = 'mumps'
       #prm['linear_solver']            = 'lu'

       while ((float(err_rel) > tolerance) and (count < maxit)):
           solver.solve()
           self.u_p = w
           p, u = w.split(deepcopy=True)

           du = u.vector().get_local()-u_k.vector().get_local()

           err = np.linalg.norm(du)
           err_rel = err/norm(u)
           print("count = %d, relative error = %G, absolute error = %G" % (count, err_rel,err))
           alpha = self.alpha
           u.vector()[:]=alpha*u.vector()[:]+(1-alpha)*u_k.vector()[:]
           # Assign new variables to old guess
           assign(u_k, u)
           count += 1
           # Kick out if the absolute error in the velocity is less than 0.1 m/a
           if err<1e-3/material.secpera:
               break

       ux,uz = u.split()
       speed = np.sqrt(ux.compute_vertex_values()**2+uz.compute_vertex_values()**2)
       print('Max viscous speed',np.max(speed))
       epsII=self.effective_strain_rate_squared(u,Q)

       self.eta=self.visc_func(epsII ,temp,strain,Q)
       self.eta_visc=self.visc_func.ductile_visc(epsII ,temp,Q)
       self.eta_plas=self.visc_func.plastic_visc(epsII ,strain,Q)
       #self.epsII = epsII

       Q = Vdg
       epsII = Function(Q) # Plastic viscosity
       eps1 = Function(Q) # Plastic viscosity
       eps2 = Function(Q) # Plastic viscosity
       eps = epsilon(u)
       local_project(eps[0,0],Q,eps1)
       local_project(eps[0,1],Q,eps2)
       epsII.vector()[:] = np.sqrt(eps1.vector().get_local()**2+eps2.vector().get_local()**2)
       #local_project(sqrt(eps1**2 + eps2**2),Q,epsII)
       self.epsII = epsII


       if count>=maxit:
           print("WARNING: MAXIMUM NUMBER OF ITERATIONS EXCEEDED")
       self.u_k = u_k
       self.u=u
       self.u_p = w
       self.u = u
       self.p = p
       self.eta = eta

       return u,p
Ejemplo n.º 8
0
def read_files(fname_base):
    L = []
    t = []
    for step in range(0, 1000000, 10):

        fname_ext = str(step).zfill(3) + '.npz'
        fname = fname_base + fname_ext
        print(fname)

        # Load particle data
        if path.exists(fname):
            tracer_data = np.load(fname)
        else:
            print('Cannot read file')
            break

        t.append(tracer_data['t'].item())

        # Load mesh
        mesh_file = fname_base + str(step).zfill(3) + '.xml'
        mesh = Mesh(mesh_file)

        # Make particle class
        n = len(tracer_data['xm'])
        xp = np.vstack(
            (tracer_data['xm'], tracer_data['zm'])).transpose().reshape(n, 2)
        pstrain = tracer_data['strain']
        pepsII = tracer_data['epsII']
        ptemp = tracer_data['temp']
        p = particles(xp, [pstrain, ptemp, pepsII], mesh)

        # Interpolate particles to mesh
        Vdg = FunctionSpace(mesh, 'DG', 1)
        strain = Function(Vdg)
        lstsq_strain = l2projection(p, Vdg, 1)  # First variable???
        lstsq_strain.project_mpm(strain)  # Projection is stored in phih0

        # Boundary mesh with portion above sea level marked
        bmesh = BoundaryMesh(mesh, 'exterior', order=True)
        x = bmesh.coordinates()
        #ymax = np.max(x[x[:,0]==0,1])
        filter = (x[:, 0] > 1e-4) & (x[:, 1] > 0)
        xm = np.min(x[filter, 0])
        id = np.argwhere(x[:, 0] == xm).item()
        # Check if nodes increasing or decreasing
        if (x[id - 1, 0] > x[id, 0]):
            # Decrease nodes
            inc = -1
            stop = 0
        else:
            # Increase nodes
            inc = 1
            stop = len(x)

        iold = id
        for i in range(id, stop, inc):
            if x[i, 1] > 0.0:
                slope = (x[i, 1] - x[iold, 1]) / (x[i, 0] - x[iold, 0])
                #print(x[i,0],strain(x[i]),strain(x[i])>0.99,slope,slope<-pi/3)
                #print(-slope*180/pi)
                if strain(x[i]) > 0.99:
                    L.append(x[iold, 0])
                    break
                elif np.abs(slope) > pi / 6:
                    L.append(x[iold, 0])
                    break

                iold = i
        print('Terminus position', L[-1])
        if i == stop - inc:
            print('No terminus identified')
            L.append(np.Nan)

    fname = fname_base + 'term_pos.npz'
    print(fname)
    # Least squares fit to data
    #if len(t)>len(L):
    #    print('Not equal')
    #    t =t[0:-1]

    print(len(t), len(L))
    t = np.array(t)
    L = np.array(L)
    filter = (t > 2 / 12)  #
    t, L = np.array(t), np.array(L)
    dLdt, b, rvalue, pvalue1, err = linregress(t[filter], L[filter])
    print('Rate of terminus advance', dLdt, 'Errror', err)
    np.savez(fname,
             t=t,
             L=L,
             dLdt=dLdt,
             err=err,
             pvalue=pvalue1,
             rvalue=rvalue)
    return None
Ejemplo n.º 9
0
            mesh,
            p,
            forms_pde["N_a"],
            forms_pde["G_a"],
            forms_pde["L_a"],
            forms_pde["H_a"],
            forms_pde["B_a"],
            forms_pde["Q_a"],
            forms_pde["R_a"],
            forms_pde["S_a"],
            [bc],
            property_idx,
        )

        # Initialize the l2 projection
        lstsq_psi = l2projection(p, W, property_idx)

        # Set initial condition at mesh and particles
        psi0_h.interpolate(psi0_expression)
        p.interpolate(psi0_h.cpp_object(), property_idx)

        # Initialize add/delete particle
        AD = AddDelete(p, 15, 25, [psi0_h])

        step = 0
        t = 0.0
        area_0 = assemble(psi0_h * dx)
        timer = Timer()

        timer.start()
        while step < num_steps:
# Define projections problem
FuncSpace_adv = {'FuncSpace_local': Q_Rho, 'FuncSpace_lambda': T_1, 'FuncSpace_bar': Qbar}
FormsPDE = FormsPDEMap(mesh, FuncSpace_adv, beta_map=Constant(1e-8))
forms_pde = FormsPDE.forms_theta_linear(phih0, uadvect, dt, Constant(1.0), zeta=Constant(0.),
                                        h=Constant(0.))
pde_projection = PDEStaticCondensation(mesh, p,
                                       forms_pde['N_a'], forms_pde['G_a'], forms_pde['L_a'],
                                       forms_pde['H_a'],
                                       forms_pde['B_a'],
                                       forms_pde['Q_a'], forms_pde['R_a'], forms_pde['S_a'],
                                       [], 1)

ap = advect_rk3(p, V, uh, 'open')

# Initialize the initial condition at mesh by an l2 projection
lstsq_rho = l2projection(p, Q_Rho, 1)
lstsq_rho.project(phih0)
outfile << phih0

for step in range(num_steps):
    u_expr.t = step * float(dt)
    u_expre_neg.t = step * float(dt)

    uh.assign(u_expr)

    # Compute area at old configuration
    old_area = assemble(phih0*dx)

    # Pre-assemble rhs
    pde_projection.assemble_state_rhs()
initial_density = BinaryBlock(geometry, float(rho1), float(rho2), degree=1)
zero_expression = Expression(("0.", "0."), degree=1)

# Initialize particles
x = RandomRectangle(Point(xmin, ymin), Point(xmax, ymax)).generate(
    [pres, int(pres * (ymax - ymin) / (xmax - xmin))])
up = assign_particle_values(x, zero_expression)
rhop = assign_particle_values(x, initial_density)

# Increment requires dup to be stored, init zero
dup = up

p = particles(x, [rhop, up, dup], mesh)

# Init rho0 field
lstsq_rho = l2projection(p, Q_Rho, 1)
lstsq_rho.project(rho0, float(rho2), float(rho1))

# Initialize l2 projection for specific momentum
lstsq_u = l2projection(p, W_2, 2)

# Initialize advection class
ap = advect_rk3(p, W_2, Udiv, 'closed')

# Set-up boundary conditions (free slip)
boundaries = MeshFunction("size_t", mesh, mesh.topology().dim() - 1)
boundaries.set_all(0)
all_bounds = Boundaries()
all_bounds.mark(boundaries, 98)
ds = Measure('ds', domain=mesh, subdomain_data=boundaries)
W = FunctionSpace(mesh, 'DG', k)
psi_h = Function(W)

V = VectorFunctionSpace(mesh, 'DG', 3)
uh = Function(V)
uh.assign(Expression(('-Uh*x[1]', 'Uh*x[0]'), Uh=Uh, degree=3))

# Generate particles
x = RandomCircle(Point(x0, y0), r).generate([pres, pres])
s = assign_particle_values(x, psi0_expr)

p = particles(x, [s], mesh)
# Initialize advection class, use RK3 scheme
ap = advect_rk3(p, V, uh, 'closed')
# Init projection
lstsq_psi = l2projection(p, W, 1)

# Do projection to get initial field
lstsq_psi.project(psi_h.cpp_object(), lb, ub)
AD = AddDelete(p, 10, 20, [psi_h], [1], [lb, ub])

step = 0
t = 0.
area_0 = assemble(psi_h * dx)
timer = Timer()
timer.start()

outfile.write(psi_h, t)
while step < num_steps:
    step += 1
    t += float(dt)
Ejemplo n.º 13
0
def read_calving_front_sim(fname_base):
    fname_ext = '.npz'
    fname = fname_base + fname_ext
    print(fname)

    # Load particle data
    if path.exists(fname):
        tracer_data = np.load(fname)
    else:
        print('Cannot read file')

    t = tracer_data['t'].item()

    # Load mesh
    mesh_file = fname_base + '.xml'
    mesh = Mesh(mesh_file)

    # Make particle class
    n = len(tracer_data['xm'])
    xp = np.vstack(
        (tracer_data['xm'], tracer_data['zm'])).transpose().reshape(n, 2)
    pstrain = tracer_data['strain']
    pepsII = tracer_data['epsII']
    ptemp = tracer_data['temp']
    p = particles(xp, [pstrain, ptemp, pepsII], mesh)

    # Interpolate particles to mesh
    Vdg = FunctionSpace(mesh, 'DG', 1)
    strain = Function(Vdg)
    lstsq_strain = l2projection(p, Vdg, 1)  # First variable???
    lstsq_strain.project_mpm(strain)  # Projection is stored in phih0

    # Boundary mesh with portion above sea level marked
    bmesh = BoundaryMesh(mesh, 'exterior', order=True)
    x = bmesh.coordinates()
    #ymax = np.max(x[x[:,0]==0,1])
    filter = (x[:, 0] > 1e-4) & (x[:, 1] > 0)
    xm = np.min(x[filter, 0])
    id = np.argwhere(x[:, 0] == xm).item()
    # Check if nodes increasing or decreasing
    if (x[id - 1, 0] > x[id, 0]):
        # Decrease nodes
        inc = -1
        stop = 0
    else:
        # Increase nodes
        inc = 1
        stop = len(x)

    iold = id
    for i in range(id, stop, inc):
        if x[i, 1] > 0.0:
            slope = (x[i, 1] - x[iold, 1]) / (x[i, 0] - x[iold, 0])
            #print(x[i,0],strain(x[i]),strain(x[i])>0.99,slope,slope<-pi/3)
            #print(-slope*180/pi)
            if strain(x[i]) > 0.1:
                L = x[iold, 0]
                break
            elif np.abs(slope) > pi / 6:
                L = x[iold, 0]
                break

            iold = i
    print('Terminus position', L)
    # Extract profile centered on terminus
    filter = (x[:, 1] > 0.0) & (x[:, 0] > 10) & (x[:, 0] < L + 5 * 800)
    xp = x[filter, 0] - L
    zp = x[filter, 1]
    idx = np.argsort(xp)
    xp = xp[idx]
    zp = zp[idx]
    zp = gaussian_filter(zp, 1.5)

    #fname = fname_base + 'term_pos.npz'
    #print(fname)

    return xp, zp
Ejemplo n.º 14
0
def test_moving_mesh():
    t = 0.
    dt = 0.025
    num_steps = 20
    xmin, ymin = 0., 0.
    xmax, ymax = 2., 2.
    xc, yc = 1., 1.
    nx, ny = 20, 20
    pres = 150
    k = 1

    mesh = RectangleMesh(Point(xmin, ymin), Point(xmax, ymax), nx, ny)
    n = FacetNormal(mesh)

    # Class for mesh motion
    dU = PeriodicVelocity(xmin, xmax, dt, t, degree=1)

    Qcg = VectorFunctionSpace(mesh, 'CG', 1)

    boundaries = MeshFunction("size_t", mesh, mesh.topology().dim()-1)
    boundaries.set_all(0)
    leftbound = Left(xmin)

    leftbound.mark(boundaries, 99)
    ds = Measure('ds', domain=mesh, subdomain_data=boundaries)

    # Create function spaces
    Q_E_Rho = FiniteElement("DG", mesh.ufl_cell(), k)
    T_1 = FunctionSpace(mesh, 'DG', 0)
    Qbar_E = FiniteElement("DGT", mesh.ufl_cell(), k)

    Q_Rho = FunctionSpace(mesh, Q_E_Rho)
    Qbar = FunctionSpace(mesh, Qbar_E)

    phih, phih0 = Function(Q_Rho), Function(Q_Rho)
    phibar = Function(Qbar)

    # Advective velocity
    uh = Function(Qcg)
    uh.assign(Constant((0., 0.)))
    # Mesh velocity
    umesh = Function(Qcg)
    # Total velocity
    uadvect = uh-umesh

    # Now throw in the particles
    x = RandomRectangle(Point(xmin, ymin), Point(xmax, ymax)).generate([pres, pres])
    s = assign_particle_values(x, GaussianPulse(center=(xc, yc), sigma=float(0.25),
                                                U=[0, 0], time=0., height=1., degree=3))
    x = comm.bcast(x, root=0)
    s = comm.bcast(s, root=0)
    p = particles(x, [s], mesh)

    # Define projections problem
    FuncSpace_adv = {'FuncSpace_local': Q_Rho, 'FuncSpace_lambda': T_1, 'FuncSpace_bar': Qbar}
    FormsPDE = FormsPDEMap(mesh, FuncSpace_adv, ds=ds)
    forms_pde = FormsPDE.forms_theta_linear(phih0, uadvect, dt, Constant(1.0), zeta=Constant(0.))
    pde_projection = PDEStaticCondensation(mesh, p,
                                           forms_pde['N_a'], forms_pde['G_a'], forms_pde['L_a'],
                                           forms_pde['H_a'],
                                           forms_pde['B_a'],
                                           forms_pde['Q_a'], forms_pde['R_a'], forms_pde['S_a'],
                                           [], 1)

    # Initialize the initial condition at mesh by an l2 projection
    lstsq_rho = l2projection(p, Q_Rho, 1)
    lstsq_rho.project(phih0.cpp_object())

    for step in range(num_steps):
        # Compute old area at old configuration
        old_area = assemble(phih0*dx)

        # Pre-assemble rhs
        pde_projection.assemble_state_rhs()

        # Move mesh
        dU.compute_ubc()
        umesh.assign(project(dU, Qcg))

        ALE.move(mesh, project(dU * dt, Qcg))
        dU.update()

        # Relocate particles as a result of mesh motion
        # NOTE: if particles were advected themselve,
        # we had to run update_facets_info() here as well
        p.relocate()

        # Assemble left-hand side on new config, but not the right-hand side
        pde_projection.assemble(True, False)
        pde_projection.solve_problem(phibar.cpp_object(), phih.cpp_object(),
                                     'mumps', 'none')

        # Needed to compute conservation, note that there
        # is an outgoing flux at left boundary
        new_area = assemble(phih*dx)
        gamma = conditional(ge(dot(uadvect, n), 0), 0, 1)
        bflux = assemble((1-gamma) * dot(uadvect, n) * phih * ds)

        # Update solution
        assign(phih0, phih)

        # Put assertion on (global) mass balance, local mass balance is
        # too time consuming but should pass also
        assert new_area - old_area + bflux * dt < 1e-12

        # Assert that max value of phih stays close to 2 and
        # min value close to 0. This typically will fail if
        # we do not do a correct relocate of particles
        assert np.amin(phih.vector().get_local()) > -0.015
        assert np.amax(phih.vector().get_local()) < 1.04