Beispiel #1
0
import dolfin as df

mesh1 = df.UnitSquareMesh(2, 2)
mesh2 = df.UnitSquareMesh(2, 2)
V1 = df.FunctionSpace(mesh1, "CG", 1)
V2 = df.FunctionSpace(mesh2, "CG", 1)

u1 = df.Function(V1)
v1 = df.TestFunction(V1)
u2 = df.Function(V2)
v2 = df.TestFunction(V2)

u3 = df.Function(V2)
u1.vector()[0] = 1
u3.vector()[:] = u1.vector()[:]
u1.vector()[0] = 2
print(u1.vector()[0], u3.vector()[0])

df.assemble(-1.0 * df.inner(df.grad(u1), df.grad(v1)) * df.dx)
df.assemble(-1.0 * df.inner(df.grad(u2), df.grad(v2)) * df.dx)
df.assemble(-1.0 * df.inner(df.grad(u3), df.grad(v2)) * df.dx)
Beispiel #2
0
def dolfin_fiberrules(
        mesh,
        fiber_space=None,
        fiber_rotation_epi=50,  # 50 
        fiber_rotation_endo=40,  # 40
        sheet_rotation_epi=65,  # 65
        sheet_rotation_endo=25,  # 25
        alpha_noise=0.0,
        beta_noise=0.0):
    """
    Create fiber, cross fibers and sheet directions

    Arguments
    ---------
    mesh : dolfin.Mesh
       A dolfin mesh with marked boundaries:
       base = 10, rv = 20, lv = 30, epi = 40
       The base is assumed placed at x=0
    fiber_space : dolfin.FunctionSpace (optional)
       Determines for what space the fibers should be calculated for.
    fiber_rotation_epi : float (optional)
       Fiber rotation angle on the endocardial surfaces.
    fiber_rotation_endo : float (optional)
       Fiber rotation angle on the epicardial surfaces.
    sheet_rotation_epi : float (optional)
       Sheet rotation angle on the endocardial surfaces.
    sheet_rotation_endo : float (optional)
       Sheet rotation angle on the epicardial surfaces.
    """
    #import cpp

    if not isinstance(mesh, d.Mesh):
        raise TypeError("Expected a dolfin.Mesh as the mesh argument.")

    # Default fiber space is P1
    fiber_space = fiber_space or d.FunctionSpace(mesh, "P", 1)

    # Create scalar laplacian solutions
    d.info("Calculating scalar fields")
    scalar_solutions = scalar_laplacians(mesh)

    # Create gradients
    d.info("\nCalculating gradients")
    data = project_gradients(mesh, fiber_space, scalar_solutions)

    # Assign the fiber and sheet rotations
    data.fiber_rotation_epi = fiber_rotation_epi
    data.fiber_rotation_endo = fiber_rotation_endo
    data.sheet_rotation_epi = sheet_rotation_epi
    data.sheet_rotation_endo = sheet_rotation_endo

    #Gaussian field with correlation length l
    #p , l = np.inf, 2
    #number of terms in expansion
    #k = 10

    #kernel = Matern(p = p,l = l)    #0,1Exponential covariance kernel
    #kle  = KLE(mesh, kernel, verbose = True)
    #kle.compute_eigendecomposition(k = k)#20 by default

    #Generate realizations
    #noise = kle.realizations()
    #x = np.zeros(len(noise))
    #noise = np.array(x)
    #noise[0:len(noise)/2] = 30
    ##print y
    #print "noise array", noise

    #V = d.FunctionSpace(mesh, "CG", 1)
    #random_field =d.Function(V)
    #random_f = np.zeros((mesh.num_vertices()),dtype =float)
    #random_f = noise
    #random_field.vector()[:] = random_f[d.dof_to_vertex_map(V)]
    #d.plot(random_field, mesh, interactive =True)

    ##random_f = noise

    #x = np.zeros(len(noise))
    #y = np.array(x)
    #y[0:len(noise)/2] = 30
    ##print y
    #print "noise array", y

    # Check noise
    if np.isscalar(alpha_noise):
        alpha_noise = np.zeros(mesh.num_vertices(), dtype=float)

    if np.isscalar(beta_noise):
        beta_noise = np.zeros(mesh.num_vertices(), dtype=float)

    # Call the fiber sheet generation
    cpp.computeFiberSheetSystem(data,
                                alpha_noise[d.dof_to_vertex_map(fiber_space)],
                                beta_noise[d.dof_to_vertex_map(fiber_space)])
    #cpp.computeFiberSheetSystem(data,noise)

    # Create output Functions
    Vv = d.VectorFunctionSpace(mesh, fiber_space.ufl_element().family(), \
                               fiber_space.ufl_element().degree())
    V = fiber_space

    fiber_sheet_tensor = data.fiber_sheet_tensor
    fiber_components = []
    scalar_size = fiber_sheet_tensor.size / 9
    indices = np.zeros(scalar_size * 3, dtype="L")
    indices[0::3] = np.arange(scalar_size, dtype="L") * 9  # x
    indices[1::3] = np.arange(scalar_size, dtype="L") * 9 + 3  # y
    indices[2::3] = np.arange(scalar_size, dtype="L") * 9 + 6  # z

    for ind, name in enumerate(["f0", "n0", "s0"]):
        component = d.Function(Vv, name=name)

        # Sort the fibers and sheets in dolfin degrees of freedom (dofs)
        component.vector()[:] = fiber_sheet_tensor[indices]
        fiber_components.append(component)
        indices += 1

    # Make sheet the last component
    fiber_components = [fiber_components[0]] + fiber_components[-1:0:-1]

    return fiber_components
def test1():
    """
    Test whether SingleRegularization returns same output as
    underlying regularization
    """
    mesh = dl.UnitSquareMesh(40, 40)
    Vm = dl.FunctionSpace(mesh, 'CG', 1)
    VmVm = createMixedFS(Vm, Vm)
    ab = dl.Function(VmVm)
    xab = dl.Function(VmVm)
    x = dl.Function(Vm)
    regul = LaplacianPrior({'Vm': Vm, 'gamma': 1e-4, 'beta': 1e-4})
    regula = LaplacianPrior({'Vm': Vm, 'gamma': 1e-4, 'beta': 1e-4})
    jointregula = SingleRegularization(regula, 'a')
    regulb = LaplacianPrior({'Vm': Vm, 'gamma': 1e-4, 'beta': 1e-4})
    jointregulb = SingleRegularization(regulb, 'b')

    for ii in range(4):
        #ab.vector()[:] = (ii+1.0)*np.random.randn(2*Vm.dim())
        ab = dl.interpolate(dl.Expression(('sin(nn*pi*x[0])*sin(nn*pi*x[1])',
        'sin(nn*pi*x[0])*sin(nn*pi*x[1])'),\
        nn=ii+1, degree=10), VmVm)
        a, b = ab.split(deepcopy=True)

        print '\nTest a'
        costregul = regul.cost(a)
        costjoint = jointregula.costab(a, b)
        print 'cost={}, diff={}'.format(costregul,
                                        np.abs(costregul - costjoint))

        gradregul = regul.grad(a)
        gradjoint = jointregula.gradab(a, b)
        xab.vector().zero()
        xab.vector().axpy(1.0, gradjoint)
        ga, gb = xab.split(deepcopy=True)
        gan = ga.vector().norm('l2')
        gbn = gb.vector().norm('l2')
        diffn = (gradregul - ga.vector()).norm('l2')
        print '|ga|={}, diff={}, |gb|={}'.format(gan, diffn, gbn)

        regul.assemble_hessian(a)
        jointregula.assemble_hessianab(a, b)
        Hvregul = regul.hessian(a.vector())
        Hvjoint = jointregula.hessianab(a.vector(), b.vector())
        xab.vector().zero()
        xab.vector().axpy(1.0, Hvjoint)
        Ha, Hb = xab.split(deepcopy=True)
        Han = Ha.vector().norm('l2')
        Hbn = Hb.vector().norm('l2')
        diffn = (Hvregul - Ha.vector()).norm('l2')
        print '|Ha|={}, diff={}, |Hb|={}'.format(Han, diffn, Hbn)

        solvera = regul.getprecond()
        solveraiter = solvera.solve(x.vector(), a.vector())
        solverab = jointregula.getprecond()
        solverabiter = solverab.solve(xab.vector(), ab.vector())
        xa, xb = xab.split(deepcopy=True)
        diffn = (x.vector() - xa.vector()).norm('l2')
        diffbn = (b.vector() - xb.vector()).norm('l2')
        xan = xa.vector().norm('l2')
        xbn = xb.vector().norm('l2')
        print '|xa|={}, diff={}'.format(xan, diffn)
        print '|xb|={}, diff={}'.format(xbn, diffbn)
        print 'iter={}, diff={}'.format(solveraiter,
                                        np.abs(solveraiter - solverabiter))

        print 'Test b'
        costregul = regul.cost(b)
        costjoint = jointregulb.costab(a, b)
        print 'cost={}, diff={}'.format(costregul,
                                        np.abs(costregul - costjoint))

        gradregul = regul.grad(b)
        gradjoint = jointregulb.gradab(a, b)
        xab.vector().zero()
        xab.vector().axpy(1.0, gradjoint)
        ga, gb = xab.split(deepcopy=True)
        gan = ga.vector().norm('l2')
        gbn = gb.vector().norm('l2')
        diffn = (gradregul - gb.vector()).norm('l2')
        print '|gb|={}, diff={}, |ga|={}'.format(gbn, diffn, gan)

        regul.assemble_hessian(b)
        jointregulb.assemble_hessianab(a, b)
        Hvregul = regul.hessian(b.vector())
        Hvjoint = jointregulb.hessianab(a.vector(), b.vector())
        xab.vector().zero()
        xab.vector().axpy(1.0, Hvjoint)
        Ha, Hb = xab.split(deepcopy=True)
        Han = Ha.vector().norm('l2')
        Hbn = Hb.vector().norm('l2')
        diffn = (Hvregul - Hb.vector()).norm('l2')
        print '|Hb|={}, diff={}, |Ha|={}'.format(Hbn, diffn, Han)

        solverb = regul.getprecond()
        solverbiter = solverb.solve(x.vector(), b.vector())
        solverab = jointregulb.getprecond()
        solverabiter = solverab.solve(xab.vector(), ab.vector())
        xa, xb = xab.split(deepcopy=True)
        diffn = (x.vector() - xb.vector()).norm('l2')
        diffan = (a.vector() - xa.vector()).norm('l2')
        xan = xa.vector().norm('l2')
        xbn = xb.vector().norm('l2')
        print '|xb|={}, diff={}'.format(xbn, diffn)
        print '|xa|={}, diff={}'.format(xan, diffan)
        print 'iter={}, diff={}'.format(solverbiter,
                                        np.abs(solverbiter - solverabiter))
