Exemple #1
0
def Newton_manual(F, vd, bcs, J, atol, rtol, max_it, lmbda\
                 , vd_res):
    #Reset counters
    Iter      = 0
    residual   = 1
    rel_res    = residual
    while rel_res > rtol and residual > atol and Iter < max_it:
        A = assemble(J, keep_diagonal = True)
        A.ident_zeros()
        b = assemble(-F)

        [bc.apply(A, b, vd.vector()) for bc in bcs]

        #solve(A, vd_res.vector(), b, "superlu_dist")
        #solve(A, vd_res.vector(), b, "mumps")
        solve(A, vd_res.vector(), b)

        vd.vector().axpy(1., vd_res.vector())
        [bc.apply(vd.vector()) for bc in bcs]
        rel_res = norm(vd_res, 'l2')
        residual = b.norm('l2')

        if MPI.rank(mpi_comm_world()) == 0:
            print "Newton iteration %d: r (atol) = %.3e (tol = %.3e), r (rel) = %.3e (tol = %.3e) " \
        % (Iter, residual, atol, rel_res, rtol)
        Iter += 1

    #Reset
    residual   = 1
    rel_res    = residual
    Iter = 0

    return vd
Exemple #2
0
def Newton_manual(F, udp, bcs, atol, rtol, max_it, lmbda, udp_res, VVQ):
    #Reset counters
    Iter = 0
    residual = 1
    rel_res = residual
    dw = TrialFunction(VVQ)
    Jac = derivative(F, udp, dw)  # Jacobi

    while rel_res > rtol and residual > atol and Iter < max_it:
        A = assemble(Jac)
        A.ident_zeros()
        b = assemble(-F)

        [bc.apply(A, b, udp.vector()) for bc in bcs]

        #solve(A, udp_res.vector(), b, "superlu_dist")

        solve(A, udp_res.vector(), b)  #, "mumps")

        udp.vector()[:] = udp.vector()[:] + lmbda * udp_res.vector()[:]
        #udp.vector().axpy(1., udp_res.vector())
        [bc.apply(udp.vector()) for bc in bcs]
        rel_res = norm(udp_res, 'l2')
        residual = b.norm('l2')

        if MPI.rank(mpi_comm_world()) == 0:
            print "Newton iteration %d: r (atol) = %.3e (tol = %.3e), r (rel) = %.3e (tol = %.3e) " \
        % (Iter, residual, atol, rel_res, rtol)
        Iter += 1

    return udp
    def _assemble(self) -> Tuple[fenics.PETScMatrix, fenics.PETScMatrix]:
        """Construct matrices for generalized eigenvalue problem.

        Assemble the left and the right hand side of the eigenfunction
        equation into the corresponding matrices.

        Returns
        -------
        A : fenics.PETScMatrix
            Matrix corresponding to the form $a(u, v)$.
        B : fenics.PETScMatrix
            Matrix corresponding to the form $b(u, v)$.

        """
        V = self.vector_space

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

        a, b = self._construct_eigenproblem(u, v)

        A = fenics.PETScMatrix()
        B = fenics.PETScMatrix()

        fenics.assemble(a * fenics.dx, tensor=A)
        fenics.assemble(b * fenics.dx, tensor=B)

        return A, B
def assemble_as_scipy(form):
    K = PETScMatrix()
    assemble(form, tensor=K)
    ki, kj, kv = K.mat().getValuesCSR()
    import scipy
    import scipy.sparse
    Ksp = scipy.sparse.csr_matrix((kv, kj, ki))
    return Ksp
Exemple #5
0
 def geneForwardMatrix(self, q_fun=fe.Constant(0.0), fR=fe.Constant(0.0), \
                       fI=fe.Constant(0.0)):
     if self.haveFunctionSpace == False:
         self.geneFunctionSpace()
         
     xx, yy, dPML, sig0_, p_ = self.domain.xx, self.domain.yy, self.domain.dPML,\
                               self.domain.sig0, self.domain.p
     # define the coefficents induced by PML
     sig1 = fe.Expression('x[0] > x1 && x[0] < x1 + dd ? sig0*pow((x[0]-x1)/dd, p) : (x[0] < 0 && x[0] > -dd ? sig0*pow((-x[0])/dd, p) : 0)', 
                  degree=3, x1=xx, dd=dPML, sig0=sig0_, p=p_)
     sig2 = fe.Expression('x[1] > x2 && x[1] < x2 + dd ? sig0*pow((x[1]-x2)/dd, p) : (x[1] < 0 && x[1] > -dd ? sig0*pow((-x[1])/dd, p) : 0)', 
                  degree=3, x2=yy, dd=dPML, sig0=sig0_, p=p_)
     
     sR = fe.as_matrix([[(1+sig1*sig2)/(1+sig1*sig1), 0.0], [0.0, (1+sig1*sig2)/(1+sig2*sig2)]])
     sI = fe.as_matrix([[(sig2-sig1)/(1+sig1*sig1), 0.0], [0.0, (sig1-sig2)/(1+sig2*sig2)]])
     cR = 1 - sig1*sig2
     cI = sig1 + sig2
     
     # define the coefficients with physical meaning
     angl_fre = self.kappa*np.pi
     angl_fre2 = fe.Constant(angl_fre*angl_fre)
     
     # define equations
     u_ = fe.TestFunction(self.V)
     du = fe.TrialFunction(self.V)
     
     u_R, u_I = fe.split(u_)
     duR, duI = fe.split(du)
     
     def sigR(v):
         return fe.dot(sR, fe.nabla_grad(v))
     def sigI(v):
         return fe.dot(sI, fe.nabla_grad(v))
     
     F1 = - fe.inner(sigR(duR)-sigI(duI), fe.nabla_grad(u_R))*(fe.dx) \
         - fe.inner(sigR(duI)+sigI(duR), fe.nabla_grad(u_I))*(fe.dx) \
         - fR*u_R*(fe.dx) - fI*u_I*(fe.dx)
     
     a2 = fe.inner(angl_fre2*q_fun*(cR*duR-cI*duI), u_R)*(fe.dx) \
          + fe.inner(angl_fre2*q_fun*(cR*duI+cI*duR), u_I)*(fe.dx) \
     
     # define boundary conditions
     def boundary(x, on_boundary):
         return on_boundary
     
     bc = [fe.DirichletBC(self.V.sub(0), fe.Constant(0.0), boundary), \
           fe.DirichletBC(self.V.sub(1), fe.Constant(0.0), boundary)]
     
     a1, L1 = fe.lhs(F1), fe.rhs(F1)
     self.u = fe.Function(self.V)
     self.A1 = fe.assemble(a1)
     self.b1 = fe.assemble(L1)
     self.A2 = fe.assemble(a2)
     bc[0].apply(self.A1, self.b1)
     bc[1].apply(self.A1, self.b1)
     bc[0].apply(self.A2)
     bc[1].apply(self.A2)
     self.A = self.A1 + self.A2
