示例#1
0
    def assemble_lumpedmm(self):
        """ Assembly lumped mass matrix - equal to 0 on robin boundary since
            there is no time derivative there.
        """
        print("Assembling lumped mass matrix")
        mass_form = self.w * self.u * dx
        mass_action_form = action(mass_form, Constant(1))
        self.MM_terms = assemble(mass_action_form)

        for n in self.robint_nodes_list:
            self.MM_terms[n] = 1.0
        for n in self.robin_nodes_list:
            self.MM_terms[n] = 0.0

        self.mass_matrix = assemble(mass_form)
        self.mass_matrix.zero()
        self.mass_matrix.set_diagonal(self.MM_terms)
        self.scipy_mass_matrix = toscipy(self.mass_matrix)
示例#2
0
def test_multi_ps_matrix_node_vector_fs(mesh):
    """Tests point source applied to a matrix with given constructor
    PointSource(V, source) and a vector function space when points
    placed at 3 vertices for 1D, 2D and 3D. Global points given to
    constructor from rank 0 processor.

    """

    point = [0.0, 0.5, 1.0]
    rank = MPI.rank(mesh.mpi_comm())
    V = VectorFunctionSpace(mesh, "CG", 1, dim=2)
    u, v = TrialFunction(V), TestFunction(V)
    w = Function(V)
    A = assemble(Constant(0.0) * dot(u, v) * dx)
    dim = mesh.geometry().dim()

    source = []
    point_coords = np.zeros(dim)
    for p in point:
        for i in range(dim):
            point_coords[i - 1] = p
        if rank == 0:
            source.append((Point(point_coords), 10.0))
    ps = PointSource(V, source)
    ps.apply(A)

    # Checks array sums to correct value
    A.get_diagonal(w.vector())
    a_sum = MPI.sum(mesh.mpi_comm(), np.sum(A.array()))
    assert round(a_sum - 2 * len(point) * 10) == 0

    # Check if coordinates are in portion of mesh and if so check that
    # diagonal components sum to the correct value.
    mesh_coords = V.tabulate_dof_coordinates()
    for p in point:
        for i in range(dim):
            point_coords[i] = p

        j = 0
        for i in range(len(mesh_coords) // (dim)):
            mesh_coords_check = mesh_coords[j:j + dim - 1]
            if np.array_equal(point_coords, mesh_coords_check) is True:
                assert np.round(w.vector()[j // (dim)] - 10.0) == 0.0
            j += dim
示例#3
0
def test_stationary_solve(show=False):

    problem = problems.Crucible()

    boundaries = problem.wp_boundaries

    average_temp = 1551.0

    material = problem.subdomain_materials[problem.wpi]
    rho = material.density(average_temp)
    cp = material.specific_heat_capacity
    kappa = material.thermal_conductivity

    my_ds = Measure("ds")(subdomain_data=boundaries)

    convection = None
    heat = maelstrom.heat.Heat(
        problem.Q,
        kappa,
        rho,
        cp,
        convection,
        source=Constant(0.0),
        dirichlet_bcs=problem.theta_bcs_d,
        neumann_bcs=problem.theta_bcs_n,
        robin_bcs=problem.theta_bcs_r,
        my_dx=dx,
        my_ds=my_ds,
    )
    theta_reference = heat.solve_stationary()
    theta_reference.rename("theta", "temperature")

    if show:
        # with XDMFFile('temperature.xdmf') as f:
        #     f.parameters['flush_output'] = True
        #     f.parameters['rewrite_function_mesh'] = False
        #     f.write(theta_reference)
        tri = plot(theta_reference)
        plt.colorbar(tri)
        plt.show()

    assert abs(maelstrom.helpers.average(theta_reference) - 1551.0) < 1.0e-1

    return theta_reference
    def __init__(self, Vm, parameters=[]):
        """ Vm = FunctionSpace for the parameters m1, and m2 """
        self.parameters = {}
        self.parameters['k'] = 1.0
        self.parameters['eps'] = 1e-2
        self.parameters['rescaledradiusdual'] = 1.0
        self.parameters['print'] = False
        self.parameters['amg'] = 'default'
        self.parameters['nb_param'] = 2
        self.parameters['use_i'] = False
        self.parameters.update(parameters)

        n = self.parameters['nb_param']
        use_i = self.parameters['use_i']
        assert ((not use_i) * (n > 2))

        Vw = FunctionSpace(Vm.mesh(), 'DG', 0)
        if not use_i:
            VmVm = createMixedFS(Vm, Vm)
            VwVw = createMixedFS(Vw, Vw)
        else:
            if self.parameters['print']:
                print '[V_TVPD] Using createMixedFSi'
            Vms, Vws = [], []
            for ii in range(n):
                Vms.append(Vm)
                Vws.append(Vw)
            VmVm = createMixedFSi(Vms)
            VwVw = createMixedFSi(Vws)
        self.parameters['Vm'] = VmVm
        self.parameters['Vw'] = VwVw

        self.regTV = TVPD(self.parameters)

        if not use_i:
            self.m1, self.m2 = Function(Vm), Function(Vm)
            self.m = Function(VmVm)

        self.w_loc = Function(VwVw)
        self.factorw = Function(Vw)
        self.factorww = Function(VwVw)

        tmp = interpolate(Constant("1.0"), Vw)
        self.one = tmp.vector()
    def updateCoefficients(self):

        x, y = SpatialCoordinate(self.mesh)

        # Init coefficient matrix
        self.a = as_matrix([[Constant(1.), Constant(0.)],
                            [Constant(0.), Constant(2.)]])

        self.b = as_vector([Constant(0.2), Constant(-0.1)])
        self.c = Constant(0.1)

        self.u_ = 0.5 * (self.t**2 + 1) * sin(2 * x * pi) * sin(2 * y * pi)

        self.u_T = ufl.replace(self.u_, {self.t: self.T[1]})

        # Init right-hand side
        self.f = self.t * sin(2*pi*x) * sin(2*pi*y) \
            + inner(self.a, grad(grad(self.u_))) \
            + inner(self.b, grad(self.u_)) \
            + self.c * self.u_
        self.g = Constant(0.0)
 def __init__(self):
     self.T = [0, 3]
     self.t = Constant(self.T[1])
     # self.T = [0, 0.1]
     # self.alpha = 0.1
     self.alpha = 2.38
     # self.r = 0.0
     self.r = 0.1
     self.sigma = 0.59
     self.pmin = 0.0
     self.pmax = 12.0
     self.Imin = 0.0
     self.Imax = 2000
     self.K0 = 6
     self.k1 = 2040.41
     self.k2 = 730000
     self.k3 = 500
     self.k4 = 2500
     self.k5 = 1.7 * 365
示例#7
0
    def scalar_force( self, field ):     
        r"""
        Returns the magnitude of the scalar force associated to the input field, per unit mass (units :math:`M_p`):
        
        .. math :: F_{\varphi} = \frac{\nabla\varphi}{M_P}
        
        if :math:`\varphi` is the input field.
        
        *Arguments*
        field
            the field associated to the scalar force
        
        """

        grad = self.grad( field, 'physical' )
        force = - grad / Constant(self.fields.Mp)
        force = project( force, self.fem.dS, self.fem.func_degree )
        
        return force
示例#8
0
def fluid_setup(v_, p_, n, psi, gamma, dx, mu_f, rho_f, k, dt, theta,
                **semimp_namespace):

    F_fluid_linear = rho_f/k*inner(v_["n"] - v_["n-1"], psi)*dx \
           + Constant(theta)*inner(sigma_f(p_["n"], v_["n"], mu_f), grad(psi))*dx \
     + Constant(1 - theta)*inner(sigma_f(p_["n-1"], v_["n-1"], mu_f), grad(psi))*dx \
           + Constant(theta)*inner(div(v_["n"]), gamma)*dx \
     + Constant(1 -theta)*inner(div(v_["n-1"]), gamma)*dx

    F_fluid_nonlinear = Constant(theta)*rho_f*inner(dot(grad(v_["n"]), v_["n"]), psi)*dx \
    + Constant(1 - theta)*rho_f*inner(dot(grad(v_["n-1"]), v_["n-1"]), psi)*dx

    return dict(F_fluid_linear=F_fluid_linear,
                F_fluid_nonlinear=F_fluid_nonlinear)
示例#9
0
def test_compute_point_values(mesh_factory):
    from numpy import all

    func, args = mesh_factory
    mesh = func(*args)

    e0 = Constant(1)
    e1 = Constant((1, 2, 3))

    e0_values = e0.compute_point_values(mesh)
    e1_values = e1.compute_point_values(mesh)

    assert all(e0_values == 1)
    assert all(e1_values == [1, 2, 3])
示例#10
0
def F(u, p, v, q, f, r, mu, my_dx):
    mu = Constant(mu)
    # Momentum equation (without the nonlinear Navier term).
    F0 = (mu * inner(r * grad(u), grad(v)) * 2 * pi * my_dx +
          mu * u[0] / r * v[0] * 2 * pi * my_dx -
          dot(f, v) * 2 * pi * r * my_dx)
    if len(u) == 3:
        F0 += mu * u[2] / r * v[2] * 2 * pi * my_dx
    F0 += (p.dx(0) * v[0] + p.dx(1) * v[1]) * 2 * pi * r * my_dx

    # Incompressibility condition.
    # div_u = 1/r * div(r*u)
    F0 += ((r * u[0]).dx(0) + r * u[1].dx(1)) * q * 2 * pi * my_dx

    # a = mu * inner(r * grad(u), grad(v)) * 2*pi * my_dx \
    #     - ((r * v[0]).dx(0) + (r * v[1]).dx(1)) * p * 2*pi * my_dx \
    #     + ((r * u[0]).dx(0) + (r * u[1]).dx(1)) * q * 2*pi * my_dx
    # #   - div(r*v)*p* 2*pi*my_dx \
    # #   + q*div(r*u)* 2*pi*my_dx
    return F0
示例#11
0
    def forms_theta_nlinear(self, v0, Ubar0, dt, theta_map=Constant(1.0),
                            theta_L=Constant(1.0), duh0=Constant((0., 0.)), duh00=Constant((0., 0)),
                            h=Constant((0., 0.)), neumann_idx=99):

        # Define trial test functions
        (v, lamb, vbar) = self.__trial_functions()
        (w, tau, wbar) = self.__test_functions()

        (zero_vec, h, duh0, duh00) = self.__check_geometric_dimension(h, duh0, duh00)

        beta_map = self.beta_map
        n = self.n
        facet_integral = self.facet_integral

        # Define v_star
        v_star = v0 + (1-theta_L) * duh00 + theta_L * duh0

        Udiv = v0 + duh0
        outer_v_a = outer(w, Udiv)
        outer_v_a_o = outer(v_star, Udiv)
        outer_ubar_a = outer(vbar, Ubar0)

        # Switch to detect in/outflow boundary
        gamma = conditional(ge(dot(Udiv, n), 0), 0, 1)

        # LHS contribution s
        N_a = facet_integral(beta_map*dot(v, w))
        G_a = dot(lamb, w)/dt * dx - theta_map*inner(outer_v_a, grad(lamb))*dx \
            + theta_map * (1-gamma) * dot(outer_v_a * n,
                                          lamb) * self.ds(neumann_idx)

        L_a = -facet_integral(beta_map * dot(vbar, w))
        H_a = facet_integral(dot(outer_ubar_a*n, tau)) \
            - dot(outer_ubar_a*n, tau) * self.ds(neumann_idx)
        B_a = facet_integral(beta_map * dot(vbar, wbar))

        # RHS contributions
        Q_a = dot(Constant(zero_vec), w) * dx
        R_a = dot(v_star, tau)/dt * dx \
            + (1-theta_map)*inner(outer_v_a_o, grad(tau))*dx \
            - gamma * dot(h, tau) * self.ds(neumann_idx)
        S_a = facet_integral(dot(Constant(zero_vec), wbar))

        return self.__fem_forms(N_a, G_a, L_a, H_a, B_a, Q_a, R_a, S_a)
示例#12
0
 def __init__(self,
              mesh,
              FuncSpaces_L,
              FuncSpaces_G,
              alpha,
              h_d=[
                  Expression(('0.0', '0.0'), degree=3),
                  Expression(('0.0', '0.0'), degree=3)
              ],
              beta_stab=Constant(0.),
              ds=ds):
     self.mixedL = FuncSpaces_L
     self.mixedG = FuncSpaces_G
     self.n = FacetNormal(mesh)
     self.beta_stab = beta_stab
     self.alpha = alpha
     self.he = CellDiameter(mesh)
     self.h_d = h_d
     self.ds = ds
     self.gdim = mesh.geometry().dim()
    def __init__(
            self,
            state,
            E0,
            ell,
            sigma_D0,
            k_ell=Constant(1.0e-8),
            user_functional=None,
    ):

        self.u = state[0]
        self.alpha = state[1]
        self.E0 = E0
        self.ell = ell
        self.sigma_D0 = sigma_D0
        self.k_ell = k_ell
        self.mu_0 = self.mu(0)
        assert state[0].function_space().ufl_element().value_size() == 1
        self.dim = state[0].function_space().ufl_element().value_size()
        self.user_functional = user_functional
示例#14
0
        def test_ale(self):

            print ""
            print "Testing ALE::move(Mesh& mesh0, const Mesh& mesh1)"

            # Create some mesh
            mesh = UnitSquareMesh(4, 5)

            # Make some cell function
            # FIXME: Initialization by array indexing is probably
            #        not a good way for parallel test
            cellfunc = CellFunction('size_t', mesh)
            cellfunc.array()[0:4] = 0
            cellfunc.array()[4:] = 1

            # Create submeshes - this does not work in parallel
            submesh0 = SubMesh(mesh, cellfunc, 0)
            submesh1 = SubMesh(mesh, cellfunc, 1)

            # Move submesh0
            disp = Constant(("0.1", "-0.1"))
            submesh0.move(disp)

            # Move and smooth submesh1 accordignly
            submesh1.move(submesh0)

            # Move mesh accordingly
            parent_vertex_indices_0 = \
                     submesh0.data().array('parent_vertex_indices', 0)
            parent_vertex_indices_1 = \
                     submesh1.data().array('parent_vertex_indices', 0)
            mesh.coordinates()[parent_vertex_indices_0[:]] = \
                     submesh0.coordinates()[:]
            mesh.coordinates()[parent_vertex_indices_1[:]] = \
                     submesh1.coordinates()[:]

            # If test passes here then it is probably working
            # Check for cell quality for sure
            magic_number = 0.28
            rmin = MeshQuality.radius_ratio_min_max(mesh)[0]
            self.assertTrue(rmin > magic_number)
示例#15
0
def test_multi_ps_vector_node_local(mesh):
    """Tests point source when given constructor PointSource(V, V, point,
    mag) with a matrix when points placed at 3 node for 1D, 2D and
    3D. Local points given to constructor.

    """

    V = FunctionSpace(mesh, "CG", 1)
    v = TestFunction(V)
    b = assemble(Constant(0.0) * v * dx)

    source = []
    point_coords = mesh.coordinates()[0]
    source.append((Point(point_coords), 10.0))
    ps = PointSource(V, source)
    ps.apply(b)

    # Checks b sums to correct value
    size = MPI.size(mesh.mpi_comm())
    b_sum = b.sum()
    assert round(b_sum - size * 10.0) == 0
    def updateCoefficients(self):
        # Init coefficient matrix
        x, y = SpatialCoordinate(self.mesh)

        self.a = self.gamma[0] * \
            as_matrix([[1.0, 0.0], [0.0, 1.0]])
        self.b = as_vector([Constant(1.0), Constant(1.0)])
        self.c = Constant(0.0)

        # Init right-hand side
        self.f = -Constant(1.0)

        self.u_T = Constant(0.0)

        # Set boundary conditions
        self.g = Constant(0.0)
示例#17
0
def test_multi_ps_vector_node(mesh):
    """Tests point source when given constructor PointSource(V, V, point,
    mag) with a matrix when points placed at 3 node for 1D, 2D and
    3D. Global points given to constructor from rank 0 processor.

    """

    point = [0.0, 0.5, 1.0]
    dim = mesh.geometry().dim()
    rank = MPI.rank(mesh.mpi_comm())
    V = FunctionSpace(mesh, "CG", 1)
    v = TestFunction(V)
    b = assemble(Constant(0.0) * v * dx)

    source = []
    point_coords = np.zeros(dim)
    for p in point:
        for i in range(dim):
            point_coords[i - 1] = p
        if rank == 0:
            source.append((Point(point_coords), 10.0))
    ps = PointSource(V, source)
    ps.apply(b)

    # Checks b sums to correct value
    b_sum = b.sum()
    assert round(b_sum - len(point) * 10.0) == 0

    # Checks values added to correct part of vector
    mesh_coords = V.tabulate_dof_coordinates()
    for p in point:
        for i in range(dim):
            point_coords[i] = p

        j = 0
        for i in range(len(mesh_coords) // (dim)):
            mesh_coords_check = mesh_coords[j:j + dim - 1]
            if np.array_equal(point_coords, mesh_coords_check) is True:
                assert np.round(b.array()[j // (dim)] - 10.0) == 0.0
            j += dim
    def __init__(
            self,
            state,
            E0,
            nu,
            ell,
            sigma_D0,
            k_res=Constant(1.0e-8),
            user_functional=None,
    ):

        self.u = state['u']
        self.alpha = state['alpha']
        self.E0 = E0
        self.nu = nu
        self.ell = ell
        self.sigma_D0 = sigma_D0
        self.k_res = k_res
        self.lmbda_0 = self.lmbda3D(0)
        self.mu_0 = self.mu3D(0)
        self.dim = self.u.function_space().ufl_element().value_size()
        self.user_functional = user_functional
示例#19
0
    def __init__(self, energy, state, bcs=None):
        """
        Initialises the damage problem.

        Arguments:
            * energy
            * state
            * boundary conditions
        """
        NonlinearProblem.__init__(self)
        self.type = "snes"
        self.bcs = bcs
        self.state = state
        alpha = state["alpha"]
        V = alpha.function_space()
        alpha_v = TestFunction(V)
        dalpha = TrialFunction(V)
        self.energy = energy
        self.F = derivative(energy, alpha, alpha_v)
        self.J = derivative(self.F, alpha, dalpha)
        self.lb = alpha.copy(True).vector()
        self.ub = interpolate(Constant(1.), V).vector()
示例#20
0
 def adaptive(self, mesh, eigv, eigf):
     """Refine mesh based on residual errors."""
     fraction = 0.1
     C = FunctionSpace(mesh, "DG", 0)  # constants on triangles
     w = TestFunction(C)
     h = CellSize(mesh)
     n = FacetNormal(mesh)
     marker = CellFunction("bool", mesh)
     print len(marker)
     indicators = np.zeros(len(marker))
     for e, u in zip(eigv, eigf):
         errform = avg(h) * jump(grad(u), n) ** 2 * avg(w) * dS \
             + h * (inner(grad(u), n) - Constant(e) * u) ** 2 * w * ds
         if self.degree > 1:
             errform += h**2 * div(grad(u))**2 * w * dx
         indicators[:] += assemble(errform).array()  # errors for each cell
     print "Residual error: ", sqrt(sum(indicators) / len(eigv))
     cutoff = sorted(indicators,
                     reverse=True)[int(len(indicators) * fraction) - 1]
     marker.array()[:] = indicators > cutoff  # mark worst errors
     mesh = refine(mesh, marker)
     return mesh
示例#21
0
def make_smoothing_solver(V, kappa=None):
    '''
    Important
    ---------
    * Smoothing is most effective when the sensitivities are defined over
      the whole domain. In practice, this is rarely the case.
    * Smoothing works well enough when the sensitivities are defined over
      a subdomain but that is the same dimension as the mesh. In such a case,
      the smoothing will be relatively poor on the boundary of the subdomain.
    * Smoothing does not work well when the sensitivities are defined over a
      boundary of the domain. More generally, when the sensitivity domain
      is lower dimension than the mesh. In this case, this type of smoothing
      is quite useless.

    Returns
    -------
    smoothing_solver:
        Returns the solver that solves the smoothing problem that is the linear
        system `M x_smoothed = x` where `x` is the vector of unsmoothed values.
        The smoothing solver can be invoked as `smoothing_solver.solve(x, x)`.

    '''

    v0 = dolfin.TestFunction(V)
    v1 = dolfin.TrialFunction(V)

    a = dot(v1,v0)*dolfin.dx

    if kappa is not None and float(kappa) != 0.0:

        if isinstance(kappa, (float, int)):
            kappa = Constant(kappa)

        a += kappa*inner(grad(v1), grad(v0))*dolfin.dx

    smoothing_solver = dolfin.LUSolver(assemble(a), "mumps")
    smoothing_solver.parameters["symmetric"] = True

    return smoothing_solver
示例#22
0
def problem_sinsin():
    """cosine example.
    """
    def mesh_generator(n):
        return UnitSquareMesh(n, n, "left/right")

    x = sympy.DeferredVector("x")

    # Choose the solution such that the boundary conditions are fulfilled
    # exactly. Also, multiply with x**2 to make sure that the right-hand side
    # doesn't contain the term 1/x. Although it looks like a singularity at
    # x=0, this terms is esentially harmless since the volume element 2*pi*x is
    # used throughout the code, canceling out with the 1/x. However, Dolfin has
    # problems with this, cf.
    # <https://bitbucket.org/fenics-project/dolfin/issues/831/some-problems-with-quadrature-expressions>.
    solution = {
        "value": x[0]**2 * sympy.sin(pi * x[0]) * sympy.sin(pi * x[1]),
        "degree": MAX_DEGREE,
    }

    # Produce a matching right-hand side.
    phi = solution["value"]
    kappa = 2.0
    rho = 3.0
    cp = 5.0
    conv = [1.0, 2.0]
    rhs_sympy = sympy.simplify(
        -1.0 / x[0] * sympy.diff(kappa * x[0] * sympy.diff(phi, x[0]), x[0]) -
        1.0 / x[0] * sympy.diff(kappa * x[0] * sympy.diff(phi, x[1]), x[1]) +
        rho * cp * conv[0] * sympy.diff(phi, x[0]) +
        rho * cp * conv[1] * sympy.diff(phi, x[1]))

    rhs = {
        "value": Expression(helpers.ccode(rhs_sympy), degree=MAX_DEGREE),
        "degree": MAX_DEGREE,
    }

    return mesh_generator, solution, rhs, triangle, kappa, rho, cp, Constant(
        conv)
示例#23
0
def Fluid_tentative_variation(v_, p_, d_, dvp_, w, w_f, v_tilde_n1, \
psi, beta, gamma, dx_f, mu_f, rho_f, k, dt, **semimp_namespace):

	d_tent = dvp_["tilde"].sub(0, deepcopy=True)
	d_n = dvp_["tilde"].sub(0, deepcopy=True)
	d_n1 = dvp_["n-1"].sub(0, deepcopy=True)

	v_n1   = dvp_["n-1"].sub(1, deepcopy=True)


	#Reuse of TrialFunction w, TestFunction beta
	#used in extrapolation assuming same degree

	F_tentative = rho_f/k*J_(d_tent)*inner(w - v_n1, beta)*dx_f
	F_tentative += rho_f*inner(J_(d_tent)*grad(w)*inv(F_(d_tent)) \
             	* (v_tilde_n1 - 1./k*(d_n - d_n1)), beta)*dx_f

	F_tentative += J_(d_tent)*inner(mu_f*D_U(d_tent, w), D_U(d_tent, beta))*dx_f

	F_tentative -= inner(Constant((0, 0)), beta)*dx_f

	return dict(F_tentative=F_tentative)
示例#24
0
    def compute(self, get):
        u = get("Velocity")
        mu = get("DynamicViscosity")
        if isinstance(mu, (float, int)):
            mu = Constant(mu)

        n = self._n
        T = -mu * dot((grad(u) + grad(u).T), n)
        Tn = dot(T, n)
        Tt = T - Tn * n

        tau_form = dot(self.v, Tt) * ds()
        assemble(tau_form, tensor=self.tau.vector())

        #self.b[self._keys] = self.tau.vector()[self._values] # FIXME: This is not safe!!!
        get_set_vector(self.b, self._keys, self.tau.vector(), self._values,
                       self._temp_array)

        # Ensure proper scaling
        self.solver.solve(self.tau_boundary.vector(), self.b)

        return self.tau_boundary
示例#25
0
def main(solver, N: int, dt: float, T: float,
         theta: float) -> Tuple[float, float, float, float, float]:
    # Create cardiac model
    mesh = UnitSquareMesh(N, N)
    time = Constant(0.0)
    cell_model = NoCellModel()

    ac_str = "cos(t)*cos(2*pi*x[0])*cos(2*pi*x[1]) + 4*pow(pi, 2)*cos(2*pi*x[0])*cos(2*pi*x[1])*sin(t)"
    stimulus = Expression(ac_str, t=time, degree=5)

    ps = solver.default_parameters()
    ps["Chi"] = 1.0
    ps["Cm"] = 1.0
    _solver = solver(mesh, time, 1.0, 1.0, stimulus, parameters=ps)

    # Define exact solution (Note: v is returned at end of time
    # interval(s), u is computed at somewhere in the time interval
    # depending on theta)

    v_exact = Expression("cos(2*pi*x[0])*cos(2*pi*x[1])*sin(t)", t=T, degree=5)
    u_exact = Expression("-cos(2*pi*x[0])*cos(2*pi*x[1])*sin(t)/2.0",
                         t=T - (1 - theta) * dt,
                         degree=5)

    # Define initial condition(s)
    vs0 = Function(_solver.V)
    vs_, *_ = _solver.solution_fields()
    vs_.assign(vs0)

    # Solve
    for _, (vs_, vur) in _solver.solve(0, T, dt):
        continue

    # Compute errors
    v, u, *_ = vur.split(deepcopy=True)
    v_error = errornorm(v_exact, v, "L2", degree_rise=5)
    u_error = errornorm(u_exact, u, "L2", degree_rise=5)
    return v_error, u_error, mesh.hmin(), dt, T
示例#26
0
    def solve(self):
        """
        Solves the stokes equation with the current multimesh
        """
        (u, p) = TrialFunctions(self.VQ)
        (v, q) = TestFunctions(self.VQ)
        n = FacetNormal(self.multimesh)
        h = 2.0 * Circumradius(self.multimesh)
        alpha = Constant(6.0)

        tensor_jump = lambda u: outer(u("+"), n("+")) + outer(u("-"), n("-"))

        a_s = inner(grad(u), grad(v)) * dX
        a_IP = - inner(avg(grad(u)), tensor_jump(v))*dI\
               - inner(avg(grad(v)), tensor_jump(u))*dI\
               + alpha/avg(h) * inner(jump(u), jump(v))*dI
        a_O = inner(jump(grad(u)), jump(grad(v))) * dO

        b_s = -div(u) * q * dX - div(v) * p * dX
        b_IP = jump(u, n) * avg(q) * dI + jump(v, n) * avg(p) * dI
        l_s = inner(self.f, v) * dX

        s_C = h*h*inner(-div(grad(u)) + grad(p), -div(grad(v)) - grad(q))*dC\
              + h("+")*h("+")*inner(-div(grad(u("+"))) + grad(p("+")),
                                    -div(grad(v("+"))) + grad(q("+")))*dO
        l_C = h*h*inner(self.f, -div(grad(v)) - grad(q))*dC\
              + h("+")*h("+")*inner(self.f("+"),
                                    -div(grad(v("+"))) - grad(q("+")))*dO

        a = a_s + a_IP + a_O + b_s + b_IP + s_C
        l = l_s + l_C

        A = assemble_multimesh(a)
        L = assemble_multimesh(l)
        [bc.apply(A, L) for bc in self.bcs]
        self.VQ.lock_inactive_dofs(A, L)
        solve(A, self.w.vector(), L, "mumps")
        self.splitMMF()
    def __getattr__(self, attr):
        if attr in self._cache:
            return self._cache[attr]

        materials = {}
        for domain, material in self._materials.items():
            ids = self._state.domain_ids(domain)
            for id in ids:
                if materials.has_key(id):
                    materials[id] = Material(materials[id], material)
                else:
                    materials[id] = material

        # scalar or vector parameter
        V = None
        expr = None
        if len(self._materials) == 0:
            self._cache[attr] = Constant(getattr(self._base_material, attr))
        else:
            for material in [self._base_material] + self._materials.values():
                try:
                    value = getattr(material, attr)
                    if isinstance(value, tuple) or isinstance(value, list):
                        assert len(value) == 3
                        V = VectorFunctionSpace(self._state.mesh, 'DG', 0)
                        expr = VectorCellExpr(attr, self._state.cell_domains,
                                              self._base_material, materials)
                    else:
                        V = FunctionSpace(self._state.mesh, 'DG', 0)
                        expr = CellExpr(attr, self._state.cell_domains,
                                        self._base_material, materials)
                    break
                except AttributeError:
                    continue

            self._cache[attr] = interpolate(expr, V)

        return self._cache[attr]
示例#28
0
def test_multi_ps_matrix_node_local(mesh):
    """Tests point source when given constructor PointSource(V, V, point,
    mag) with a matrix when points placed at 3 node for 1D, 2D and
    3D. Local points given to constructor.

    """

    V = FunctionSpace(mesh, "CG", 1)
    u, v = TrialFunction(V), TestFunction(V)
    w = Function(V)
    A = assemble(Constant(0.0) * u * v * dx)

    source = []
    point_coords = mesh.coordinates()[0]
    source.append((Point(point_coords), 10.0))
    ps = PointSource(V, source)
    ps.apply(A)

    # Checks matrix sums to correct value.
    A.get_diagonal(w.vector())
    size = MPI.size(mesh.mpi_comm())
    a_sum = MPI.sum(mesh.mpi_comm(), np.sum(A.array()))
    assert round(a_sum - size * 10.0) == 0
示例#29
0
def test_pointsource_vector(mesh):
    """Tests point source when given constructor PointSource(V, point,
    mag) with a vector that isn't placed at a node for 1D, 2D and
    3D. Global points given to constructor from rank 0 processor

    """

    cell = Cell(mesh, 0)
    point = cell.midpoint()
    rank = MPI.rank(mesh.mpi_comm())

    V = FunctionSpace(mesh, "CG", 1)
    v = TestFunction(V)
    b = assemble(Constant(0.0) * v * dx)
    if rank == 0:
        ps = PointSource(V, point, 10.0)
    else:
        ps = PointSource(V, [])
    ps.apply(b)

    # Checks array sums to correct value
    b_sum = b.sum()
    assert round(b_sum - 10.0) == 0
    def __init__(self, domain):
        rho, mu, dt, g = domain.rho, domain.mu, domain.dt, domain.g
        u, u_1, p_1, vu = domain.u, domain.u_1, domain.p_1, domain.vu

        n = FacetNormal(domain.mesh)
        acceleration = rho * inner((u - u_1) / dt, vu) * dx
        diffusion = (-inner(mu * (grad(u_1) + grad(u_1).T), grad(vu)) * dx +
                     dot(mu * (grad(u_1) + grad(u_1).T) * n, vu) * ds)
        body_force = dot(g*rho, vu)*dx \
            + dot(Constant((0.0, 0.0)), vu) * ds
        # diffusion = (mu*inner(grad(u_1), grad(vu))*dx
        #              - mu*dot(nabla_grad(u_1)*n, vu)*ds)  # int. by parts
        pressure = inner(p_1, div(vu)) * dx - dot(p_1 * n,
                                                  vu) * ds  # int. by parts
        # TODO: what is better?
        # convection = dot(div(rho*outer(u_1, u_1)), vu) * dx  # not stable!
        convection = rho * dot(dot(u_1, nabla_grad(u_1)), vu) * dx
        F_impl = -acceleration - convection + diffusion + pressure + body_force
        self.a, self.L = lhs(F_impl), rhs(F_impl)
        self.domain = domain
        self.A = assemble(self.a)
        [bc.apply(self.A) for bc in domain.bcu]
        return
示例#31
0
def test_estimator_refinement():
    # define source term
    f = Constant("1.0")
    #    f = Expression("10.*exp(-(pow(x[0] - 0.6, 2) + pow(x[1] - 0.4, 2)) / 0.02)", degree=3)

    # set default vector for new indices
    mesh0 = refine(Mesh(lshape_xml))
    fs0 = FunctionSpace(mesh0, "CG", 1)
    B = FEniCSBasis(fs0)
    u0 = Function(fs0)
    diffcoeff = Constant("1.0")
    pde = FEMPoisson()
    fem_A = pde.assemble_lhs(diffcoeff, B)
    fem_b = pde.assemble_rhs(f, B)
    solve(fem_A, u0.vector(), fem_b)
    vec0 = FEniCSVector(u0)

    # setup solution multi vector
    mis = [Multiindex([0]),
           Multiindex([1]),
           Multiindex([0, 1]),
           Multiindex([0, 2])]
    N = len(mis)

    #    meshes = [UnitSquare(i + 3, 3 + N - i) for i in range(N)]
    meshes = [refine(Mesh(lshape_xml)) for _ in range(N)]
    fss = [FunctionSpace(mesh, "CG", 1) for mesh in meshes]

    # solve Poisson problem
    w = MultiVectorWithProjection()
    for i, mi in enumerate(mis):
        B = FEniCSBasis(fss[i])
        u = Function(fss[i])
        pde = FEMPoisson()
        fem_A = pde.assemble_lhs(diffcoeff, B)
        fem_b = pde.assemble_rhs(f, B)
        solve(fem_A, u.vector(), fem_b)
        w[mi] = FEniCSVector(u)
        #        plot(w[mi]._fefunc)

    # define coefficient field
    a0 = Expression("1.0", element=FiniteElement('Lagrange', ufl.triangle, 1))
    #    a = [Expression('2.+sin(2.*pi*I*x[0]+x[1]) + 10.*exp(-pow(I*(x[0] - 0.6)*(x[1] - 0.3), 2) / 0.02)', I=i, degree=3,
    a = (Expression('A*cos(pi*I*x[0])*cos(pi*I*x[1])', A=1 / i ** 2, I=i, degree=2,
        element=FiniteElement('Lagrange', ufl.triangle, 1)) for i in count())
    rvs = (NormalRV(mu=0.5) for _ in count())
    coeff_field = ParametricCoefficientField(a, rvs, a0=a0)

    # refinement loop
    # ===============
    refinements = 3

    for refinement in range(refinements):
        print "*****************************"
        print "REFINEMENT LOOP iteration ", refinement + 1
        print "*****************************"

        # evaluate residual and projection error estimates
        # ================================================
        maxh = 1 / 10
        resind, reserr = ResidualEstimator.evaluateResidualEstimator(w, coeff_field, f)
        projind, projerr = ResidualEstimator.evaluateProjectionError(w, coeff_field, maxh)

        # testing -->
        projglobal, _ = ResidualEstimator.evaluateProjectionError(w, coeff_field, maxh, local=False)
        for mu, val in projglobal.iteritems():
            print "GLOBAL Projection Error for", mu, "=", val
            # <-- testing

        # ==============
        # MARK algorithm
        # ==============

        # setup marking sets
        mesh_markers = defaultdict(set)

        # residual marking
        # ================
        theta_eta = 0.8
        global_res = sum([res[1] for res in reserr.items()])
        allresind = list()
        for mu, resmu in resind.iteritems():
            allresind = allresind + [(resmu.coeffs[i], i, mu) for i in range(len(resmu.coeffs))]
        allresind = sorted(allresind, key=itemgetter(1))
        # TODO: check that indexing and cell ids are consistent (it would be safer to always work with cell indices) 
        marked_res = 0
        for res in allresind:
            if marked_res >= theta_eta * global_res:
                break
            mesh_markers[res[2]].add(res[1])
            marked_res += res[0]

        print "RES MARKED elements:\n", [(mu, len(cell_ids)) for mu, cell_ids in mesh_markers.iteritems()]

        # projection marking
        # ==================
        theta_zeta = 0.8
        min_zeta = 1e-10
        max_zeta = max([max(projind[mu].coeffs) for mu in projind.active_indices()])
        print "max_zeta =", max_zeta
        if max_zeta >= min_zeta:
            for mu, vec in projind.iteritems():
                indmu = [i for i, p in enumerate(vec.coeffs) if p >= theta_zeta * max_zeta]
                mesh_markers[mu] = mesh_markers[mu].union(set(indmu))
                print "PROJ MARKING", len(indmu), "elements in", mu

            print "FINAL MARKED elements:\n", [(mu, len(cell_ids)) for mu, cell_ids in mesh_markers.iteritems()]
        else:
            print "NO PROJECTION MARKING due to very small projection error!"

        # new multiindex activation
        # =========================
        # determine possible new indices
        theta_delta = 0.9
        maxm = 10
        a0_f = coeff_field.mean_func
        Ldelta = {}
        Delta = w.active_indices()
        deltaN = int(ceil(0.1 * len(Delta)))               # max number new multiindices
        for mu in Delta:
            norm_w = norm(w[mu].coeffs, 'L2')
            for m in count():
                mu1 = mu.inc(m)
                if mu1 not in Delta:
                    if m > maxm or m >= coeff_field.length:  # or len(Ldelta) >= deltaN
                        break
                    am_f, am_rv = coeff_field[m]
                    beta = am_rv.orth_polys.get_beta(1)
                    # determine ||a_m/\overline{a}||_{L\infty(D)} (approximately)
                    f = Function(w[mu]._fefunc.function_space())
                    f.interpolate(a0_f)
                    min_a0 = min(f.vector().array())
                    f.interpolate(am_f)
                    max_am = max(f.vector().array())
                    ainfty = max_am / min_a0
                    assert isinstance(ainfty, float)

                    #                    print "A***", beta[1], ainfty, norm_w
                    #                    print "B***", beta[1] * ainfty * norm_w
                    #                    print "C***", theta_delta, max_zeta
                    #                    print "D***", theta_delta * max_zeta
                    #                    print "E***", bool(beta[1] * ainfty * norm_w >= theta_delta * max_zeta)

                    if beta[1] * ainfty * norm_w >= theta_delta * max_zeta:
                        val1 = beta[1] * ainfty * norm_w
                        if mu1 not in Ldelta.keys() or (mu1 in Ldelta.keys() and Ldelta[mu1] < val1):
                            Ldelta[mu1] = val1

        print "POSSIBLE NEW MULTIINDICES ", sorted(Ldelta.iteritems(), key=itemgetter(1), reverse=True)
        Ldelta = sorted(Ldelta.iteritems(), key=itemgetter(1), reverse=True)[:min(len(Ldelta), deltaN)]
        # add new multiindices to solution vector
        for mu, _ in Ldelta:
            w[mu] = vec0
        print "SELECTED NEW MULTIINDICES ", Ldelta

        # create new refined (and enlarged) multi vector
        # ==============================================
        for mu, cell_ids in mesh_markers.iteritems():
            vec = w[mu].refine(cell_ids, with_prolongation=False)
            fs = vec._fefunc.function_space()
            B = FEniCSBasis(fs)
            u = Function(fs)
            pde = FEMPoisson()
            fem_A = pde.assemble_lhs(diffcoeff, B)
            fem_b = pde.assemble_rhs(f, B)
            solve(fem_A, vec.coeffs, fem_b)
            w[mu] = vec
示例#32
0
def test_time_step():
    problem = problems.Crucible()

    boundaries = problem.wp_boundaries

    # The melting point of GaAs is 1511 K.
    average_temp = 1520.0

    f = Constant(0.0)

    material = problem.subdomain_materials[problem.wpi]
    rho = material.density(average_temp)
    cp = material.specific_heat_capacity
    kappa = material.thermal_conductivity

    my_ds = Measure("ds")(subdomain_data=boundaries)

    # from dolfin import DirichletBC
    convection = None
    heat = maelstrom.heat.Heat(
        problem.Q,
        kappa,
        rho,
        cp,
        convection,
        source=Constant(0.0),
        dirichlet_bcs=problem.theta_bcs_d,
        neumann_bcs=problem.theta_bcs_n,
        robin_bcs=problem.theta_bcs_r,
        my_dx=dx,
        my_ds=my_ds,
    )

    # create time stepper
    # stepper = parabolic.ExplicitEuler(heat)
    stepper = parabolic.ImplicitEuler(heat)
    # stepper = parabolic.Trapezoidal(heat)

    theta0 = project(Constant(average_temp), problem.Q)
    # theta0 = heat.solve_stationary()
    theta0.rename("theta0", "temperature")

    theta1 = Function(problem.Q)
    theta1 = Function(problem.Q)

    t = 0.0
    dt = 1.0e-3
    end_time = 10 * dt

    with XDMFFile("temperature.xdmf") as f:
        f.parameters["flush_output"] = True
        f.parameters["rewrite_function_mesh"] = False

        f.write(theta0, t)
        while t < end_time:
            theta1.assign(stepper.step(theta0, t, dt))
            theta0.assign(theta1)
            t += dt
            #
            f.write(theta0, t)

    assert abs(maelstrom.helpers.average(theta0) - 1519.81) < 1.0e-2

    return