Beispiel #4
0
             try:
                 f_read = pickle.load(f)
             except:
                 f_read = pickle.load(f, encoding='bytes')
             gLIS_eigv, gLIS_eigf = f_read[-2:]
             f.close()
             found = True
         except:
             print('pickle file broken! global LIS not read!')
 if found:
     # read samples
     fnames = [f for f in os.listdir(folder) if f.endswith('.h5')]
     num_samp = 10000
     prj_samp = np.zeros((num_samp, len(gLIS_eigv)))
     found = False
     samp_f = df.Function(elliptic.pde.V, name="parameter")
     bad_idx = []
     prog = np.ceil(num_samp * (.1 + np.arange(0, 1, .1)))
     for f_i in fnames:
         if '_' + algs[i] + '_' in f_i:
             try:
                 f = df.HDF5File(elliptic.pde.mpi_comm,
                                 os.path.join(folder, f_i), "r")
                 for s in xrange(num_samp):
                     try:
                         f.read(samp_f, 'sample_{0}'.format(s))
                     except:
                         bad_idx.append(s)
                     prj_samp[s, ] = gLIS_eigf.T.dot(elliptic.prior.M *
                                                     samp_f.vector())
                     if s + 1 in prog:
Beispiel #5
0
    fid << vector2Function(post_pw_variance, Vh, name="Posterior")
    fid << vector2Function(pr_pw_variance, Vh, name="Prior")
    fid << vector2Function(corr_pw_variance, Vh, name="Correction")

    U.export(Vh, "hmisfit/evect.pvd", varname="gen_evect", normalize=True)
    if rank == 0:
        np.savetxt("hmisfit/eigevalues.dat", d)

    if rank == 0:
        print sep, "Generate samples from Prior and Posterior", sep
    fid_prior = dl.File("samples/sample_prior.pvd")
    fid_post = dl.File("samples/sample_post.pvd")
    nsamples = 50
    noise = dl.Vector()
    posterior.init_vector(noise, "noise")
    s_prior = dl.Function(Vh, name="sample_prior")
    s_post = dl.Function(Vh, name="sample_post")
    for i in range(nsamples):
        parRandom.normal(1., noise)
        posterior.sample(noise, s_prior.vector(), s_post.vector())
        fid_prior << s_prior
        fid_post << s_post

    if rank == 0:
        print sep, "Visualize results", sep
        plt.figure()
        plt.plot(range(0, k), d, 'b*', range(0, k), np.ones(k), '-r')
        plt.yscale('log')
        plt.show()

    if nproc == 1:
Beispiel #6
0
def set_D_with_protein(setup):
    meshp = setup.geo.mesh  # mesh WITH protein
    x0 = np.array(setup.geop.x0)
    dim = setup.phys.dim
    x0 = x0 if dim == 3 else x0[::2]
    r0 = setup.geop.rMolecule
    rion = 0.11

    # load diffusivity on mesh without protein
    functions, mesh = fields.get_functions(**setup.solverp.diffusivity_data)
    dist = functions["dist"]
    D0 = functions["D"]

    # evaluate dist, D on meshp nodes
    Vp = dolfin.FunctionSpace(meshp, "CG", 1)
    VVp = dolfin.VectorFunctionSpace(meshp, "CG", 1)

    distp_ = dolfin.interpolate(dist, Vp)
    D0p_ = dolfin.interpolate(D0, VVp)

    distp = distp_.vector()[dolfin.vertex_to_dof_map(Vp)]
    D0p = D0p_.vector()[dolfin.vertex_to_dof_map(VVp)]
    D0p = np.column_stack([D0p[i::dim] for i in range(dim)])

    x = meshp.coordinates()
    #    probes = Probes(x.flatten(), V)
    #    probes(dist)
    #    distp = probes.array(0)
    #
    #    probes_ = Probes(x.flatten(), VV)
    #    probes_(D0)
    #    D0p = probes_.array(0)

    # first create (N,3,3) array from D0 (N,3)
    N = len(D0p)
    Da = np.zeros((N, dim, dim))
    i3 = np.array(range(dim))

    Da[:, i3, i3] = D0p

    # modify (N,3,3) array to include protein interaction
    R = x - x0
    r = np.sqrt(np.sum(R**2, 1))
    overlap = r < rion + r0
    near = ~overlap & (r - r0 < distp)
    h = np.maximum(r[near] - r0, rion)
    eps = 1e-2
    D00 = setup.phys.D

    Dt = np.zeros_like(r)
    Dn = np.zeros_like(r)

    Dt[overlap] = eps
    Dn[overlap] = eps
    Dt[near] = diff.Dt_plane(h, rion)
    Dn[near] = diff.Dn_plane(h, rion, N=20)

    # D(R) = Dn(h) RR^T + Dt(h) (I - RR^T) where R is normalized
    R0 = R / (r[:, None] + 1e-100)
    RR = (R0[:, :, None] * R0[:, None, :])
    I = np.zeros((N, dim, dim))
    I[:, i3, i3] = 1.
    Dpp = Dn[:, None, None] * RR + Dt[:, None, None] * (I - RR)
    Da[overlap | near] = D00 * Dpp[overlap | near]

    # assign final result to dolfin P1 TensorFunction
    VVV = dolfin.TensorFunctionSpace(meshp, "CG", 1, shape=(dim, dim))
    D = dolfin.Function(VVV)
    v2d = dolfin.vertex_to_dof_map(VVV)
    Dv = D.vector()
    for k, (i, j) in enumerate(product(i3, i3)):
        Dv[np.ascontiguousarray(v2d[k::dim**2])] = np.ascontiguousarray(Da[:,
                                                                           i,
                                                                           j])

    setup.phys.update(Dp=D, Dm=D)
    #embed()
    return D