Exemple #6
0
def vjp_solve_eval_impl(
    g: np.array,
    fenics_solution: fenics.Function,
    fenics_residual: ufl.Form,
    fenics_inputs: List[FenicsVariable],
    bcs: List[fenics.DirichletBC],
) -> Tuple[np.array]:
    """Computes the gradients of the output with respect to the inputs."""
    # Convert tangent covector (adjoint) to a FEniCS variable
    adj_value = numpy_to_fenics(g, fenics_solution)
    adj_value = adj_value.vector()

    F = fenics_residual
    u = fenics_solution
    V = u.function_space()
    dFdu = fenics.derivative(F, u)
    adFdu = ufl.adjoint(
        dFdu, reordered_arguments=ufl.algorithms.extract_arguments(dFdu)
    )

    u_adj = fenics.Function(V)
    adj_F = ufl.action(adFdu, u_adj)
    adj_F = ufl.replace(adj_F, {u_adj: fenics.TrialFunction(V)})
    adj_F_assembled = fenics.assemble(adj_F)

    if len(bcs) != 0:
        for bc in bcs:
            bc.homogenize()
        hbcs = bcs

        for bc in hbcs:
            bc.apply(adj_F_assembled)
            bc.apply(adj_value)

    fenics.solve(adj_F_assembled, u_adj.vector(), adj_value)

    fenics_grads = []
    for fenics_input in fenics_inputs:
        if isinstance(fenics_input, fenics.Function):
            V = fenics_input.function_space()
        dFdm = fenics.derivative(F, fenics_input, fenics.TrialFunction(V))
        adFdm = fenics.adjoint(dFdm)
        result = fenics.assemble(-adFdm * u_adj)
        if isinstance(fenics_input, fenics.Constant):
            fenics_grad = fenics.Constant(result.sum())
        else:  # fenics.Function
            fenics_grad = fenics.Function(V, result)
        fenics_grads.append(fenics_grad)

    # Convert FEniCS gradients to jax array representation
    jax_grads = (
        None if fg is None else np.asarray(fenics_to_numpy(fg)) for fg in fenics_grads
    )

    jax_grad_tuple = tuple(jax_grads)

    return jax_grad_tuple
Exemple #7
0
    def test_DoGIP_vs_FEniCS(self):
        print(
            '\n== testing DoGIP vs. FEniCS for problem of weighted projection ===='
        )

        for dim, pol_order in itertools.product([2, 3], [1, 2]):
            print('dim={}; pol_order={}'.format(dim, pol_order))
            N = 2
            # creating MESH, defining MATERIAL and SOURCE
            if dim == 2:
                mesh = UnitSquareMesh(N, N)
                m = Expression("1+10*16*x[0]*(1-x[0])*x[1]*(1-x[1])",
                               degree=3)  # material coefficients
                f = Expression("x[0]*x[0]*x[1]", degree=2)
            elif dim == 3:
                mesh = UnitCubeMesh(N, N, N)
                m = Expression("1+100*x[0]*(1-x[0])*x[1]*x[2]",
                               degree=2)  # material coefficients
                f = Expression("(1-x[0])*x[1]*x[2]", degree=2)

            mesh.coordinates()[:] += 0.1 * np.random.random(
                mesh.coordinates().shape)  # mesh perturbation

            ## standard approach with FEniCS #############################################
            V = FunctionSpace(mesh, "CG", pol_order)  # original FEM space
            u, v = TrialFunction(V), TestFunction(V)
            u_fenics = Function(V)
            solve(m * u * v * dx == m * f * v * dx, u_fenics)

            ## DoGIP - double-grid integration with interpolation-projection #############
            W = FunctionSpace(mesh, "CG", 2 * pol_order)  # double-grid space
            w = TestFunction(W)
            A_dogip = assemble(
                m * w *
                dx).get_local()  # diagonal matrix of material coefficients
            b = assemble(m * f * v * dx)  # vector of right-hand side

            # assembling interpolation-projection matrix B
            B = get_B(V, W, problem=0)

            # # linear solver on double grid, standard
            Afun = lambda x: B.T.dot(A_dogip * B.dot(x))

            Alinoper = linalg.LinearOperator((V.dim(), V.dim()),
                                             matvec=Afun,
                                             dtype=np.float)
            x, info = linalg.cg(Alinoper,
                                b.get_local(),
                                x0=np.zeros(V.dim()),
                                tol=1e-10,
                                maxiter=1e3,
                                callback=None)

            # testing the difference between DoGIP and FEniCS
            self.assertAlmostEqual(
                0, np.linalg.norm(u_fenics.vector().get_local() - x))
            print('...ok')