Beispiel #7
0
def _load_function(FILE, mesh, rank):
    V = _space(mesh, rank)
    return dolfin.Function(V, str(os.path.join(DIR, FILE)))
    def initiate_solution_diffusion(mod,rho_solute=const.rhom):
        """
        Before the equations can be solved for the liquid solution: initial conditions and solution properties need to be setup
            update domain
            time array and ethanol source timing
            initial conditions
            variational problem
            solution properties
            boundary conditions
        To be run once after get_initial_conditions() and get_boundary_conditions()
        """

        # --- Get new domain --- #
        mod.sol_mesh = dolfin.IntervalMesh(mod.n,mod.Rstar_center,mod.Rstar)
        mod.sol_V = dolfin.FunctionSpace(mod.sol_mesh,'CG',1)
        mod.sol_mesh.coordinates()[:] = np.log(mod.sol_mesh.coordinates())
        mod.sol_coords = mod.sol_V.tabulate_dof_coordinates().copy()
        mod.sol_idx_wall = np.argmax(mod.sol_coords)

        # --- Time array --- #
        # Now that we have the melt-out time, we can define the time array
        mod.ts = np.arange(mod.t_init,mod.t_final+mod.dt,mod.dt)/mod.t0
        mod.dt /= mod.t0
        # Define the ethanol source
        mod.source_timing = mod.source_timing/mod.t0
        mod.source_duration /= mod.t0
        mod.source = mod.source_mass_final/(mod.source_duration*np.sqrt(np.pi))*np.exp(-((mod.ts-mod.source_timing)/mod.source_duration)**2.)

        # --- Set initial conditions --- #
        # solution temperature
        mod.u0_s = dolfin.Function(mod.sol_V)
        mod.u0_s.vector()[:] = mod.Tf_wall
        # solution concentration
        mod.u0_c = dolfin.project(dolfin.Constant(mod.C),mod.sol_V)

        # --- Set up the variational Problem --- #
        mod.u_s = dolfin.TrialFunction(mod.sol_V)
        mod.v_s = dolfin.TestFunction(mod.sol_V)
        mod.T_s = dolfin.Function(mod.sol_V)
        mod.C = dolfin.project(dolfin.Constant(mod.C),mod.sol_V)
        mod.Tf = Tf_depression(mod.C,linear=True)/abs(mod.T_inf)
        mod.Tf_wall = dolfin.project(mod.Tf,mod.sol_V).vector()[mod.sol_idx_wall]

        # --- Get the solution properties --- #
        mod.rhos = dolfin.project(dolfin.Expression('C + rhow*(1.-C/rho_solute)',degree=1,C=mod.C,rhow=const.rhow,rho_solute=rho_solute),mod.sol_V)
        mod.cs = dolfin.project(dolfin.Expression('ce*(C/rho_solute) + cw*(1.-C/rho_solute)',degree=1,C=mod.C,cw=const.cw,ce=const.ce,rho_solute=rho_solute),mod.sol_V)
        mod.ks = dolfin.project(dolfin.Expression('ke*(C/rho_solute) + kw*(1.-C/rho_solute)',degree=1,C=mod.C,kw=const.kw,ke=const.ke,rho_solute=rho_solute),mod.sol_V)
        mod.rhos_wall = mod.rhos.vector()[mod.sol_idx_wall]
        mod.cs_wall = mod.cs.vector()[mod.sol_idx_wall]
        mod.ks_wall = mod.ks.vector()[mod.sol_idx_wall]

        # --- Boundary Conditions --- #
        # Liquid boundary condition at hole wall (same temperature as ice)
        class sWall(dolfin.SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary and x[0] > mod.sol_coords[mod.sol_idx_wall] - const.tol
        # center flux
        class center(dolfin.SubDomain):
            def inside(self, x, on_boundary):
                return on_boundary and x[0] < mod.w_center + const.tol

        # Initialize boundary classes
        mod.sWall = sWall()
        mod.center = center()
        # This will be used in the boundary condition for mass diffusion
        mod.boundaries = dolfin.MeshFunction("size_t", mod.sol_mesh, 0) # this index 0 is an alternative to the command boundaries.set_all(0)
        mod.sWall.mark(mod.boundaries, 1)
        mod.center.mark(mod.boundaries, 2)
        mod.sds = dolfin.Measure("ds")(subdomain_data=mod.boundaries)
Beispiel #9
0
    def __init__(self, simulation, field_inp):
        """
        A scalar field
        """
        self.simulation = simulation
        self.read_input(field_inp)

        # Show the input data
        simulation.log.info('Creating a sharp field %r' % self.name)
        simulation.log.info('    Variable: %r' % self.var_name)
        simulation.log.info('    Local proj: %r' % self.local_projection)
        simulation.log.info('    Proj. degree: %r' % self.projection_degree)
        simulation.log.info('    Poly. degree: %r' % self.polynomial_degree)

        mesh = simulation.data['mesh']
        self.V = dolfin.FunctionSpace(mesh, 'DG', self.polynomial_degree)
        self.func = dolfin.Function(self.V)

        if self.local_projection:
            # Represent the jump using a quadrature element
            quad_elem = dolfin.FiniteElement(
                'Quadrature',
                mesh.ufl_cell(),
                self.projection_degree,
                quad_scheme="default",
            )
            xpos, ypos, zpos = self.xpos, self.ypos, self.zpos
            if simulation.ndim == 2:
                cpp0 = 'x[0] < %r and x[1] < %r' % (xpos, ypos)
            else:
                cpp0 = 'x[0] < %r and x[1] < %r and x[2] < %r' % (xpos, ypos, zpos)
            cpp = '(%s) ? %r : %r' % (cpp0, self.val_below, self.val_above)
            e = dolfin.Expression(cpp, element=quad_elem)
            dx = dolfin.dx(metadata={'quadrature_degree': self.projection_degree})

            # Perform the local projection
            u, v = dolfin.TrialFunction(self.V), dolfin.TestFunction(self.V)
            a = u * v * dolfin.dx
            L = e * v * dx
            ls = dolfin.LocalSolver(a, L)
            ls.solve_local_rhs(self.func)

            # Clip values to allowable bounds
            arr = self.func.vector().get_local()
            val_min = min(self.val_below, self.val_above)
            val_max = max(self.val_below, self.val_above)
            clipped_arr = numpy.clip(arr, val_min, val_max)
            self.func.vector().set_local(clipped_arr)
            self.func.vector().apply('insert')

        else:
            # Initialise the sharp static field
            dm = self.V.dofmap()
            arr = self.func.vector().get_local()
            above, below = self.val_above, self.val_below
            xpos, ypos, zpos = self.xpos, self.ypos, self.zpos
            for cell in dolfin.cells(simulation.data['mesh']):
                mp = cell.midpoint()[:]
                dof, = dm.cell_dofs(cell.index())
                if (
                    mp[0] < xpos
                    and mp[1] < ypos
                    and (simulation.ndim == 2 or mp[2] < zpos)
                ):
                    arr[dof] = below
                else:
                    arr[dof] = above
            self.func.vector().set_local(arr)
            self.func.vector().apply('insert')
Beispiel #10
0
 def generate_parameter(self):
     """ return a vector in the shape of the parameter """
     return dl.Function(self.Vh[PARAMETER]).vector()
Beispiel #11
0
    def QoI_FEM(lam1,lam2,pointa,pointb,gridx,gridy,p):
        aa = pointa[0]
        bb = pointb[0]
        cc = pointa[1]
        dd = pointb[1]

        mesh = fn.UnitSquareMesh(gridx, gridy)
        V = fn.FunctionSpace(mesh, "Lagrange", p)

        # Define diffusion tensor (here, just a scalar function) and parameters
        A = fn.Expression((('exp(lam1)','a'),
                    ('a','exp(lam2)')), a = fn.Constant(0.0), lam1 = lam1, lam2 = lam2, degree=3) 

        u_exact = fn.Expression("sin(lam1*pi*x[0])*cos(lam2*pi*x[1])", lam1 = lam1, lam2 = lam2, degree=2+p)

        # Define the mix of Neumann and Dirichlet BCs
        class LeftBoundary(fn.SubDomain):
            def inside(self, x, on_boundary):
                return (x[0] < fn.DOLFIN_EPS)
        class RightBoundary(fn.SubDomain):
            def inside(self, x, on_boundary):
                return (x[0] > 1.0 - fn.DOLFIN_EPS)
        class TopBoundary(fn.SubDomain):
            def inside(self, x, on_boundary):
                return (x[1] > 1.0 - fn.DOLFIN_EPS)
        class BottomBoundary(fn.SubDomain):
            def inside(self, x, on_boundary):
                return (x[1] < fn.DOLFIN_EPS)

        # Create a mesh function (mf) assigning an unsigned integer ('uint')
        # to each edge (which is a "Facet" in 2D)
        mf = fn.MeshFunction('size_t', mesh, 1)
        mf.set_all(0) # initialize the function to be zero
        # Setup the boundary classes that use Neumann boundary conditions
        NTB = TopBoundary() # instatiate
        NTB.mark(mf, 1) # set all values of the mf to be 1 on this boundary
        NBB = BottomBoundary()
        NBB.mark(mf, 2) # set all values of the mf to be 2 on this boundary
        NRB = RightBoundary()
        NRB.mark(mf, 3)

        # Define Dirichlet boundary conditions
        Gamma_0 = fn.DirichletBC(V, u_exact, LeftBoundary())
        bcs = [Gamma_0]

        # Define data necessary to approximate exact solution
        f = ( fn.exp(lam1)*(lam1*fn.pi)**2 + fn.exp(lam2)*(lam2*fn.pi)**2 ) * u_exact
        #g1:#pointing outward unit normal vector, pointing upaward (0,1)
        g1 = fn.Expression("-exp(lam2)*lam2*pi*sin(lam1*pi*x[0])*sin(lam2*pi*x[1])", lam1=lam1, lam2=lam2, degree=2+p)
        #g2:pointing downward (0,1)
        g2 = fn.Expression("exp(lam2)*lam2*pi*sin(lam1*pi*x[0])*sin(lam2*pi*x[1])", lam1=lam1, lam2=lam2, degree=2+p)
        g3 = fn.Expression("exp(lam1)*lam1*pi*cos(lam1*pi*x[0])*cos(lam2*pi*x[1])", lam1=lam1, lam2=lam2, degree=2+p)

        fn.ds = fn.ds(subdomain_data=mf)
        # Define variational problem
        u = fn.TrialFunction(V)
        v = fn.TestFunction(V)
        a = fn.inner(A*fn.grad(u), fn.grad(v))*fn.dx
        L = f*v*fn.dx + g1*v*fn.ds(1) + g2*v*fn.ds(2) + g3*v*fn.ds(3)  #note the 1, 2 and 3 correspond to the mf

        # Compute solution
        u = fn.Function(V)
        fn.solve(a == L, u, bcs)
        psi = AvgCharFunc([aa, bb, cc, dd], degree=0)
        Q = fn.assemble(fn.project(psi * u, V) * fn.dx)
        
        return Q
Beispiel #12
0
 def generate_state(self):
     """ return a vector in the shape of the state """
     return dl.Function(self.Vh[STATE]).vector()
Beispiel #13
0
VV = createMixedFS(V, V)
cg = normalizedcrossgradient(VV)

print '\nsinusoidal cross-gradients'
for ii in range(5):
    a = dl.interpolate(dl.Expression('1.0 + sin(n*pi*x[0])*sin(n*pi*x[1])',\
    n=ii, degree=10), V)
    for jj in range(5):
        b = dl.interpolate(dl.Expression('1.0 + sin(n*pi*x[0])*sin(n*pi*x[1])',\
        n=jj, degree=10), V)
        print cg.costab(a, b),
    print ''

#############################################################
print '\ncheck gradient'
ak, bk = dl.Function(V), dl.Function(V)
directab = dl.Function(VV)
H = [1e-6, 1e-7, 1e-5]
for ii in range(5):
    print 'ii={}'.format(ii)
    a = dl.interpolate(dl.Expression('1.0 + sin(n*pi*x[0])*sin(n*pi*x[1])',\
    n=ii, degree=10), V)
    b = dl.interpolate(dl.Expression('pow(x[0], n)*pow(x[1], n)',\
    n=ii, degree=10), V)
    grad = cg.gradab(a, b)
    for jj in range(5):
        directa = dl.interpolate(dl.Expression('pow(x[0], n)*pow(x[1], n)',\
        n=jj+1, degree=10), V)
        directb = dl.interpolate(dl.Expression('1.0 + sin(n*pi*x[0])*sin(n*pi*x[1])',\
        n=jj+1, degree=10), V)
        dl.assign(directab.sub(0), directa)
Beispiel #14
0
    def __init__(self,
                 V,
                 bcs=None,
                 objects=None,
                 circuit=None,
                 remove_null_space=False,
                 eps0=1,
                 linalg_solver='gmres',
                 linalg_precond='hypre_amg'):

        if bcs == None:
            bcs = []

        if objects == None:
            objects = []

        if not isinstance(bcs, list):
            bcs = [bcs]

        if not isinstance(objects, list):
            objects = [objects]

        self.V = V
        self.bcs = bcs
        self.objects = objects
        self.circuit = circuit
        self.remove_null_space = remove_null_space
        """
        One could perhaps identify the cases in which different solvers and preconditioners
        should be used, and by default choose the best suited for the problem.
        """
        self.solver = df.PETScKrylovSolver(linalg_solver, linalg_precond)
        self.solver.parameters['absolute_tolerance'] = 1e-14
        self.solver.parameters['relative_tolerance'] = 1e-12
        self.solver.parameters['maximum_iterations'] = 1000
        self.solver.parameters['nonzero_initial_guess'] = True

        phi = df.TrialFunction(V)
        phi_ = df.TestFunction(V)

        self.a = df.Constant(eps0) * df.inner(df.grad(phi),
                                              df.grad(phi_)) * df.dx
        A = df.assemble(self.a)

        for bc in bcs:
            bc.apply(A)

        for o in objects:
            o.apply(A)

        if circuit != None:
            A, = circuit.apply(A)

        if remove_null_space:
            phi = df.Function(V)
            null_vec = df.Vector(phi.vector())
            V.dofmap().set(null_vec, 1.0)
            null_vec *= 1.0 / null_vec.norm("l2")

            self.null_space = df.VectorSpaceBasis([null_vec])
            df.as_backend_type(A).set_nullspace(self.null_space)

        self.A = A
        self.phi_ = phi_
Beispiel #15
0
    def __init__(self, fileName, timeEnd, timeStep):

        self.times = []
        self.BB = []
        self.HH = []
        self.TD = []
        self.TB = []
        self.TX = []
        self.TY = []
        self.TZ = []
        self.us = []
        self.ub = []

        ##########################################################
        ################           MESH          #################
        ##########################################################
        # TODO: Probably do not have to save then open mesh
        self.mesh = df.Mesh()
        self.inFile = fc.HDF5File(self.mesh.mpi_comm(), fileName, "r")
        self.inFile.read(self.mesh, "/mesh", False)

        #########################################################
        #################  FUNCTION SPACES  #####################
        #########################################################
        self.E_Q = df.FiniteElement("CG", self.mesh.ufl_cell(), 1)
        self.Q = df.FunctionSpace(self.mesh, self.E_Q)
        self.E_V = df.MixedElement(self.E_Q, self.E_Q, self.E_Q)
        self.V = df.FunctionSpace(self.mesh, self.E_V)

        self.assigner_inv = fc.FunctionAssigner([self.Q, self.Q, self.Q],
                                                self.V)
        self.assigner = fc.FunctionAssigner(self.V, [self.Q, self.Q, self.Q])

        self.U = df.Function(self.V)
        self.dU = df.TrialFunction(self.V)
        self.Phi = df.TestFunction(self.V)
        self.u, self.u2, self.H = df.split(self.U)
        self.phi, self.phi1, self.xsi = df.split(self.Phi)

        self.un = df.Function(self.Q)
        self.u2n = df.Function(self.Q)

        self.zero_sol = df.Function(self.Q)

        self.S0 = df.Function(self.Q)
        self.B = df.Function(self.Q)
        self.H0 = df.Function(self.Q)
        self.A = df.Function(self.Q)

        self.inFile.read(self.S0.vector(), "/surface", True)
        self.inFile.read(self.B.vector(), "/bed", True)
        self.inFile.read(self.A.vector(), "/smb", True)

        self.H0.assign(self.S0 - self.B)

        self.Hmid = theta * self.H + (1 - theta) * self.H0

        self.S = self.B + self.Hmid

        self.width = df.interpolate(Width(degree=2), self.Q)

        self.strs = Stresses(self.U, self.Hmid, self.H0, self.H, self.width,
                             self.B, self.S, self.Phi)

        self.R = -(self.strs.tau_xx + self.strs.tau_xz + self.strs.tau_b +
                   self.strs.tau_d + self.strs.tau_xy) * df.dx

        #############################################################################
        ########################  MASS CONSERVATION  ################################
        #############################################################################
        self.h = df.CellSize(self.mesh)
        self.D = self.h * abs(self.U[0]) / 2.
        self.area = self.Hmid * self.width

        self.mesh_min = self.mesh.coordinates().min()
        self.mesh_max = self.mesh.coordinates().max()

        # Define boundaries
        self.ocean = df.FacetFunctionSizet(self.mesh, 0)
        self.ds = fc.ds(subdomain_data=self.ocean
                        )  # THIS DS IS FROM FENICS! border integral

        for f in df.facets(self.mesh):
            if df.near(f.midpoint().x(), self.mesh_max):
                self.ocean[f] = 1
            if df.near(f.midpoint().x(), self.mesh_min):
                self.ocean[f] = 2

        self.R += ((self.H - self.H0) / dt * self.xsi
                   - self.xsi.dx(0) * self.U[0] * self.Hmid
                   + self.D * self.xsi.dx(0) * self.Hmid.dx(0)
                   - (self.A - self.U[0] * self.H / self.width * self.width.dx(0))
                   * self.xsi) * df.dx + self.U[0] * self.area * self.xsi * self.ds(1) \
                  - self.U[0] * self.area * self.xsi * self.ds(0)

        #####################################################################
        #########################  SOLVER SETUP   ###########################
        #####################################################################

        # Bounds
        self.l_thick_bound = df.project(Constant(thklim), self.Q)
        self.u_thick_bound = df.project(Constant(1e4), self.Q)

        self.l_v_bound = df.project(-10000.0, self.Q)
        self.u_v_bound = df.project(10000.0, self.Q)

        self.l_bound = df.Function(self.V)
        self.u_bound = df.Function(self.V)

        self.assigner.assign(self.l_bound,
                             [self.l_v_bound] * 2 + [self.l_thick_bound])
        self.assigner.assign(self.u_bound,
                             [self.u_v_bound] * 2 + [self.u_thick_bound])

        # This should set the velocity at the divide (left) to zero
        self.dbc0 = df.DirichletBC(
            self.V.sub(0), 0, lambda x, o: df.near(x[0], self.mesh_min) and o)
        # Set the velocity on the right terminus to zero
        self.dbc1 = df.DirichletBC(
            self.V.sub(0), 0, lambda x, o: df.near(x[0], self.mesh_max) and o)
        # overkill?
        self.dbc2 = df.DirichletBC(
            self.V.sub(1), 0, lambda x, o: df.near(x[0], self.mesh_max) and o)
        # set the thickness on the right edge to thklim
        self.dbc3 = df.DirichletBC(
            self.V.sub(2), thklim,
            lambda x, o: df.near(x[0], self.mesh_max) and o)

        # Define variational solver for the mass-momentum coupled problem
        self.J = df.derivative(self.R, self.U, self.dU)

        self.coupled_problem = df.NonlinearVariationalProblem(self.R, self.U, bcs=[self.dbc0, self.dbc1, self.dbc3], \
                                                              J=self.J)

        self.coupled_problem.set_bounds(self.l_bound, self.u_bound)

        self.coupled_solver = df.NonlinearVariationalSolver(
            self.coupled_problem)

        # Acquire the optimizations in fenics optimizations
        set_solver_options(self.coupled_solver)

        self.t = 0
        self.timeEnd = float(timeEnd)
        self.dtFloat = float(timeStep)

        self.inFile.close()
Beispiel #16
0
def general_solver(parameters, advanced_parameters):
    print 'TESTING THREAD1'
    setup_general_parameters()
    patient = parameters['patient']
    mesh = patient.mesh
    mesh_name = parameters['mesh_name']
    marked_mesh = patient.ffun
    N = df.FacetNormal(mesh)
    fibers = patient.fiber

    # Getting BC
    BC_type = parameters['BC_type']

    def make_dirichlet_bcs(W):
        V = W if W.sub(0).num_sub_spaces() == 0 else W.sub(0)
        if BC_type == 'fix_x':
            no_base_x_tran_bc = df.DirichletBC(V.sub(0), df.Constant(0.0),
                                               marked_mesh,
                                               patient.markers["BASE"][0])
        elif BC_type == 'fixed':
            no_base_x_tran_bc = df.DirichletBC(V, df.Constant(
                (0.0, 0.0, 0.0)), marked_mesh, patient.markers["BASE"][0])
        return no_base_x_tran_bc

    # Contraction parameter
    # gamma = Constant(0.0)
    #gamma = df.Function(df.FunctionSpace(mesh, "R", 0))
    gamma = RegionalParameter(patient.sfun)

    gamma_values = parameters['gamma']
    gamma_base = gamma_values['gamma_base']
    gamma_mid = gamma_values['gamma_mid']
    gamma_apical = gamma_values['gamma_apical']
    gamma_apex = gamma_values['gamma_apex']

    gamma_arr = np.array(gamma_base + gamma_mid + gamma_apical + gamma_apex)

    G = RegionalParameter(patient.sfun)
    G.vector()[:] = gamma_arr
    G_ = df.project(G.get_function(), G.get_ind_space())

    f_gamma = df.XDMFFile(df.mpi_comm_world(), "activation.xdmf")
    f_gamma.write(G_)

    # Pressure
    pressure = df.Constant(0.0)
    lv_pressure = df.Constant(0.0)
    rv_pressure = df.Constant(0.0)
    #lv_pressure = df.Constant(0.0)
    #rv_pressure = df.Constant(0.0)

    # Spring
    spring_constant = advanced_parameters['spring_constant']
    spring = df.Constant(spring_constant)
    spring_area = advanced_parameters['spring_area']

    # Set up material model
    material_model = advanced_parameters['material_model']
    active_model = advanced_parameters['active_model']
    T_ref = advanced_parameters['T_ref']
    matparams = advanced_parameters['mat_params']
    #matparams=setup_material_parameters(material_model)
    if material_model == 'guccione':
        try:
            args = (fibers, gamma, matparams, active_model, patient.sheet,
                    patient.sheet_normal, T_ref)

        except AttributeError:
            print 'Mesh does not have "sheet" attribute, choose another material model.'
            return

    else:
        args = (
            fibers,
            gamma,
            matparams,
            active_model,
            #patient.sheet,
            #patient.sheet_normal,
            T_ref)

    if material_model == 'holzapfel_ogden':
        material = mat.HolzapfelOgden(*args)

    elif material_model == 'guccione':
        material = mat.Guccione(*args)

    elif material_model == 'neo_hookean':
        material = mat.NeoHookean(*args)

    # Create parameters for the solver
    if mesh_name == 'biv_ellipsoid.h5':
        params = {
            "mesh": mesh,
            "facet_function": marked_mesh,
            "facet_normal": N,
            "state_space": "P_2:P_1",
            "compressibility": {
                "type": "incompressible",
                "lambda": 0.0
            },
            "material": material,
            "bc": {
                "dirichlet":
                make_dirichlet_bcs,
                "neumann": [[lv_pressure, patient.markers["ENDO_LV"][0]],
                            [rv_pressure, patient.markers["ENDO_RV"][0]]],
                "robin": [[spring, patient.markers[spring_area][0]]]
            }
        }
    else:
        params = {
            "mesh": mesh,
            "facet_function": marked_mesh,
            "facet_normal": N,
            "state_space": "P_2:P_1",
            "compressibility": {
                "type": "incompressible",
                "lambda": 0.0
            },
            "material": material,
            "bc": {
                "dirichlet": make_dirichlet_bcs,
                "neumann": [[pressure, patient.markers["ENDO"][0]]],
                "robin": [[spring, patient.markers[spring_area][0]]]
            }
        }

    df.parameters["adjoint"]["stop_annotating"] = True

    # Initialize solver
    solver = LVSolver(params)
    print 'TESTING THREAD2'
    # Solve for the initial state
    folder_path = parameters['folder_path']
    u, p = solver.get_state().split(deepcopy=True)
    U = df.Function(u.function_space(), name="displacement")
    f = df.XDMFFile(df.mpi_comm_world(), folder_path + "/displacement.xdmf")

    sigma_f = solver.postprocess().cauchy_stress_component(fibers)
    V = df.FunctionSpace(mesh, 'DG', 1)
    sf = df.project(sigma_f, V)
    SF = df.Function(sf.function_space(), name='stress')
    g = df.XDMFFile(df.mpi_comm_world(), folder_path + "/stress.xdmf")

    solver.solve()

    u1, p1 = solver.get_state().split(deepcopy=True)
    U.assign(u1)
    f.write(U)

    sigma_f1 = solver.postprocess().cauchy_stress_component(fibers)
    sf1 = df.project(sigma_f1, V)
    SF.assign(sf1)
    g.write(SF)

    # Put on some pressure and solve
    plv = parameters['lv_pressure']
    prv = parameters['rv_pressure']

    if mesh_name == 'biv_ellipsoid.h5':
        iterate("pressure", solver, (plv, prv), {
            "p_lv": lv_pressure,
            "p_rv": rv_pressure
        })
    else:
        iterate("pressure", solver, plv, {"p_lv": pressure})

    u2, p2 = solver.get_state().split(deepcopy=True)
    U.assign(u2)
    f.write(U)

    sigma_f2 = solver.postprocess().cauchy_stress_component(fibers)
    sf2 = df.project(sigma_f2, V)
    SF.assign(sf2)
    g.write(SF)

    # Put on some active contraction and solve
    cont_mult = parameters['contraction_multiplier']
    g_ = cont_mult * gamma_arr

    iterate("gamma", solver, g_, gamma, max_nr_crash=100, max_iters=100)
    u3, p3 = solver.get_state().split(deepcopy=True)
    U.assign(u3)
    f.write(U)

    sigma_f3 = solver.postprocess().cauchy_stress_component(fibers)
    sf3 = df.project(sigma_f3, V)
    SF.assign(sf3)
    g.write(SF)

    fname_u = "output_u.h5"
    if os.path.isfile(fname_u): os.remove(fname_u)
    u1.rename("u1", "displacement")
    u2.rename("u2", "displacement")
    u3.rename("u3", "displacement")

    fname_sf = "output_sf.h5"
    if os.path.isfile(fname_sf): os.remove(fname_sf)
    sf1.rename("sf1", "stress")
    sf2.rename("sf2", "stress")
    sf3.rename("sf3", "stress")

    save_to_h5(fname_u, mesh, u1, u2, u3)
    save_to_h5(fname_sf, mesh, sf1, sf2, sf3)

    return u1, u2, u3, sf1, sf2, sf3
Beispiel #17
0
        return sum(wq * f(*xq) for xq, wq in zip(pts, weights)) / l

    # Get the MEAN
    mesh = df.BoxMesh(df.Point(-1, -1, -1), df.Point(1, 1, 1), 16, 16, 16)
    # Make 1d
    f = df.MeshFunction('size_t', mesh, 1, 0)
    # df.CompiledSubDomain('near(x[0], x[1]) && near(x[1], x[2])').mark(f, 1)
    df.CompiledSubDomain('near(x[0], 0.) && near(x[1], 0.)').mark(f, 1)

    line_mesh = EmbeddedMesh(f, 1)

    # Circle ---------------------------------------------------------
    size = 0.125
    ci = Circle(radius=lambda x0: size, degree=12)

    u = df.Function(df.FunctionSpace(mesh, 'CG', 1))
    op = Average(u, line_mesh, ci)

    surface = render_avg_surface(op)

    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')

    x0 = np.array([0, 0, 0.5])
    n = np.array([0, 0, 1])
    ci_integrate = lambda f, shape=ci, n=n, x0=x0: shape_integrate(
        f, shape, x0, n)

    # Sanity
    f = lambda x, y, z: 1
    value = ci_integrate(f)
Beispiel #18
0
def main():
    parser = argparse.ArgumentParser(description="Average various files")
    parser.add_argument("-l",
                        "--list",
                        nargs="+",
                        help="List of folders",
                        required=True)
    parser.add_argument("-f",
                        "--fields",
                        nargs="+",
                        default=None,
                        help="Sought fields")
    parser.add_argument("-t", "--time", type=float, default=0, help="Time")
    parser.add_argument("--show", action="store_true", help="Show")
    parser.add_argument("-R",
                        "--radius",
                        type=float,
                        default=None,
                        help="Radial distance")
    args = parser.parse_args()

    tss = []
    for folder in args.list:
        ts = InterpolatedTimeSeries(folder, sought_fields=args.fields)
        tss.append(ts)
    Ntss = len(tss)

    all_fields_ = []
    for ts in tss:
        all_fields_.append(set(ts.fields))
    all_fields = list(set.intersection(*all_fields_))
    if args.fields is None:
        fields = all_fields
    else:
        fields = list(set.intersection(set(args.fields), set(all_fields)))

    f_in = []
    for ts in tss:
        f_in.append(ts.functions())

    # Using the first timeseries to define the spaces
    # Could be redone to e.g. a finer, structured mesh.
    # ref_mesh = tss[0].mesh
    ref_spaces = dict([(field, f.function_space())
                       for field, f in f_in[0].items()])

    if "psi" not in fields:
        exit("No psi")

    var_names = ["t", "s"]
    index_names = ["tt", "st", "ss"]
    index_numbers = [0, 1, 4]
    dim_names = ["x", "y", "z"]

    # Loading geometry
    rad_t = []
    rad_s = []
    g_ab = []
    gab = []
    for ts in tss:
        # Should compute these from the curvature tensor
        rad_t.append(
            df.interpolate(df.Expression("x[0]", degree=2), ts.function_space))
        rad_s.append(
            df.interpolate(df.Expression("x[1]", degree=2), ts.function_space))

        # g_loc = [ts.function(name) for name in ["gtt", "gst", "gss"]]
        # g_inv_loc = [ts.function(name) for name in ["g_tt", "g_st", "g_ss"]]

        gab_loc = dict([(idx, ts.function("g{}".format(idx)))
                        for idx in index_names])
        g_ab_loc = dict([(idx, ts.function("g_{}".format(idx)))
                         for idx in index_names])

        for idx, ij in zip(index_names, index_numbers):
            # for ij in range(3):
            # ts.set_val(g_loc[ij], ts.g[:, ij])
            # ts.set_val(g_inv_loc[ij], ts.g_inv[:, ij])
            ts.set_val(g_ab_loc[idx], ts.g_ab[:, ij])
            # Could compute the gab locally instead of loading
            ts.set_val(gab_loc[idx], ts.gab[:, ij])

        g_ab_loc["ts"] = g_ab_loc["st"]
        gab_loc["ts"] = gab_loc["st"]

        g_ab.append(g_ab_loc)
        gab.append(gab_loc)

    costheta = df.Function(ref_spaces["psi"], name="costheta")
    for its, (ts, g_ab_loc, gab_loc) in enumerate(zip(tss, g_ab, gab)):
        if args.time is not None:
            step, time = get_step_and_info(ts, args.time)
        g_ab_ = to_vector(g_ab_loc)
        gab_ = to_vector(gab_loc)

        ts.update(f_in[its]["psi"], "psi", step)
        psi = f_in[its]["psi"]
        psi_t = df.project(psi.dx(0), ts.function_space)
        psi_s = df.project(psi.dx(1), ts.function_space)

        gp_t = psi_t.vector().get_local()
        gp_s = psi_s.vector().get_local()
        # gtt, gst, gss = [g_ij.vector().get_local() for g_ij in g[its]]
        # g_tt, g_st, g_ss = [g_ij.vector().get_local() for g_ij in g_inv[its]]
        gtt = gab_["tt"]
        gst = gab_["ts"]
        gss = gab_["ss"]
        g_tt = g_ab_["tt"]
        g_st = g_ab_["ts"]
        g_ss = g_ab_["ss"]

        rht = rad_t[its].vector().get_local()
        rhs = rad_s[its].vector().get_local()
        rh_norm = np.sqrt(g_tt * rht**2 + g_ss * rhs**2 + 2 * g_st * rht * rhs)
        gp_norm = np.sqrt(gtt * gp_t**2 + gss * gp_s**2 +
                          2 * gst * gp_t * gp_s)

        costheta_loc = ts.function("costheta")
        # abs(cos(theta)):
        costheta_loc.vector()[:] = abs(
            (rht * gp_t + rhs * gp_s) / (rh_norm * gp_norm + 1e-8))
        # cos(theta)**2:
        #costheta_loc.vector()[:] = ((rht*gp_t + rhs*gp_s)/(rh_norm*gp_norm+1e-8))**2
        # sin(theta):
        #costheta_loc.vector()[:] = np.sin(np.arccos((rht*gp_t + rhs*gp_s)/(rh_norm*gp_norm+1e-8)))
        # sin(theta)**2:
        # costheta_loc.vector()[:] = np.sin(np.arccos((rht*gp_t + rhs*gp_s)/(rh_norm*gp_norm+1e-8)))**2
        # abs(theta):
        #costheta_loc.vector()[:] = abs(np.arccos((rht*gp_t + rhs*gp_s)/(rh_norm*gp_norm+1e-8)))

        costheta_intp = interpolate_nonmatching_mesh(costheta_loc,
                                                     ref_spaces["psi"])

        costheta.vector()[:] += costheta_intp.vector().get_local() / Ntss

    dump_xdmf(costheta)

    if args.show:
        JET = plt.get_cmap('jet')
        RYB = plt.get_cmap('RdYlBu')
        RYB_r = plt.get_cmap('RdYlBu_r')
        mgm = plt.get_cmap('magma')
        fig, ax = plt.subplots()
        fig.set_size_inches(4.7, 4.7)
        rc('text', usetex=True)
        rc('font', **{'family': 'serif', 'serif': ['Palatino']})
        # First, dump a hires PNG version of the data:
        plot = df.plot(costheta, cmap=mgm)
        plt.axis('off')
        plt.savefig('anglogram_hires.png',
                    format="png",
                    bbox_inches='tight',
                    pad_inches=0,
                    dpi=500)
        mainfs = 10  # Fontsize
        titlefs = 12  # Fontsize
        #plt.set_cmap('jet')
        #cbar = fig.colorbar(plot, ticks=[0, 0.5, 1], orientation='vertical')
        #cbar.ax.set_yticklabels(['Radial', 'Intermediate', 'Azimuthal'])
        #cbar = fig.colorbar(plot, ticks=[0, 0.5, 0.95], orientation='horizontal', fraction=0.046, pad=0.04)
        #cbar = fig.colorbar(plot, ticks=[0, 0.5, 0.995], orientation='horizontal', fraction=0.046, pad=0.04)
        cbar = fig.colorbar(plot,
                            ticks=[0, 0.5, 0.9995],
                            orientation='horizontal',
                            fraction=0.046,
                            pad=0.04)
        cbar.ax.set_xticklabels(['Radial', 'Intermediate', 'Azimuthal'])
        #ax.set_title('Stripe orientation -- $\\cos^2(\\theta)$', fontsize=mainfs)
        #ax.set_title(r'Stripe orientation -- $\cos^2(\theta)$')
        plt.text(0.5,
                 1.05,
                 r'Stripe orientation -- $\left\vert\cos(\theta)\right\vert$',
                 fontsize=titlefs,
                 horizontalalignment='center',
                 transform=ax.transAxes)
        #ax.set_title('Stripe orientation', fontsize=mainfs)
        #plt.text(0.2, 0.2, '$\\textcolor{red}{\\mathbf{p}(u,w,\\xi)}=\\textcolor{blue}{\\tilde{\\mathbf{p}}(u,w)}  + \\xi \\tilde{\\mathbf{n}}(u,w)$', fontsize=mainfs)
        ax.get_xaxis().set_visible(False)
        ax.get_yaxis().set_visible(False)
        #plt.show()
        plt.savefig('anglogram.pdf',
                    format="pdf",
                    bbox_inches='tight',
                    pad_inches=0)
        #plt.axis('on')
        #ax.get_xaxis().set_visible(True)
        #ax.get_yaxis().set_visible(True)
        #plt.colorbar(plot)
        #plt.show()

    if args.radius is not None and args.radius > 0:
        Nr, Nphi = 256, 256
        r_lin = np.linspace(0., args.radius, Nr)
        phi_lin = np.linspace(0, 2 * np.pi, Nphi, endpoint=False)
        R, Phi = np.meshgrid(r_lin, phi_lin)
        r = R.reshape((Nr * Nphi, 1))
        phi = Phi.reshape((Nr * Nphi, 1))

        xy = np.hstack((r * np.cos(phi), r * np.sin(phi)))

        pts = xy.flatten()
        probes = Probes(pts, ref_spaces["psi"])
        probes(costheta)

        ct = probes.array()
        CT = ct.reshape(R.shape)

        g_r = CT.mean(axis=0)
        g_phi = CT.mean(axis=1)

        plt.figure()
        plt.plot(r_lin, g_r)
        plt.ylabel("g(r)")
        plt.xlabel("r")

        plt.figure()
        plt.plot(phi_lin, g_phi)
        plt.xlabel("phi")
        plt.ylabel("g(phi)")
        plt.show()
    def _setup_problem(self):
        """
        Method setting up solver objects of the stationary problem.
        """
        assert hasattr(self, "_mesh")
        assert hasattr(self, "_boundary_markers")

        self._setup_function_spaces()
        self._setup_boundary_conditions()

        # creating test function
        self._v = dlfn.TestFunction(self._Vh)
        self._u = dlfn.TrialFunction(self._Vh)

        # solution
        self._solution = dlfn.Function(self._Vh)

        # volume element
        self._dV = dlfn.Measure("dx", domain=self._mesh)
        self._dA = dlfn.Measure("ds",
                                domain=self._mesh,
                                subdomain_data=self._boundary_markers)

        # setup the parameters for the elastic law
        self._elastic_law.set_parameters(self._mesh, self._C)

        # virtual work
        if self._elastic_law.linearity_type == "Linear":
            self._dw_int = self._elastic_law.dw_int(self._u,
                                                    self._v) * self._dV
        elif self._elastic_law.linearity_type == "Nonlinear":
            self._dw_int = self._elastic_law.dw_int(self._solution,
                                                    self._v) * self._dV

        # virtual work of external forces
        self._dw_ext = dlfn.dot(self._null_vector, self._v) * self._dV

        # add body force term
        if hasattr(self, "_body_force"):
            assert hasattr(self, "_D"), "Dimensionless parameter related to" + \
                                        "the body forces is not specified."
            self._dw_ext += self._D * dot(self._body_force, self._v) * self._dV

        # add boundary tractions
        if hasattr(self, "_traction_bcs"):
            for bc in self._traction_bcs:
                # unpack values
                if len(bc) == 3:
                    bc_type, bndry_id, traction = bc
                elif len(bc) == 4:
                    bc_type, bndry_id, component_index, traction = bc

                if bc_type is TractionBCType.constant:
                    assert isinstance(traction, (tuple, list))
                    const_function = dlfn.Constant(traction)
                    self._dw_ext += dot(const_function,
                                        self._v) * self._dA(bndry_id)

                elif bc_type is TractionBCType.constant_component:
                    assert isinstance(traction, float)
                    const_function = dlfn.Constant(traction)
                    self._dw_ext += const_function * self._v[
                        component_index] * self._dA(bndry_id)

                elif bc_type is TractionBCType.function:
                    assert isinstance(traction, dlfn.Expression)
                    self._dw_ext += dot(traction, self._v) * self._dA(bndry_id)

                elif bc_type is TractionBCType.function_component:
                    assert isinstance(traction, dlfn.Expression)
                    self._dw_ext += traction * self._v[
                        component_index] * self._dA(bndry_id)

        if self._elastic_law.linearity_type == "Linear":
            # linear variational problem
            self._problem = dlfn.LinearVariationalProblem(
                self._dw_int, self._dw_ext, self._solution,
                self._dirichlet_bcs)
            # setup linear variational solver
            self._solver = dlfn.LinearVariationalSolver(self._problem)
        elif self._elastic_law.linearity_type == "Nonlinear":
            self._Form = self._dw_int - self._dw_ext
            self._J_newton = dlfn.derivative(self._Form, self._solution)
            self._problem = dlfn.NonlinearVariationalProblem(
                self._Form,
                self._solution,
                self._dirichlet_bcs,
                J=self._J_newton)
            # setup linear variational solver
            self._solver = dlfn.NonlinearVariationalSolver(self._problem)
Beispiel #20
0
def solver(interval, dt=0.1, theta=1):
    t0, t1 = interval

    mesh = get_mesh(10)
    cell_function = get_cell_function(mesh)
    model = get_models(cell_function)
    num_global_states = model.num_states()

    # Create time keepers and time step
    const_dt = df.Constant(dt)
    current_time = df.Constant(0)
    t = t0 + theta*(t1 - t0)
    current_time.assign(t)

    # Create stimulus
    stimulus = df.Constant(0)

    # Make shared function pace
    mixed_vector_function_space = df.VectorFunctionSpace(
        mesh,
        "DG",
        0,
        dim=num_global_states + 1
    )

    # Create previous solution and assign initial conditions
    previous_solution = df.Function(mixed_vector_function_space)

    # _model = xb.cellmodels.Cressman()
    # previous_solution.assign(_model.initial_conditions())        # Initial condition
    previous_solution.assign(model.initial_conditions())        # Initial condition

    v_previous, s_previous = splat(previous_solution, num_global_states + 1)

    # Create current solution
    current_solution = df.Function(mixed_vector_function_space)
    v_current, s_current = splat(current_solution, num_global_states + 1)

    # Create test functions
    test_functions = df.TestFunction(mixed_vector_function_space)
    test_v, test_s = splat(test_functions, num_global_states + 1)

    # Crate time derivatives
    Dt_v = (v_current - v_previous)/const_dt
    Dt_s = (s_current - s_previous)/const_dt

    # Create midpoint evaluations following theta rule
    v_mid = theta*v_current + (1.0 - theta)*v_previous
    s_mid = theta*s_current + (1.0 - theta)*s_previous

    if isinstance(model, xb.MultiCellModel):
        # model = xb.cellmodels.Cressman()
        # dy = df.Measure("dx", domain=mesh)
        # F_theta = model.F(v_mid, s_mid, time=current_time)
        # I_theta = -model.I(v_mid, s_mid, time=current_time)
        # lhs = (Dt_v - I_theta)*test_v
        # lhs += df.inner(Dt_s - F_theta, test_s)
        # lhs *= dy()



        dy = df.Measure("dx", domain=mesh, subdomain_data=model.markers())
        domain_indices = model.keys()
        lhs_list = list()
        for k, model_k in enumerate(model.models()):
            domain_index_k = domain_indices[k]
            F_theta = model.F(v_mid, s_mid, time=current_time, index=domain_index_k)
            I_theta = -model.I(v_mid, s_mid, time=current_time, index=domain_index_k)
            a = (Dt_v - I_theta)*test_v
            a += df.inner(Dt_s - F_theta, test_s)
            a *= dy(domain_index_k)
            lhs_list.append(a)
        # Sum the form
        lhs = sum(lhs_list)
    else:
        # Evaluate currents at averaged v and s. Note sign for I_theta
        model = xb.cellmodels.Cressman()
        dy = df.Measure("dx", domain=mesh)
        F_theta = model.F(v_mid, s_mid, time=current_time)
        I_theta = -model.I(v_mid, s_mid, time=current_time)
        lhs = (Dt_v - I_theta)*test_v
        lhs += df.inner(Dt_s - F_theta, test_s)
        lhs *= dy()
    rhs = stimulus*test_v*dy()
    G = lhs - rhs

    # Solve system
    current_solution.assign(previous_solution)
    pde = df.NonlinearVariationalProblem(
        G,
        current_solution,
        J=df.derivative(G, current_solution)
    )
    solver = df.NonlinearVariationalSolver(pde)
    solver.solve()
Beispiel #21
0
    parRandom.normal(1., noise)
    # use the same noise across processors
    if rank == 0:
        noise_array = noise.get_local()
    else:
        noise_array = None
    noise_array = comm.bcast(noise_array, root=0)
    noise.set_local(noise_array)

    mtrue = dl.Vector()
    prior.init_vector(mtrue, 0)
    prior.sample(noise, mtrue)

    if rank == 0:
        filename = 'data/particle_true.xdmf'
        particle_fun = dl.Function(Vh[PARAMETER], name='particle')
        particle_fun.vector().axpy(1.0, mtrue)
        if dlversion() <= (1, 6, 0):
            dl.File(mesh.mpi_comm(), filename) << particle_fun
        else:
            xf = dl.XDMFFile(mesh.mpi_comm(), filename)
            xf.write(particle_fun)

    utrue = pde.generate_state()
    x = [utrue, mtrue, None]
    pde.solveFwd(x[STATE], x, 1e-9)
    misfit.B.mult(x[STATE], misfit.d)
    rel_noise = 0.01
    MAX = misfit.d.norm("linf")
    noise_std_dev = rel_noise * MAX
    parRandom.normal_perturb(noise_std_dev, misfit.d)
Beispiel #22
0
def get_residual_form(u,
                      v,
                      rho_e,
                      V_density,
                      tractionBC,
                      T,
                      iteration_number,
                      additive='strain',
                      k=8.,
                      method='RAMP'):

    df.dx = df.dx(metadata={"quadrature_degree": 4})
    # stiffness = rho_e/(1 + 8. * (1. - rho_e))

    if method == 'SIMP':
        stiffness = rho_e**3
    else:
        stiffness = rho_e / (1 + 8. * (1. - rho_e))

    # print('the value of stiffness is:', rho_e.vector().get_local())
    # Kinematics
    d = len(u)
    I = df.Identity(d)  # Identity tensor
    F = I + df.grad(u)  # Deformation gradient
    C = F.T * F  # Right Cauchy-Green tensor
    # Invariants of deformation tensors
    Ic = df.tr(C)
    J = df.det(F)
    stiffen_pow = 1.
    threshold_vol = 1.

    eps_star = 0.05
    # print("eps_star--------")

    if additive == 'strain':
        print("additive == strain")

        if iteration_number == 1:
            print('iteration_number == 1')
            eps = df.sym(df.grad(u))
            eps_dev = eps - 1 / 3 * df.tr(eps) * df.Identity(2)
            eps_eq = df.sqrt(2.0 / 3.0 * df.inner(eps_dev, eps_dev))
            # eps_eq_proj = df.project(eps_eq, density_function_space)
            ratio = eps_eq / eps_star
            ratio_proj = df.project(ratio, V_density)

            c1_e = k * (5.e-2) / (1 + 8. * (1. - (5.e-2))) / 6

            c2_e = df.Function(V_density)
            c2_e.vector().set_local(5e-4 * np.ones(V_density.dim()))

            fFile = df.HDF5File(df.MPI.comm_world, "c2_e_proj.h5", "w")
            fFile.write(c2_e, "/f")
            fFile.close()

            fFile = df.HDF5File(df.MPI.comm_world, "ratio_proj.h5", "w")
            fFile.write(ratio_proj, "/f")
            fFile.close()
            iteration_number += 1
            E = k * stiffness
            phi_add = (1 - stiffness) * ((c1_e * (Ic - 3)) + (c2_e *
                                                              (Ic - 3))**2)

        else:
            ratio_proj = df.Function(V_density)
            fFile = df.HDF5File(df.MPI.comm_world, "ratio_proj.h5", "r")
            fFile.read(ratio_proj, "/f")
            fFile.close()

            c2_e = df.Function(V_density)
            fFile = df.HDF5File(df.MPI.comm_world, "c2_e_proj.h5", "r")
            fFile.read(c2_e, "/f")
            fFile.close()
            c1_e = k * (5.e-2) / (1 + 8. * (1. - (5.e-2))) / 6

            c2_e = df.conditional(df.le(ratio_proj, eps_star),
                                  c2_e * df.sqrt(ratio_proj),
                                  c2_e * (ratio_proj**3))
            phi_add = (1 - stiffness) * ((c1_e * (Ic - 3)) + (c2_e *
                                                              (Ic - 3))**2)
            E = k * stiffness

            c2_e_proj = df.project(c2_e, V_density)
            print('c2_e projected -------------')

            eps = df.sym(df.grad(u))
            eps_dev = eps - 1 / 3 * df.tr(eps) * df.Identity(2)
            eps_eq = df.sqrt(2.0 / 3.0 * df.inner(eps_dev, eps_dev))
            # eps_eq_proj = df.project(eps_eq, V_density)
            ratio = eps_eq / eps_star
            ratio_proj = df.project(ratio, V_density)

            fFile = df.HDF5File(df.MPI.comm_world, "c2_e_proj.h5", "w")
            fFile.write(c2_e_proj, "/f")
            fFile.close()

            fFile = df.HDF5File(df.MPI.comm_world, "ratio_proj.h5", "w")
            fFile.write(ratio_proj, "/f")
            fFile.close()

    elif additive == 'vol':
        print("additive == vol")
        stiffness = stiffness / (df.det(F)**stiffen_pow)

        # stiffness = df.conditional(df.le(df.det(F),threshold_vol), (stiffness/(df.det(F)/threshold_vol))**stiffen_pow, stiffness)
        E = k * stiffness

    elif additive == 'False':
        print("additive == False")
        E = k * stiffness  # rho_e is the design variable, its values is from 0 to 1

    nu = 0.4  # Poisson's ratio

    lambda_ = E * nu / (1. + nu) / (1 - 2 * nu)
    mu = E / 2 / (1 + nu)  #lame's parameters

    # Stored strain energy density (compressible neo-Hookean model)
    psi = (mu / 2) * (Ic - 3) - mu * df.ln(J) + (lambda_ / 2) * (df.ln(J))**2
    # print('the length of psi is:',len(psi.vector()))
    if additive == 'strain':
        psi += phi_add
    B = df.Constant((0.0, 0.0))

    # Total potential energy
    '''The first term in this equation provided this error'''
    Pi = psi * df.dx - df.dot(B, u) * df.dx - df.dot(T, u) * tractionBC

    res = df.derivative(Pi, u, v)

    return res
Beispiel #23
0
def ii_derivative(f, x):
    '''DOLFIN's derivative df/dx extended to handle trace stuff'''
    test_f = is_okay_functional(f)

    # FIXME: for now don't allow diffing wrt compound expressions, in particular
    # restricted args.
    assert isinstance(x, ufl.Coefficient) and not is_restricted(x)

    # So now we have L(arg, v) where arg = (u, ..., T[u], Pi[u], ...) and the idea
    # is to define derivative w.r.t to x by doing
    # J = sum_{arg} (partial L / partial arg){arg=T[u]}(partial arg / partial x).
    J = 0
    # NOTE: in the following I try to avoid assembly of zero forms because
    # these might not be well-defined for xii assembler. Also, assembling
    # zeros is useless
    for fi in [c for c in f.coefficients() if not isinstance(c, df.Constant)]:
        # Short circuit if (partial fi)/(partial x) is 0
        if not ((fi == x) or fi.vector().id() == x.vector().id()): continue

        if is_restricted(fi):
            rtype = restriction_type(fi)
            attributes = (rtype, )
        else:
            rtype = ''
            attributes = None
        fi_sub = df.Function(fi.function_space())

        # To recreate the form for partial we sub in every integral of f
        sub_form_integrals = []
        for integral in f.integrals():

            integrand = ii_replace(integral.integrand(), fi, fi_sub,
                                   attributes)
            # If the substitution is do nothing then there's no need to diff
            if integrand != integral.integrand():
                sub_form_integrals.append(
                    integral.reconstruct(integrand=integrand))
        sub_form = ufl.Form(sub_form_integrals)

        # Partial wrt to substituated argument
        df_dfi = df.derivative(sub_form, fi_sub)

        # Substitue back the original form argument
        sub_form_integrals = []
        for integral in df_dfi.integrals():
            integrand = ii_replace(integral.integrand(), fi_sub, fi)
            assert integrand != integral.integrand()
            sub_form_integrals.append(
                integral.reconstruct(integrand=integrand))
        df_dfi = ufl.Form(sub_form_integrals)

        # As d Tu / dx = T(x) we now need to restrict the trial function
        if rtype:
            trial_f = get_trialfunction(df_dfi)
            setattr(trial_f, rtype, getattr(fi, rtype))
        # Since we only allos diff wrt to coef then in the case rtype == ''
        # we have dfi/dx = 1

        J += df_dfi
    # Done
    return J
Beispiel #24
0
    dl.File("results/poisson_parameter_prmean.pvd") << vector2Function(
        prior.mean, Vh[PARAMETER], name=xxname[PARAMETER])
    dl.File("results/poisson_adjoint.pvd") << xx[ADJOINT]

    exportPointwiseObservation(Vh[STATE], misfit.B, misfit.d,
                               "results/poisson_observation")

    if rank == 0:
        print(sep, "Generate samples from Prior and Posterior\n",
              "Export generalized Eigenpairs", sep)
    fid_prior = dl.File("samples/sample_prior.pvd")
    fid_post = dl.File("samples/sample_post.pvd")
    nsamples = 500
    noise = dl.Vector()
    posterior.init_vector(noise, "noise")
    s_prior = dl.Function(Vh[PARAMETER], name="sample_prior")
    s_post = dl.Function(Vh[PARAMETER], name="sample_post")
    for i in range(nsamples):
        parRandom.normal(1., noise)
        posterior.sample(noise, s_prior.vector(), s_post.vector())
        fid_prior << s_prior
        fid_post << s_post

    #Save eigenvalues for printing:

    U.export(Vh[PARAMETER],
             "hmisfit/evect.pvd",
             varname="gen_evects",
             normalize=True)
    if rank == 0:
        np.savetxt("hmisfit/eigevalues.dat", d)
    def assemble(self, form, arity):
        '''Assemble a biliner(2), linear(1) form'''
        reduced_integrals = self.select_integrals(form)  #! Selector
        # Signal to xii.assemble
        if not reduced_integrals: return None

        components = []
        for integral in form.integrals():
            # Delegate to friend
            if integral not in reduced_integrals:
                components.append(
                    xii.assembler.xii_assembly.assemble(Form([integral])))
                continue

            reduced_mesh = integral.ufl_domain().ufl_cargo()

            integrand = integral.integrand()
            # Split arguments in those that need to be and those that are
            # already restricted.
            terminals = set(traverse_unique_terminals(integrand))

            # FIXME: is it enough info (in general) to decide
            terminals_to_restrict = self.restriction_filter(
                terminals, reduced_mesh)
            # You said this is a trace ingral!
            assert terminals_to_restrict

            # Let's pick a guy for restriction
            terminal = terminals_to_restrict.pop()
            # We have some assumption on the candidate
            assert self.is_compatible(terminal, reduced_mesh)

            data = self.reduction_matrix_data(terminal)

            integrand = ufl2uflcopy(integrand)
            # With sane inputs we can get the reduced element and setup the
            # intermediate function space where the reduction of terminal
            # lives
            V = terminal.function_space()
            TV = self.reduced_space(V, reduced_mesh)  #! Space construc

            # Setup the matrix to from space of the trace_terminal to the
            # intermediate space. FIXME: normal and trace_mesh
            #! mat construct
            df.info('\tGetting reduction op')
            rop_timer = df.Timer('rop')
            T = self.reduction_matrix(V, TV, reduced_mesh, data)
            df.info('\tDone (reduction op) %g' % rop_timer.stop())
            # T
            if is_test_function(terminal):
                replacement = df.TestFunction(TV)
                # Passing the args to get the comparison a make substitution
                integrand = replace(integrand,
                                    terminal,
                                    replacement,
                                    attributes=self.attributes)
                trace_form = Form([integral.reconstruct(integrand=integrand)])

                if arity == 2:
                    # Make attempt on the substituted form
                    A = xii.assembler.xii_assembly.assemble(trace_form)
                    components.append(block_transpose(T) * A)
                else:
                    b = xii.assembler.xii_assembly.assemble(trace_form)
                    Tb = df.Function(V).vector()  # Alloc and apply
                    T.transpmult(b, Tb)
                    components.append(Tb)

            if is_trial_function(terminal):
                assert arity == 2
                replacement = df.TrialFunction(TV)
                # Passing the args to get the comparison
                integrand = replace(integrand,
                                    terminal,
                                    replacement,
                                    attributes=self.attributes)
                trace_form = Form([integral.reconstruct(integrand=integrand)])

                A = xii.assembler.xii_assembly.assemble(trace_form)
                components.append(A * T)

            # Okay, then this guy might be a function
            if isinstance(terminal, df.Function):
                replacement = df.Function(TV)
                # Replacement is not just a placeholder
                T.mult(terminal.vector(), replacement.vector())
                # Substitute
                integrand = replace(integrand,
                                    terminal,
                                    replacement,
                                    attributes=self.attributes)
                trace_form = Form([integral.reconstruct(integrand=integrand)])
                components.append(
                    xii.assembler.xii_assembly.assemble(trace_form))

        # The whole form is then the sum of integrals
        return reduce(operator.add, components)
tau = df.Constant(parameters["tau"])
h = df.Constant(parameters["h"])
M = df.Constant(parameters["M"])

geo_map = TorusMap(R, r)
geo_map.initialize(res, restart_folder=parameters["restart_folder"])

W = geo_map.mixed_space((geo_map.ref_el, ) * 4)

# Define trial and test functions
du = df.TrialFunction(W)
chi, xi, eta, etahat = df.TestFunctions(W)

# Define functions
u = df.TrialFunction(W)
u_ = df.Function(W, name="u_")  # current solution
u_1 = df.Function(W, name="u_1")  # solution from previous converged step

# Split mixed functions
psi, mu, nu, nuhat = df.split(u)
psi_, mu_, nu_, nuhat_ = df.split(u_)
psi_1, mu_1, nu_1, nuhat_1 = df.split(u_1)

# Create intial conditions
if parameters["restart_folder"] is None:
    init_mode = parameters["init_mode"]
    if init_mode == "random":
        u_init = RandomIC(u_, degree=1)
    elif init_mode == "striped":
        u_init = StripedIC(u_,
                           alpha=parameters["alpha"] * np.pi / 180.0,
Beispiel #27
0
def scalar_laplacians(mesh):
    """
    Calculate the laplacians needed by fiberrule algorithms
    
    Arguments
    ---------
    mesh : dolfin.Mesh
       A dolfin mesh with marked boundaries:
       base = 10, rv = 20, lv = 30, epi = 40
       The base is assumed placed at x=0
    
    """

    if not isinstance(mesh, d.Mesh):
        raise TypeError("Expected a dolfin.Mesh as the mesh argument.")

    # Init connectivities
    mesh.init(2)
    facet_markers = d.MeshFunction("size_t", mesh, 2, mesh.domains())

    # Boundary markers, solutions and cases
    markers = dict(base=10, rv=20, lv=30, epi=40, apex=50)

    # Solver parameters
    solver_param=dict(solver_parameters=dict(
        preconditioner="ml_amg" if d.has_krylov_solver_preconditioner("ml_amg") \
        else "default", linear_solver="gmres"))

    cases = ["rv", "lv", "epi"]
    boundaries = cases + ["base"]

    # Check that all boundary faces are marked
    num_boundary_facets = d.BoundaryMesh(mesh, "exterior").num_cells()

    if num_boundary_facets != sum(np.sum(\
        facet_markers.array()==markers[boundary])\
                                  for boundary in boundaries):
        d.error("Not all boundary faces are marked correctly. Make sure all "\
                "boundary facets are marked as: base = 10, rv = 20, lv = 30, "\
                "epi = 40.")

    # Coords and cells
    coords = mesh.coordinates()
    cells_info = mesh.cells()

    # Find apex by solving a laplacian with base solution = 0
    # Create Base variational problem
    V = d.FunctionSpace(mesh, "CG", 1)

    u = d.TrialFunction(V)
    v = d.TestFunction(V)

    a = d.dot(d.grad(u), d.grad(v)) * d.dx
    L = v * d.Constant(1) * d.dx

    DBC_10 = d.DirichletBC(V, 1, facet_markers, markers["base"], "topological")

    # Create solutions
    solutions = dict(
        (what, d.Function(V)) for what in markers if what != "base")

    d.solve(a == L,
            solutions["apex"],
            DBC_10,
            solver_parameters={"linear_solver": "gmres"})

    apex_values = solutions["apex"].vector().array()
    apex_values[d.dof_to_vertex_map(V)] = solutions["apex"].vector().array()
    ind_apex_max = apex_values.argmax()
    apex_coord = coords[ind_apex_max, :]

    # Update rhs
    L = v * d.Constant(0) * d.dx

    d.info("  Apex coord: ({0}, {1}, {2})".format(*apex_coord))
    d.info("  Num coords: {0}".format(len(coords)))
    d.info("  Num cells: {0}".format(len(cells_info)))

    # Calculate volume
    volume = 0.0
    for cell in d.cells(mesh):
        volume += cell.volume()

    d.info("  Volume: {0}".format(volume))
    d.info("")

    # Cases
    # =====
    #
    # 1) base: 1, apex: 0
    # 2) lv: 1, rv, epi: 0
    # 3) rv: 1, lv, epi: 0
    # 4) epi: 1, rv, lv: 0

    class ApexDomain(d.SubDomain):
        def inside(self, x, on_boundary):
            return d.near(x[0], apex_coord[0]) and d.near(x[1], apex_coord[1]) and \
                   d.near(x[2], apex_coord[2])

    apex_domain = ApexDomain()

    # Case 1:
    Poisson = 1
    DBC_11 = d.DirichletBC(V, 0, apex_domain, "pointwise")

    # Using Poisson
    if Poisson:
        d.solve(a == L,
                solutions["apex"], [DBC_10, DBC_11],
                solver_parameters={"linear_solver": "gmres"})

    # Using Eikonal equation
    else:
        Le = v * d.Constant(1) * d.dx
        d.solve(a == Le,
                solutions["apex"],
                DBC_11,
                solver_parameters={"linear_solver": "gmres"})

        # Create Eikonal problem
        eps = d.Constant(mesh.hmax() / 25)
        y = solutions["apex"]
        F = d.sqrt(d.inner(d.grad(y), d.grad(y)))*v*d.dx - \
            d.Constant(1)*v*d.dx + eps*d.inner(d.grad(y), d.grad(v))*d.dx
        d.solve(F == 0,
                y,
                DBC_11,
                solver_parameters={
                    "linear_solver": "lu",
                    "newton_solver": {
                        "relative_tolerance": 1e-5
                    }
                })

    # Check that solution of the three last cases all sum to 1.
    sol = solutions["apex"].vector().copy()
    sol[:] = 0.0

    # Iterate over the three different cases
    for case in cases:

        # Solve linear system
        bcs = [d.DirichletBC(V, 1 if what == case else 0, \
                             facet_markers, markers[what], "topological") \
               for what in cases]
                def solve(selfmat, var, b):
                    if selfmat.adjoint:
                        operators = transpose_operators(selfmat.operators)
                    else:
                        operators = selfmat.operators

                    # Fetch/construct the solver
                    if var.type in ['ADJ_FORWARD', 'ADJ_TLM']:
                        solver = krylov_solvers[idx]
                        need_to_set_operator = self._need_to_reset_operator
                    else:
                        if adj_krylov_solvers[idx] is None:
                            need_to_set_operator = True
                            adj_krylov_solvers[idx] = KrylovSolver(
                                *solver_parameters)
                        else:
                            need_to_set_operator = self._need_to_reset_operator
                        solver = adj_krylov_solvers[idx]
                    solver.parameters.update(parameters)
                    self._need_to_reset_operator = False

                    if selfmat.adjoint:
                        (nsp_, tnsp_) = (tnsp, nsp)
                    else:
                        (nsp_, tnsp_) = (nsp, tnsp)

                    x = dolfin.Function(fn_space)
                    if selfmat.initial_guess is not None and var.type == 'ADJ_FORWARD':
                        x.vector()[:] = selfmat.initial_guess.vector()

                    if b.data is None:
                        dolfin.info_red(
                            "Warning: got zero RHS for the solve associated with variable %s"
                            % var)
                        return adjlinalg.Vector(x)

                    if var.type in ['ADJ_TLM', 'ADJ_ADJOINT']:
                        selfmat.bcs = [
                            utils.homogenize(bc) for bc in selfmat.bcs
                            if isinstance(bc, dolfin.cpp.DirichletBC)
                        ] + [
                            bc for bc in selfmat.bcs
                            if not isinstance(bc, dolfin.cpp.DirichletBC)
                        ]

                    # This is really hideous. Sorry.
                    if isinstance(b.data, dolfin.Function):
                        rhs = b.data.vector().copy()
                        [bc.apply(rhs) for bc in selfmat.bcs]

                        if need_to_set_operator:
                            if assemble_system:  # if we called assemble_system, rather than assemble
                                v = dolfin.TestFunction(fn_space)
                                (A, rhstmp) = dolfin.assemble_system(
                                    operators[0],
                                    dolfin.inner(b.data, v) * dolfin.dx,
                                    selfmat.bcs)
                                if has_preconditioner:
                                    (P, rhstmp) = dolfin.assemble_system(
                                        operators[1],
                                        dolfin.inner(b.data, v) * dolfin.dx,
                                        selfmat.bcs)
                                    solver.set_operators(A, P)
                                else:
                                    solver.set_operator(A)
                            else:  # we called assemble
                                A = dolfin.assemble(operators[0])
                                [bc.apply(A) for bc in selfmat.bcs]
                                if has_preconditioner:
                                    P = dolfin.assemble(operators[1])
                                    [bc.apply(P) for bc in selfmat.bcs]
                                    solver.set_operators(A, P)
                                else:
                                    solver.set_operator(A)
                    else:

                        if assemble_system:  # if we called assemble_system, rather than assemble
                            (A, rhs) = dolfin.assemble_system(
                                operators[0], b.data, selfmat.bcs)
                            if need_to_set_operator:
                                if has_preconditioner:
                                    (P, rhstmp) = dolfin.assemble_system(
                                        operators[1], b.data, selfmat.bcs)
                                    solver.set_operators(A, P)
                                else:
                                    solver.set_operator(A)
                        else:  # we called assemble
                            A = dolfin.assemble(operators[0])
                            rhs = dolfin.assemble(b.data)
                            [bc.apply(A) for bc in selfmat.bcs]
                            [bc.apply(rhs) for bc in selfmat.bcs]
                            if need_to_set_operator:
                                if has_preconditioner:
                                    P = dolfin.assemble(operators[1])
                                    [bc.apply(P) for bc in selfmat.bcs]
                                    solver.set_operators(A, P)
                                else:
                                    solver.set_operator(A)

                    # Set the nullspace for the linear operator
                    if nsp_ is not None and need_to_set_operator:
                        dolfin.as_backend_type(A).set_nullspace(nsp_)

                    # (Possibly override the user in) orthogonalize
                    # the right-hand-side
                    if tnsp_ is not None:
                        tnsp_.orthogonalize(rhs)

                    solver.solve(x.vector(), rhs)
                    return adjlinalg.Vector(x)
Beispiel #29
0
def test_assembly_ds_domains(mesh):
    V = dolfin.FunctionSpace(mesh, ("CG", 1))
    u, v = dolfin.TrialFunction(V), dolfin.TestFunction(V)

    marker = dolfin.MeshFunction("size_t", mesh, mesh.topology.dim - 1, 0)

    def bottom(x):
        return numpy.isclose(x[:, 1], 0.0)

    def top(x):
        return numpy.isclose(x[:, 1], 1.0)

    def left(x):
        return numpy.isclose(x[:, 0], 0.0)

    def right(x):
        return numpy.isclose(x[:, 0], 1.0)

    marker.mark(bottom, 111)
    marker.mark(top, 222)
    marker.mark(left, 333)
    marker.mark(right, 444)

    ds = ufl.Measure('ds', subdomain_data=marker, domain=mesh)

    w = dolfin.Function(V)
    with w.vector.localForm() as w_local:
        w_local.set(0.5)

    #
    # Assemble matrix
    #

    a = w * ufl.inner(u, v) * (ds(111) + ds(222) + ds(333) + ds(444))

    A = dolfin.fem.assemble_matrix(a)
    A.assemble()
    norm1 = A.norm()

    a2 = w * ufl.inner(u, v) * ds

    A2 = dolfin.fem.assemble_matrix(a2)
    A2.assemble()
    norm2 = A2.norm()

    assert norm1 == pytest.approx(norm2, 1.0e-12)

    #
    # Assemble vector
    #

    L = ufl.inner(w, v) * (ds(111) + ds(222) + ds(333) + ds(444))
    b = dolfin.fem.assemble_vector(L)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)

    L2 = ufl.inner(w, v) * ds
    b2 = dolfin.fem.assemble_vector(L2)
    b2.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)

    assert b.norm() == pytest.approx(b2.norm(), 1.0e-12)

    #
    # Assemble scalar
    #

    L = w * (ds(111) + ds(222) + ds(333) + ds(444))
    s = dolfin.fem.assemble_scalar(L)
    s = dolfin.MPI.sum(mesh.mpi_comm(), s)

    L2 = w * ds
    s2 = dolfin.fem.assemble_scalar(L2)
    s2 = dolfin.MPI.sum(mesh.mpi_comm(), s2)

    assert (s == pytest.approx(s2, 1.0e-12)
            and 2.0 == pytest.approx(s, 1.0e-12))
Beispiel #30
0
    def __init__(self, problem_params, dtype_u, dtype_f):
        """
        Initialization routine

        Args:
            problem_params (dict): custom parameters for the example
            dtype_u: particle data type (will be passed parent class)
            dtype_f: acceleration data type (will be passed parent class)
        """

        # Sub domain for Periodic boundary condition
        class PeriodicBoundary(df.SubDomain):

            # Left boundary is "target domain" G
            def inside(self, x, on_boundary):
                return bool(df.DOLFIN_EPS > x[0] > -df.DOLFIN_EPS
                            and on_boundary)

            # Map right boundary (H) to left boundary (G)
            def map(self, x, y):
                y[0] = x[0] - 1.0

        # these parameters will be used later, so assert their existence
        essential_keys = [
            'c_nvars', 't0', 'family', 'order', 'refinements', 'nu', 'freq'
        ]
        for key in essential_keys:
            if key not in problem_params:
                msg = 'need %s to instantiate problem, only got %s' % (
                    key, str(problem_params.keys()))
                raise ParameterError(msg)

        # set logger level for FFC and dolfin
        df.set_log_level(df.WARNING)
        logging.getLogger('FFC').setLevel(logging.WARNING)

        # set solver and form parameters
        df.parameters["form_compiler"]["optimize"] = True
        df.parameters["form_compiler"]["cpp_optimize"] = True

        # set mesh and refinement (for multilevel)
        mesh = df.UnitIntervalMesh(self.params.c_nvars)
        for i in range(self.refinements):
            mesh = df.refine(mesh)

        # define function space for future reference
        self.V = df.FunctionSpace(mesh,
                                  self.params.family,
                                  self.params.order,
                                  constrained_domain=PeriodicBoundary())
        tmp = df.Function(self.V)
        print('DoFs on this level:', len(tmp.vector().array()))

        # invoke super init, passing number of dofs, dtype_u and dtype_f
        super(fenics_adv_diff_1d, self).__init__(self.V, dtype_u, dtype_f,
                                                 problem_params)

        u = df.TrialFunction(self.V)
        v = df.TestFunction(self.V)

        # Stiffness term (diffusion)
        a_K = -1.0 * df.inner(df.nabla_grad(u),
                              self.params.nu * df.nabla_grad(v)) * df.dx

        # Stiffness term (advection)
        a_G = df.inner(self.params.mu * df.nabla_grad(u)[0], v) * df.dx

        # Mass term
        a_M = u * v * df.dx

        self.M = df.assemble(a_M)
        self.K = df.assemble(a_K)
        self.G = df.assemble(a_G)