Exemple #8
0
	def compute_objective(self):
		"""Computes the part of the objective value that comes from the regularization

		Returns
		-------
		float
			Part of the objective value coming from the regularization

		"""

		if self.has_regularization:

			value = 0.0

			if self.mu_volume > 0.0:
				if not self.measure_hole:
					volume = fenics.assemble(Constant(1.0)*self.dx)
				else:
					volume = self.delta_x*self.delta_y*self.delta_z - fenics.assemble(Constant(1)*self.dx)

				value += 0.5*self.mu_volume*pow(volume - self.target_volume, 2)

			if self.mu_surface > 0.0:
				surface = fenics.assemble(Constant(1.0)*self.ds)
				# self.current_surface.val = surface
				value += 0.5*self.mu_surface*pow(surface - self.target_surface, 2)
			
			if self.mu_curvature > 0.0:
				self.compute_curvature()
				curvature_val = fenics.assemble(fenics.inner(self.kappa_curvature, self.kappa_curvature)*self.ds)
				value += 0.5*self.mu_curvature*curvature_val
			
			if self.mu_barycenter > 0.0:
				if not self.measure_hole:
					volume = fenics.assemble(Constant(1)*self.dx)

					barycenter_x = fenics.assemble(self.spatial_coordinate[0]*self.dx) / volume
					barycenter_y = fenics.assemble(self.spatial_coordinate[1]*self.dx) / volume
					if self.form_handler.mesh.geometric_dimension() == 3:
						barycenter_z = fenics.assemble(self.spatial_coordinate[2]*self.dx) / volume
					else:
						barycenter_z = 0.0

				else:
					volume = self.delta_x*self.delta_y*self.delta_z - fenics.assemble(Constant(1)*self.dx)

					barycenter_x = (0.5*(pow(self.x_end, 2) - pow(self.x_start, 2))*self.delta_y*self.delta_z - fenics.assemble(self.spatial_coordinate[0]*self.dx)) / volume
					barycenter_y = (0.5*(pow(self.y_end, 2) - pow(self.y_start, 2))*self.delta_x*self.delta_z - fenics.assemble(self.spatial_coordinate[1]*self.dx)) / volume
					if self.form_handler.mesh.geometric_dimension() == 3:
						barycenter_z = (0.5*(pow(self.z_end, 2) - pow(self.z_start, 2))*self.delta_x*self.delta_y - fenics.assemble(self.spatial_coordinate[2]*self.dx)) / volume
					else:
						barycenter_z = 0.0

				value += 0.5*self.mu_barycenter*(pow(barycenter_x - self.target_barycenter_list[0], 2) + pow(barycenter_y - self.target_barycenter_list[1], 2)
												 + pow(barycenter_z - self.target_barycenter_list[2], 2))

			return value

		else:
			return 0.0
    def refine_mesh(self, tolerance: float) -> Optional[bool]:
        """Generate refined mesh.

        This method locates cells of the mesh where the error of the
        eigenfunction is above a certain threshold and generates a new mesh
        with finer resolution on the problematic regions.

        For a given eigenfunction $u$ with corresponding eigenvalue
        $\lambda$, it must be true that $a(u, v) = \lambda b(u, v)$ for all
        functions $v$. We make $v$ go through all the basis functions on the
        mesh and locate the cells where the previous identity fails to hold.

        Parameters
        ----------
        tolerance : float
            Criterion to determine whether a cell needs to be refined or not.

        Returns
        -------
        refined_mesh : Optional[fenics.Mesh]
            A new mesh derived from `mesh` with higher level of granularity
            on certain regions. If no refinements are needed, None is
            returned.

        """
        ew, ev = self.eigenvalues[1:], self.eigenfunctions[1:]
        dofs_needing_refinement = set()

        # Find all the degrees of freedom needing refinement.
        for k, (l, u) in enumerate(zip(ew, ev)):
            v = fenics.TrialFunction(self.vector_space)
            a, b = self._construct_eigenproblem(u, v)
            A = fenics.assemble(a * fenics.dx)
            B = fenics.assemble(b * fenics.dx)

            error = np.abs((A - l * B).sum())
            indices = np.flatnonzero(error > tolerance)
            dofs_needing_refinement.update(indices)

        if not dofs_needing_refinement:
            return

        # Refine the cells corresponding to the degrees of freedom needing
        # refinement.
        dofmap = self.vector_space.dofmap()
        cell_markers = fenics.MeshFunction('bool', self.mesh,
                                           self.mesh.topology().dim())
        cell_markers.set_all(False)
        for cell in fenics.cells(self.mesh):
            cell_dofs = set(dofmap.cell_dofs(cell.index()))
            if cell_dofs.intersection(dofs_needing_refinement):
                cell_markers[cell] = True

        return fenics.refine(self.mesh, cell_markers)
def test_empty_measure():
    mesh, _, _, dx, ds, dS = cashocs.regular_mesh(5)
    V = fenics.FunctionSpace(mesh, 'CG', 1)
    dm = cashocs.utils.EmptyMeasure(dx)

    trial = fenics.TrialFunction(V)
    test = fenics.TestFunction(V)

    assert fenics.assemble(1 * dm) == 0.0
    assert (fenics.assemble(test * dm).norm('linf')) == 0.0
    assert (fenics.assemble(trial * test * dm).norm('linf')) == 0.0
Exemple #11
0
    def solve(self, **arguments):

        t_start = time.clock()

        # definig Function space on this mesh using Lagrange
        #polynoimals of degree 1.
        H = FunctionSpace(self.mesh, "CG", 1)

        # Setting up the variational problem
        v = TrialFunction(H)
        w = TestFunction(H)

        coeff_dx2 = Constant(1)
        coeff_v = Constant(1)

        f = Expression("(4*pow(pi,2))*exp(-(1/coeff_v)*t)*sin(2*pi*x[0])",
                       {'coeff_v': coeff_v},
                       degree=2)

        v0 = Expression("sin(2*pi*x[0])", degree=2)

        f.t = 0

        def boundary(x, on_boundary):
            return on_boundary

        bc = DirichletBC(H, v0, boundary)

        v1 = interpolate(v0, H)
        dt = self.steps.time

        a = (dt * inner(grad(v), grad(w)) + dt * coeff_v * inner(v, w)) * dx
        L = (f * dt - coeff_v * v1) * w * dx

        A = assemble(a)
        v = Function(H)

        T = self.domain.time[-1]
        t = dt

        # solving the variational problem.
        while t <= T:
            b = assemble(L, tensor=b)
            vo.t = t
            bc.apply(A, b)

            solve(A, v.vector(), b)
            t += dt

            v1.assign(v)

        self.solution.extend(v.vector().array())

        return [self.solution, time.clock() - t_start]
Exemple #12
0
def integrateFluidStress(p, u):
  eps   = 0.5*(grad(u) + grad(u).T)
  sig   = -p*Identity(2) + 2.0*mu_f*eps
  sig1 = J_(u)*sig*inv(F_(u)).T
  traction  = dot(sig1, -n)

  forceX = traction[0]*ds(5) + traction[0]*ds(6)
  forceY = traction[1]*ds(5) + traction[1]*ds(6)
  fX = assemble(forceX)
  fY = assemble(forceY)

  return fX, fY
Exemple #13
0
    def update_map(self):
        d_clipped = fe.conditional(fe.gt(self.d_new, 0.5), self.d_new, 0.)
        d_int_full = fe.assemble(self.d_new * fe.det(self.grad_gamma) * fe.dx)
        d_int = fe.assemble(d_clipped * fe.det(self.grad_gamma) * fe.dx)

        print("d_int_clipped {}".format(float(d_int)))
        print("d_int_full {}".format(float(d_int_full)))

        update_flag = False
        if d_int - self.d_integrals[-1] > self.d_integral_interval:
            update_flag = True

        if update_flag and not self.finish_flag:
            print('\n')
            print(
                '================================================================================='
            )
            print('>> Updating map...')
            print(
                '================================================================================='
            )

            new_tip_point = self.identify_crack_tip()
            if self.inside_domain(new_tip_point):
                if len(self.control_points) > 1:
                    v1 = self.control_points[-1] - self.control_points[-2]
                    v2 = new_tip_point - self.control_points[-1]
                    v1 = v1 / np.linalg.norm(v1)
                    v2 = v2 / np.linalg.norm(v2)
                    print("new_tip_point is {}".format(new_tip_point))
                    print("v1 is {}".format(v1))
                    print("v2 is {}".format(v2))
                    print("control points are \n{}".format(
                        self.control_points))
                    print("impact_radii are {}".format(self.impact_radii))
                    assert np.dot(
                        v1, v2
                    ) > np.sqrt(2) / 2, "Crack propogration angle not good"
                self.compute_impact_radii(new_tip_point)
                self.interpolate_H()
                self.d_integrals.append(d_int)
                print(
                    '================================================================================='
                )
            else:
                self.finish_flag = True
            self.update_weak_form = True

        else:
            print("Do not modify map")

        print("d_integrals {}".format(self.d_integrals))
    def compute_dmdt(m):
        """Convenience function that does all in one go"""

        # Assemble RHS
        b = fe.assemble(Heff_form)

        # Project onto Heff
        LU.solve(Heff.vector(), b)

        LLG = -gamma/(1+alpha*alpha)*fe.cross(m, Heff) - alpha*gamma/(1+alpha*alpha)*fe.cross(m, fe.cross(m, Heff))

        result = fe.assemble(fe.dot(LLG, v)*fe.dP)
        return result.array()
    def write_results_table_row(self, table_filepath):

        with open(table_filepath, "a") as table_file:

            table_file.write(
                str(self.pressure_penalty_factor.__float__()) + "," \
                + str(self.solid_viscosity.__float__()) + "," \
                + str(self.temperature_rayleigh_number.__float__()) + "," \
                + str(self.concentration_rayleigh_number.__float__()) + ", " \
                + str(self.prandtl_number.__float__()) + ", " \
                + str(self.stefan_number.__float__()) + ", " \
                + str(self.schmidt_number.__float__()) + ", " \
                + str(self.liquidus_slope.__float__()) + ", " \
                + str(self.pure_liquidus_temperature.__float__()) + ", " \
                + str(self.regularization_central_temperature_offset.__float__()) + ", " \
                + str(self.regularization_smoothing_parameter.__float__()) + ", " \
                + str(1./float(self.uniform_gridsize)) + ", " \
                + str(self.timestep_size.__float__()) + ", " \
                + str(self.time_order) + ", " \
                + str(self.time) + ", ")

            solid_area = fenics.assemble(self.solid_area_integrand())

            area_above_critical_phi = fenics.assemble(
                self.area_above_critical_phi_integrand())

            solute_mass = fenics.assemble(self.solute_mass_integrand())

            p, u, T, C = self.solution.leaf_node().split(deepcopy=True)

            phi = fenics.project(self.semi_phasefield(T=T, C=C),
                                 mesh=self.mesh.leaf_node())

            Cbar = fenics.project(C * (1. - phi), mesh=self.mesh.leaf_node())

            table_file.write(
                str(solid_area) + ", " \
                + str(area_above_critical_phi) + ", " \
                + str(solute_mass) + ", " \
                + str(p.vector().min()) + ", " \
                + str(p.vector().max()) + ", " \
                + str(fenics.norm(u.vector(), "linf"))  + ", " \
                + str(T.vector().min()) + ", " \
                + str(T.vector().max()) + ", " \
                + str(Cbar.vector().min()) + ", " \
                + str(Cbar.vector().max()) + ", " \
                + str(phi.vector().min()) + ", " \
                + str(phi.vector().max()))

            table_file.write("\n")
Exemple #16
0
    def solve_problem_matrix_approach(self):
        u = fa.TrialFunction(self.V)
        v = fa.TestFunction(self.V)
        a = fa.inner(fa.grad(u), fa.grad(v)) * fa.dx
        L = self.source * v * fa.dx

        # equivalent to solve(a == L, U, b)
        A = fa.assemble(a)
        b = fa.assemble(L)
        [bc.apply(A, b) for bc in self.bcs]
        u = fa.Function(self.V)
        U = u.vector()
        fa.solve(A, U, b)
        return u
Exemple #17
0
def test__deepcopy__ci__():

    tolerance = 1.e-6

    sim = CavityMeltingSimulationWithoutConcentration()

    sim.assign_initial_values()

    for it in range(3):

        sim.solve(goal_tolerance=4.e-5)

        sim.advance()

    sim2 = sim.deepcopy()

    assert (all(sim.solution.vector() == sim2.solution.vector()))

    for it in range(2):

        sim.solve(goal_tolerance=4.e-5)

        sim.advance()

    p_fine, u_fine, T_fine, C_fine = fenics.split(sim.solution)

    phi = sim.semi_phasefield(T=T_fine, C=C_fine)

    solid_area = fenics.assemble(phi * fenics.dx)

    assert (abs(solid_area - expected_solid_area) < tolerance)

    assert (not (sim.solution.vector() == sim2.solution.vector()))

    for it in range(2):

        sim2.solve(goal_tolerance=4.e-5)

        sim2.advance()

    p_fine, u_fine, T_fine, C_fine = fenics.split(sim2.solution)

    phi = sim2.semi_phasefield(T=T_fine, C=C_fine)

    solid_area = fenics.assemble(phi * fenics.dx)

    assert (abs(solid_area - expected_solid_area) < tolerance)

    assert (all(sim.solution.vector() == sim2.solution.vector()))
Exemple #18
0
    def compute_operators(self):
        u = fa.TrialFunction(self.V)
        v = fa.TestFunction(self.V)
        form_a = fa.inner(fa.grad(u), fa.grad(v)) * fa.dx
        form_b = u * v * fa.dx

        A = fa.assemble(form_a)
        B = fa.assemble(form_b)
        A_np = np.array(A.array())
        B_np = np.array(B.array())

        [bc.apply(A) for bc in self.bcs]
        A_np_modified = np.array(A.array())

        return A_np, B_np, A_np_modified
Exemple #19
0
def mean_value(u, xmin, xmax, V):
    uu = fenics.Expression(
        f"((x[0] >= {xmin}) "
        f"&& (x[0] < {xmax}))"
        f"? 1 : 0;",
        element=V.ufl_element()
    )
    one = fenics.Function(V)
    one.vector()[:] = 1.0
    denom = fenics.assemble(uu * one * fenics.dx)
    if denom == 0:
        out = np.nan
    else:
        out = fenics.assemble(uu * u * fenics.dx) / denom
    return out
    def compute_steady_state(self):

        names = {'Cl', 'Na', 'K'}

        P1 = FiniteElement('P', fe.triangle, 1)
        element = MixedElement([P1, P1, P1])
        V = FunctionSpace(self.mesh, element)
        self.V_conc = V

        (u_cl, u_na, u_k) = TrialFunction(V)
        (v_cl, v_na, v_k) = TestFunction(V)

        assert (self.flow is not None)

        n = fe.FacetNormal(self.mesh)

        # F = ( self.F_diff_conv(u_cl, v_cl, n, grad(self.phi), 1. ,1., 0.)
        #    + self.F_diff_conv(u_na, v_na, n, grad(self.phi), 1. ,1., 0.)
        #    + self.F_diff_conv(u_k , v_k , n, grad(self.phi), 1. ,1., 0.) )

        dx, ds = self.dx, self.ds
        flow = self.flow
        F = inner(grad(u_cl), grad(v_cl)) * dx \
            + inner(flow, grad(u_cl)) * v_cl * dx \
            + inner(grad(u_na), grad(v_na)) * dx \
            + inner(flow, grad(u_na)) * v_na * dx \
            + inner(grad(u_k), grad(v_k)) * dx \
            + inner(flow, grad(u_k)) * v_k * dx

        a, L = fe.lhs(F), fe.rhs(F)
        a_mat = fe.assemble(a)
        L_vec = fe.assemble(L)
        # solve
        u = Function(V)
        fe.solve(a_mat, u.vector(), L_vec)

        u_cl, u_na, u_k = u.split()

        output1 = fe.File('/tmp/steady_state_cl.pvd')
        output1 << u_cl
        output2 = fe.File('/tmp/steady_state_na.pvd')
        output2 << u_na
        output3 = fe.File('/tmp/steady_state_k.pvd')
        output3 << u_k

        self.u_cl = u_cl
        self.u_na = u_na
        self.u_k = u_k
    def __init__(me, V, max_smooth_vectors=50):
        R = fenics.FunctionSpace(V.mesh(), 'R', 0)

        u_trial = fenics.TrialFunction(V)
        v_test = fenics.TestFunction(V)
        c_trial = fenics.TrialFunction(R)
        d_test = fenics.TestFunction(R)
        a11 = fenics.inner(fenics.grad(u_trial),
                           fenics.grad(v_test)) * fenics.dx
        a12 = c_trial * v_test * fenics.dx
        a21 = u_trial * d_test * fenics.dx
        A11 = convert_fenics_csr_matrix_to_scipy_csr_matrix(
            fenics.assemble(a11))
        A12 = convert_fenics_csr_matrix_to_scipy_csr_matrix(
            fenics.assemble(a12))
        A21 = convert_fenics_csr_matrix_to_scipy_csr_matrix(
            fenics.assemble(a21))
        me.A = sps.bmat([[A11, A12], [A21, None]]).tocsc()
        solve_A = spla.factorized(me.A)

        m = u_trial * v_test * fenics.dx
        me.M = convert_fenics_csr_matrix_to_scipy_csr_matrix(
            fenics.assemble(m)).tocsc()
        solve_M = spla.factorized(me.M)

        def solve_neumann(f_vec):
            fe_vec = np.concatenate([f_vec, np.array([0])])
            ue_vec = solve_A(fe_vec)
            u_vec = ue_vec[:-1]
            return u_vec

        me.solve_neumann_linop = spla.LinearOperator((V.dim(), V.dim()),
                                                     matvec=solve_neumann)
        me.solve_M_linop = spla.LinearOperator((V.dim(), V.dim()),
                                               matvec=solve_M)

        ee, UU = spla.eigsh(me.solve_neumann_linop,
                            k=max_smooth_vectors - 1,
                            M=me.solve_M_linop,
                            which='LM')

        me.U_smooth = np.zeros((V.dim(), max_smooth_vectors))
        const_fct = np.ones(V.dim())
        me.U_smooth[:, 0] = const_fct / np.sqrt(
            np.dot(const_fct, me.M * const_fct))
        me.U_smooth[:, 1:] = solve_M(UU[:, ::-1])

        me.k = 0
def test__cavity_freezing_simulation__ci__():

    sim = phaseflow.cavity_freezing_simulation.CavityFreezingSimulation(
        uniform_gridsize=16, time_order=2)

    sim.cold_wall_temperature_before_freezing.assign(0.25)

    sim.cold_wall_temperature_during_freezing.assign(-1.25)

    sim.temperature_rayleigh_number.assign(3.e5)

    sim.concentration_rayleigh_number.assign(-3.e4)

    sim.schmidt_number.assign(1.)

    sim.liquidus_slope.assign(-0.1)

    sim.regularization_smoothing_parameter.assign(1. / 16.)

    sim.output_dir = tempfile.mkdtemp() + "/test__cavity_freezing_simulation/"

    sim.timestep_size.assign(1.)

    endtime = 3.

    sim.run(endtime=endtime, checkpoint_times=(
        0.,
        endtime,
    ))

    A_S = fenics.assemble(sim.solid_area_integrand())

    assert (abs(A_S - 0.177) < 1.e-3)
Exemple #23
0
def vjp_assemble_impl(
    g: np.array,
    fenics_output_form: ufl.Form,
    fenics_inputs: List[FenicsVariable],
) -> Tuple[np.array]:
    """Computes the gradients of the output with respect to the inputs."""

    # Compute derivative form for the output with respect to each input
    fenics_grads_forms = []
    for fenics_input in fenics_inputs:
        # Need to construct direction (test function) first
        if isinstance(fenics_input, fenics.Function):
            V = fenics_input.function_space()
        elif isinstance(fenics_input, fenics.Constant):
            mesh = fenics_output_form.ufl_domain().ufl_cargo()
            V = fenics.FunctionSpace(mesh, "Real", 0)
        else:
            raise NotImplementedError

        dv = fenics.TestFunction(V)
        fenics_grad_form = fenics.derivative(fenics_output_form, fenics_input,
                                             dv)
        fenics_grads_forms.append(fenics_grad_form)

    # Assemble the derivative forms
    fenics_grads = [fenics.assemble(form) for form in fenics_grads_forms]

    # Convert FEniCS gradients to jax array representation
    jax_grads = (None if fg is None else np.asarray(g * fenics_to_numpy(fg))
                 for fg in fenics_grads)

    jax_grad_tuple = tuple(jax_grads)

    return jax_grad_tuple
Exemple #24
0
def jvp_assemble_eval(
    fenics_function: Callable,
    fenics_templates: Iterable[FenicsVariable],
    primals: Tuple[np.array],
    tangents: Tuple[np.array],
) -> Tuple[np.array]:
    """Computes the jacobian-vector product for fenics.assemble
    """

    numpy_output_primal, output_primal_form, fenics_primals = assemble_eval(
        fenics_function, fenics_templates, *primals)

    # Now tangent evaluation!
    fenics_tangents = convert_all_to_fenics(fenics_primals, *tangents)
    output_tangent_form = 0.0
    for fp, ft in zip(fenics_primals, fenics_tangents):
        output_tangent_form += fenics.derivative(output_primal_form, fp, ft)

    if not isinstance(output_tangent_form, float):
        output_tangent_form = ufl.algorithms.expand_derivatives(
            output_tangent_form)
        output_tangent = fenics.assemble(output_tangent_form)

    jax_output_tangent = output_tangent

    return numpy_output_primal, jax_output_tangent
Exemple #25
0
def test_create_measure():
    meas = cashocs.utils.generate_measure([1, 2, 3], ds)
    test = ds(1) + ds(2) + ds(3)

    assert abs(fenics.assemble(1 * meas) - 3) < 1e-14
    for i in range(3):
        assert meas._measures[i] == test._measures[i]
Exemple #26
0
 def energy_norm(self, u):
     psi_plus = self.psi_plus(strain(self.mfem_grad(u)))
     psi_minus = self.psi_minus(strain(self.mfem_grad(u)))
     return np.sqrt(
         float(
             fe.assemble((g_d(self.d_exact) * psi_plus + psi_minus) *
                         fe.det(self.grad_gamma) * fe.dx)))
Exemple #27
0
def test__compositional_convection_coupled_melting_benchmark__amr__regression__ci__(
):

    sim = phaseflow.cavity_melting_simulation.CavityMeltingSimulation()

    sim.output_dir = tempfile.mkdtemp() + \
        "/test__compositional_convection_coupled_melting/"

    phaseflow.helpers.mkdir_p(sim.output_dir)

    sim.assign_initial_values()

    sim.timestep_size.assign(10.)

    for it, epsilon_M in zip(range(4), (0.5e-3, 0.25e-3, 0.125e-3, 0.0625e-3)):

        if it == 1:

            sim.regularization_sequence = None

        sim.solve_with_auto_regularization(goal_tolerance=epsilon_M)

        sim.advance()

    p_fine, u_fine, T_fine, C_fine = fenics.split(sim.solution)

    phi = sim.semi_phasefield(T=T_fine, C=C_fine)

    expected_solid_area = 0.7405

    solid_area = fenics.assemble(phi * fenics.dx)

    tolerance = 1.e-4

    assert (abs(solid_area - expected_solid_area) < tolerance)
Exemple #28
0
def test__coarsen__ci__():

    sim = CavityMeltingSimulationWithoutConcentration()

    sim.assign_initial_values()

    for it in range(3):

        sim.solve(goal_tolerance=4.e-5)

        sim.advance()

    sim.coarsen(absolute_tolerances=(1., 1., 1.e-3, 1., 1.))

    for it in range(2):

        sim.solve(goal_tolerance=4.e-5)

        sim.advance()

    p_fine, u_fine, T_fine, C_fine = fenics.split(sim.solution)

    phi = sim.semi_phasefield(T=T_fine, C=C_fine)

    solid_area = fenics.assemble(phi * fenics.dx)

    tolerance = 1.e-3

    assert (abs(solid_area - expected_solid_area) < tolerance)
Exemple #29
0
def test__checkpoint__ci__():

    sim = CavityMeltingSimulationWithoutConcentration()

    sim.assign_initial_values()

    for it in range(2):

        sim.solve(goal_tolerance=4.e-5)

        sim.advance()

    checkpoint_filepath = tempfile.mkdtemp() + "/checkpoint.h5"

    sim.write_checkpoint(checkpoint_filepath)

    sim2 = CavityMeltingSimulationWithoutConcentration()

    sim2.read_checkpoint(checkpoint_filepath)

    for it in range(3):

        sim.solve(goal_tolerance=4.e-5)

        sim.advance()

    p_fine, u_fine, T_fine, C_fine = fenics.split(sim.solution)

    phi = sim.semi_phasefield(T=T_fine, C=C_fine)

    solid_area = fenics.assemble(phi * fenics.dx)

    assert (abs(solid_area - expected_solid_area) < 1.e-6)
def test__stefan_problem_with_bdf2__regression__ci__():

    expected_melted_length = 0.094662

    sim = StefanProblemBenchmarkSimulation(time_order=2)

    sim.output_dir = tempfile.mkdtemp() + "/test__stefan_problem_with_bdf2/"

    phaseflow.helpers.mkdir_p(sim.output_dir)

    sim.assign_initial_values()

    end_time = 0.1

    timestep_count = 25

    sim.timestep_size.assign(end_time / float(timestep_count))

    sim.regularization_smoothing_parameter.assign(0.005)

    for it in range(timestep_count):

        if it == 1:

            sim.regularization_sequence = None

        sim.solve_with_auto_regularization(goal_tolerance=1.e-7)

        sim.advance()

    melted_length = fenics.assemble(sim.melted_length_integrand())

    tolerance = 1.e-4

    assert (abs(melted_length - expected_melted_length) < tolerance)
 def get_tumour_volume(self):
     # Perhaps there is a prettier way, but integrate a unit function over the tumour tets
     one = d.Function(self.V)
     one.vector()[:] = 1
     return sum(d.assemble(one * self.dxs(i)) for i in v.tissues["tumour"]["indices"])
Exemple #32
0
def main():
    """Main function. Organizes workflow."""
    fname = str(INPUTS['filename'])
    term = Terminal()
    print(
        term.yellow
        + "Working on file {}.".format(fname)
        + term.normal
    )
    # Load mesh and physical domains from file.
    mesh = fe.Mesh(fname + ".xml")
    if INPUTS['saving']['mesh']:
        fe.File(fname + "_mesh.pvd") << mesh
    if INPUTS['plotting']['mesh']:
        fe.plot(mesh, title='Mesh')
    subdomains = fe.MeshFunction(
        'size_t', mesh, fname + '_physical_region.xml')
    if INPUTS['saving']['subdomains']:
        fe.File(fname + "_subdomains.pvd") << subdomains
    if INPUTS['plotting']['subdomains']:
        fe.plot(subdomains, title='Subdomains')
    # function space for temperature/concentration
    func_space = fe.FunctionSpace(
        mesh,
        INPUTS['element_type'],
        INPUTS['element_degree'],
        constrained_domain=PeriodicDomain()
    )
    # discontinuous function space for visualization
    dis_func_space = fe.FunctionSpace(
        mesh,
        'DG',
        INPUTS['element_degree'],
        constrained_domain=PeriodicDomain()
    )
    if ARGS['--verbose']:
        print('Number of cells:', mesh.num_cells())
        print('Number of faces:', mesh.num_faces())
        print('Number of edges:', mesh.num_edges())
        print('Number of vertices:', mesh.num_vertices())
        print('Number of DOFs:', len(func_space.dofmap().dofs()))
    # temperature/concentration field
    field = fe.TrialFunction(func_space)
    # test function
    test_func = fe.TestFunction(func_space)
    # function, which is equal to 1 everywhere
    unit_function = fe.Function(func_space)
    unit_function.assign(fe.Constant(1.0))
    # assign material properties to each domain
    if INPUTS['mode'] == 'conductivity':
        mat_prop = SubdomainConstant(
            subdomains,
            fe.Constant(INPUTS['conductivity']['gas']),
            fe.Constant(INPUTS['conductivity']['solid']),
            degree=0
        )
    elif INPUTS['mode'] == 'diffusivity':
        mat_prop = SubdomainConstant(
            subdomains,
            fe.Constant(INPUTS['diffusivity']['gas']),
            fe.Constant(INPUTS['diffusivity']['solid']) *
            fe.Constant(INPUTS['solubility'] *
                        gas_constant * INPUTS['temperature']),
            degree=0
        )
    # assign 1 to gas domain, and 0 to solid domain
    gas_content = SubdomainConstant(
        subdomains,
        fe.Constant(1.0),
        fe.Constant(0.0),
        degree=0
    )
    # define structure of foam over whole domain
    structure = fe.project(unit_function * gas_content, dis_func_space)
    # calculate porosity and wall thickness
    porosity = fe.assemble(structure *
                           fe.dx) / ((XMAX - XMIN) * (YMAX - YMIN) * (ZMAX - ZMIN))
    print('Porosity: {0}'.format(porosity))
    dwall = wall_thickness(
        porosity, INPUTS['morphology']['cell_size'],
        INPUTS['morphology']['strut_content'])
    print('Wall thickness: {0} m'.format(dwall))
    # calculate effective conductivity/diffusivity by analytical model
    if INPUTS['mode'] == 'conductivity':
        eff_prop = analytical_conductivity(
            INPUTS['conductivity']['gas'], INPUTS['conductivity']['solid'],
            porosity, INPUTS['morphology']['strut_content'])
        print('Analytical model: {0} W/(mK)'.format(eff_prop))
    elif INPUTS['mode'] == 'diffusivity':
        eff_prop = analytical_diffusivity(
            INPUTS['diffusivity']['solid'] *
            INPUTS['solubility'], INPUTS['solubility'],
            porosity, INPUTS['morphology']['cell_size'], dwall,
            INPUTS['temperature'], INPUTS['morphology']['enhancement_par'])
        print('Analytical model: {0} m^2/s'.format(eff_prop))
    # create system matrix
    system_matrix = -mat_prop * \
        fe.inner(fe.grad(field), fe.grad(test_func)) * fe.dx
    left_side, right_side = fe.lhs(system_matrix), fe.rhs(system_matrix)
    # define boundary conditions
    bcs = [
        fe.DirichletBC(func_space, fe.Constant(
            INPUTS['boundary_conditions']['top']), top_bc),
        fe.DirichletBC(func_space, fe.Constant(
            INPUTS['boundary_conditions']['bottom']), bottom_bc)
    ]
    # compute solution
    field = fe.Function(func_space)
    fe.solve(left_side == right_side, field, bcs)
    # output temperature/concentration at the boundaries
    if ARGS['--verbose']:
        print('Checking periodicity:')
        print('Value at XMIN:', field(XMIN, (YMIN + YMAX) / 3, (ZMIN + ZMAX) / 3))
        print('Value at XMAX:', field(XMAX, (YMIN + YMAX) / 3, (ZMIN + ZMAX) / 3))
        print('Value at YMIN:', field((XMIN + XMAX) / 3, YMIN, (ZMIN + ZMAX) / 3))
        print('Value at YMAX:', field((XMIN + XMAX) / 3, YMAX, (ZMIN + ZMAX) / 3))
        print('Value at ZMIN:', field((XMIN + XMAX) / 3, (YMIN + YMAX) / 3, ZMIN))
        print('Value at ZMAX:', field((XMIN + XMAX) / 3, (YMIN + YMAX) / 3, ZMAX))
    # calculate flux, and effective properties
    vec_func_space = fe.VectorFunctionSpace(
        mesh,
        INPUTS['element_type'],
        INPUTS['element_degree']
    )
    flux = fe.project(-mat_prop * fe.grad(field), vec_func_space)
    divergence = fe.project(-fe.div(mat_prop * fe.grad(field)), func_space)
    flux_x, flux_y, flux_z = flux.split()
    av_flux = fe.assemble(flux_z * fe.dx) / ((XMAX - XMIN) * (YMAX - YMIN))
    eff_prop = av_flux * (ZMAX - ZMIN) / (
        INPUTS['boundary_conditions']['top']
        - INPUTS['boundary_conditions']['bottom']
    )
    if INPUTS['mode'] == 'conductivity':
        print('Numerical model: {0} W/(mK)'.format(eff_prop))
    elif INPUTS['mode'] == 'diffusivity':
        print('Numerical model: {0} m^2/s'.format(eff_prop))
    # projection of concentration has to be in discontinuous function space
    if INPUTS['mode'] == 'diffusivity':
        sol_field = SubdomainConstant(
            subdomains,
            fe.Constant(1.0),
            fe.Constant(INPUTS['solubility'] *
                        gas_constant * INPUTS['temperature']),
            degree=0
        )
        field = fe.project(field * sol_field, dis_func_space)
    # save results
    with open(fname + "_eff_prop.csv", 'w') as textfile:
        textfile.write('eff_prop\n')
        textfile.write('{0}\n'.format(eff_prop))
    fe.File(fname + "_solution.pvd") << field
    fe.File(fname + "_structure.pvd") << structure
    if INPUTS['saving']['flux']:
        fe.File(fname + "_flux.pvd") << flux
    if INPUTS['saving']['flux_divergence']:
        fe.File(fname + "_flux_divergence.pvd") << divergence
    if INPUTS['saving']['flux_components']:
        fe.File(fname + "_flux_x.pvd") << flux_x
        fe.File(fname + "_flux_y.pvd") << flux_y
        fe.File(fname + "_flux_z.pvd") << flux_z
    # plot results
    if INPUTS['plotting']['solution']:
        fe.plot(field, title="Solution")
    if INPUTS['plotting']['flux']:
        fe.plot(flux, title="Flux")
    if INPUTS['plotting']['flux_divergence']:
        fe.plot(divergence, title="Divergence")
    if INPUTS['plotting']['flux_components']:
        fe.plot(flux_x, title='x-component of flux (-kappa*grad(u))')
        fe.plot(flux_y, title='y-component of flux (-kappa*grad(u))')
        fe.plot(flux_z, title='z-component of flux (-kappa*grad(u))')
    if True in INPUTS['plotting'].values():
        fe.interactive()
    print(
        term.yellow
        + "End."
        + term.normal
    )