Beispiel #1
0
    def solve(self, mesh, num=5):
        """ Solve for num eigenvalues based on the mesh. """
        # conforming elements
        V = FunctionSpace(mesh, "CG", self.degree)
        u = TrialFunction(V)
        v = TestFunction(V)

        # weak formulation
        a = inner(grad(u), grad(v)) * dx
        b = u * v * ds
        A = PETScMatrix()
        B = PETScMatrix()
        A = assemble(a, tensor=A)
        B = assemble(b, tensor=B)

        # find eigenvalues
        eigensolver = SLEPcEigenSolver(A, B)
        eigensolver.parameters["spectral_transform"] = "shift-and-invert"
        eigensolver.parameters["problem_type"] = "gen_hermitian"
        eigensolver.parameters["spectrum"] = "smallest real"
        eigensolver.parameters["spectral_shift"] = 1.0E-10
        eigensolver.solve(num + 1)

        # extract solutions
        lst = [
            eigensolver.get_eigenpair(i) for i in range(
                1,
                eigensolver.get_number_converged())]
        for k in range(len(lst)):
            u = Function(V)
            u.vector()[:] = lst[k][2]
            lst[k] = (lst[k][0], u)  # pair (eigenvalue,eigenfunction)
        return np.array(lst)
Beispiel #2
0
    def weak_form(self):

        from bempp.api.assembly.discrete_boundary_operator import SparseDiscreteBoundaryOperator

        if self._sparse_mat is not None:
            return SparseDiscreteBoundaryOperator(self._sparse_mat)

        backend = parameters['linear_algebra_backend']
        if backend not in ['PETSc', 'uBLAS']:
            parameters['linear_algebra_backend'] = 'PETSc'

        if parameters['linear_algebra_backend'] == 'PETSc':
            A = as_backend_type(assemble(self._fenics_weak_form)).mat()
            (indptr, indices, data) = A.getValuesCSR()
            self._sparse_mat = csr_matrix((data, indices, indptr), shape=A.size)
        elif parameters['linear_algebra_backend'] == 'uBLAS':
            self._sparse_mat = assemble(self._fenics_weak_form).sparray()
        else:
            raise ValueError(
                "This should not happen! Backend type is '{0}'. " +
                "Default backend should have been set to 'PETSc'.".format(
                    parameters['linear_algebra_backend']))

        parameters['linear_algebra_backend'] = backend
        return SparseDiscreteBoundaryOperator(self._sparse_mat)
Beispiel #3
0
  def M_inv_diag(self, domain = "all"):
    """
    Returns the inverse lumped mass matrix for the vector function space.
    The result ist cached.

    .. note:: This method requires the PETSc Backend to be enabled.

    *Returns*
      :class:`dolfin.Matrix`
        the matrix
    """
    if not self._M_inv_diag.has_key(domain):
      v = TestFunction(self.VectorFunctionSpace())
      u = TrialFunction(self.VectorFunctionSpace())

      mass_form = inner(v, u) * self.dx(domain)
      mass_action_form = action(mass_form, Constant((1.0, 1.0, 1.0)))
      diag = assemble(mass_action_form)
      as_backend_type(diag).vec().reciprocal()

      result = assemble(inner(v, u) * dP)
      result.zero()
      result.set_diagonal(diag)
      self._M_inv_diag[domain] = result

    return self._M_inv_diag[domain]
def transpose_operators(operators):
    out = [None, None]

    for i in range(2):
        op = operators[i]

        if op is None:
            out[i] = None
        elif isinstance(op, dolfin.cpp.GenericMatrix):
            out[i] = op.__class__()
            dolfin.assemble(dolfin.adjoint(op.form), tensor=out[i])

            if hasattr(op, 'bcs'):
                adjoint_bcs = [utils.homogenize(bc) for bc in op.bcs if isinstance(bc, dolfin.cpp.DirichletBC)] + [bc for bc in op.bcs if not isinstance(bc, dolfin.DirichletBC)]
                [bc.apply(out[i]) for bc in adjoint_bcs]

        elif isinstance(op, dolfin.Form) or isinstance(op, ufl.form.Form):
            out[i] = dolfin.adjoint(op)

            if hasattr(op, 'bcs'):
                out[i].bcs = [utils.homogenize(bc) for bc in op.bcs if isinstance(bc, dolfin.cpp.DirichletBC)] + [bc for bc in op.bcs if not isinstance(bc, dolfin.DirichletBC)]

        elif isinstance(op, AdjointKrylovMatrix):
            pass

        else:
            print "op.__class__: ", op.__class__
            raise libadjoint.exceptions.LibadjointErrorNotImplemented("Don't know how to transpose anything else!")

    return out
Beispiel #5
0
def test_krylov_solver_norm_type():
    """Check setting of norm type used in testing for convergence by
    PETScKrylovSolver

    """

    norm_type = (PETScKrylovSolver.norm_type.default_norm,
                 PETScKrylovSolver.norm_type.natural,
                 PETScKrylovSolver.norm_type.preconditioned,
                 PETScKrylovSolver.norm_type.none,
                 PETScKrylovSolver.norm_type.unpreconditioned)

    for norm in norm_type:
        # Solve a system of equations
        mesh = UnitSquareMesh(4, 4)
        V = FunctionSpace(mesh, "Lagrange", 1)
        u, v = TrialFunction(V), TestFunction(V)
        a = u*v*dx
        L = Constant(1.0)*v*dx
        A, b = assemble(a), assemble(L)

        solver = PETScKrylovSolver("cg")
        solver.parameters["maximum_iterations"] = 2
        solver.parameters["error_on_nonconvergence"] = False
        solver.set_norm_type(norm)
        solver.set_operator(A)
        solver.solve(b.copy(), b)
        solver.get_norm_type()

        if norm is not PETScKrylovSolver.norm_type.default_norm:
            assert solver.get_norm_type() == norm
Beispiel #6
0
  def calculate_cell_powers(self):
    """
    Calculates cell-integrated powers (sets :attr:`E`). Also performs normalization to the specified core(-fraction)
    power (:attr:`core.power`).

    Note that the array is ordered by the associated DG(0) dof, not by the cell index in the mesh.
    """
    q_calc_timer = Timer("FM: Calculation of cell powers")
    ass_timer = Timer("FM: Assemble cell powers")

    if self.verb > 2:
      print0(self.print_prefix + "  calculating cell-wise powers.")

    self.E.fill(0)

    if not self.up_to_date["flux"]:
      self.update_phi()

    for g in xrange(self.DD.G):
      self.PD.get_xs('eSf', self.R, g)

      ass_timer.start()
      self.phig.assign(self.phi_mg[g])
      assemble(self.cell_RR_form, tensor=self._cell_RRg_vector)
      ass_timer.stop()

      self.E += self._cell_RRg_vector.get_local()

    self.up_to_date["cell_powers"] = True
    self.normalize_cell_powers()
Beispiel #7
0
 def assemble_L(self):
     #------------------------------
     # evaluate numerically, adding the real and imaginary parts
     L = self.get_L_form()
     L_theta = dolfin.assemble(L['r_theta']) + 1j*dolfin.assemble(L['i_theta'])
     L_phi = dolfin.assemble(L['r_phi']) + 1j*dolfin.assemble(L['i_phi'])
     return (L_theta, L_phi)
Beispiel #8
0
 def assemble_N(self):
     #------------------------------
     # evaluate numerically, adding the real and imaginary parts
     N = self.get_N_form()
     N_theta = dolfin.assemble(N['r_theta']) + 1j*dolfin.assemble(N['i_theta'])
     N_phi = dolfin.assemble(N['r_phi']) + 1j*dolfin.assemble(N['i_phi'])
     return (N_theta, N_phi)
Beispiel #9
0
    def __init__(self, u_, Space, bcs=[], name="div", method={}):

        solver_type = method.get('solver_type', 'cg')
        preconditioner_type = method.get('preconditioner_type', 'default')
        solver_method = method.get('method', 'default')
        low_memory_version = method.get('low_memory_version', False)

        OasisFunction.__init__(self, div(u_), Space, bcs=bcs, name=name,
                               method=solver_method, solver_type=solver_type,
                               preconditioner_type=preconditioner_type)

        Source = u_[0].function_space()
        if not low_memory_version:
            self.matvec = [[A_cache[(self.test * TrialFunction(Source).dx(i) * dx, ())], u_[i]]
                           for i in range(Space.mesh().geometry().dim())]

        if solver_method.lower() == "gradient_matrix":
            from fenicstools import compiled_gradient_module
            DG = FunctionSpace(Space.mesh(), 'DG', 0)
            G = assemble(TrialFunction(DG) * self.test * dx())
            dg = Function(DG)
            self.WGM = []
            st = TrialFunction(Source)
            for i in range(Space.mesh().geometry().dim()):
                dP = assemble(st.dx(i) * TestFunction(DG) * dx)
                A = Matrix(G)
                self.WGM.append(compiled_gradient_module.compute_weighted_gradient_matrix(A, dP, dg))
Beispiel #10
0
 def compute_err(self, is_tent, velocity, t):
     if self.doErrControl:
         er_list_L2 = self.listDict['u2L2' if is_tent else 'u_L2']['list']
         er_list_H1 = self.listDict['u2H1' if is_tent else 'u_H1']['list']
         self.tc.start('errorV')
         # assemble is faster than errornorm
         errorL2_sq = assemble(inner(velocity - self.solution, velocity - self.solution) * dx)
         errorH1seminorm_sq = assemble(inner(grad(velocity - self.solution), grad(velocity - self.solution)) * dx)
         info('  H1 seminorm error: %f' % sqrt(errorH1seminorm_sq))
         errorL2 = sqrt(errorL2_sq)
         errorH1 = sqrt(errorL2_sq + errorH1seminorm_sq)
         info("  Relative L2 error in velocity = %f" % (errorL2 / self.analytic_v_norm_L2))
         self.last_error = errorH1 / self.analytic_v_norm_H1
         self.last_status_functional = self.last_error
         info("  Relative H1 error in velocity = %f" % self.last_error)
         er_list_L2.append(errorL2)
         er_list_H1.append(errorH1)
         self.tc.end('errorV')
         if self.testErrControl:
             er_list_test_H1 = self.listDict['u2H1test' if is_tent else 'u_H1test']['list']
             er_list_test_L2 = self.listDict['u2L2test' if is_tent else 'u_L2test']['list']
             self.tc.start('errorVtest')
             er_list_test_L2.append(errornorm(velocity, self.solution, norm_type='L2', degree_rise=0))
             er_list_test_H1.append(errornorm(velocity, self.solution, norm_type='H1', degree_rise=0))
             self.tc.end('errorVtest')
         # stopping criteria for detecting diverging solution
         if self.last_error > self.divergence_treshold:
             raise RuntimeError('STOPPED: Failed divergence test!')
    def initialize(self, V, Q, PS, D):
        super(Problem, self).initialize(V, Q, PS, D)

        print("IC type: " + self.ic)
        print("Velocity scale factor = %4.2f" % self.factor)
        reynolds = 728.761 * self.factor  # TODO modify by nu_factor
        print("Computing with Re = %f" % reynolds)

        self.v_in = Function(V)
        print('Initializing error control')
        self.load_precomputed_bessel_functions(PS)
        self.solution = self.assemble_solution(0.0)

        # set constants for
        self.area = assemble(interpolate(Expression("1.0"), Q) * self.dsIn)  # inflow area

        # womersley = steady + e^iCt, e^iCt has average 0
        self.pg_normalization_factor.append(womersleyBC.average_analytic_pressure_grad(self.factor))
        self.p_normalization_factor.append(norm(
            interpolate(womersleyBC.average_analytic_pressure_expr(self.factor), self.pSpace), norm_type='L2'))
        self.vel_normalization_factor.append(norm(
            interpolate(womersleyBC.average_analytic_velocity_expr(self.factor), self.vSpace), norm_type='L2'))
        # print('Normalisation factors (vel, p, pg):', self.vel_normalization_factor[0], self.p_normalization_factor[0],
        #       self.pg_normalization_factor[0])

        one = (interpolate(Expression('1.0'), Q))
        self.outflow_area = assemble(one*self.dsOut)
        print('Outflow area:', self.outflow_area)
Beispiel #12
0
def les_update(nut_, nut_form, A_mass, At, u_, dt, bc_ksgs, bt, ksgs_sol,
        KineticEnergySGS, CG1, ksgs, delta, **NS_namespace):

    p, q = TrialFunction(CG1), TestFunction(CG1)

    Ck = KineticEnergySGS["Ck"]
    Ce = KineticEnergySGS["Ce"]

    Sij = sym(grad(u_))
    assemble(dt*inner(dot(u_, 0.5*grad(p)), q)*dx
             + inner((dt*Ce*sqrt(ksgs)/delta)*0.5*p, q)*dx
             + inner(dt*Ck*sqrt(ksgs)*delta*grad(0.5*p), grad(q))*dx, tensor=At)
    
    assemble(dt*2*Ck*delta*sqrt(ksgs)*inner(Sij,grad(u_))*q*dx, tensor=bt)
    bt.axpy(1.0, A_mass*ksgs.vector())
    bt.axpy(-1.0, At*ksgs.vector())
    At.axpy(1.0, A_mass, True)

    # Solve for ksgs
    bc_ksgs.apply(At, bt)
    ksgs_sol.solve(At, ksgs.vector(), bt)
    ksgs.vector().set_local(ksgs.vector().array().clip(min=1e-7))
    ksgs.vector().apply("insert")

    # Update nut_
    nut_()
Beispiel #13
0
def check_ass_penaro(bcsd=None, bcssfuns=None, V=None, plot=False):
    mesh = V.mesh()

    bcone = bcsd[1]
    contshfunone = bcssfuns[1]
    Gammaone = bcone()

    bparts = dolfin.MeshFunction('size_t', mesh, mesh.topology().dim() - 1)
    Gammaone.mark(bparts, 0)

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

    # Robin boundary form
    arob = dolfin.inner(u, v) * dolfin.ds(0)
    brob = dolfin.inner(v, contshfunone) * dolfin.ds(0)

    amatrob = dolfin.assemble(arob, exterior_facet_domains=bparts)
    bmatrob = dolfin.assemble(brob, exterior_facet_domains=bparts)

    amatrob = dts.mat_dolfin2sparse(amatrob)
    amatrob.eliminate_zeros()
    print 'Number of nonzeros in amatrob:', amatrob.nnz
    bmatrob = bmatrob.array()  # [ININDS]

    if plot:
        plt.figure(2)
        plt.spy(amatrob)

    if plot:
        plt.figure(1)
        for x in contshfunone.xs:
            plt.plot(x[0], x[1], 'bo')

    plt.show()
Beispiel #14
0
def weighted_gradient_matrix(mesh, i, degree=1, constrained_domain=None):
    """Compute weighted gradient matrix
    
    The matrix allows us to compute the gradient of a P1 Function 
    through a simple matrix vector product
    
      p_ is the pressure solution on CG1
      dPdX = weighted_gradient_matrix(mesh, 0, degree)
      V = FunctionSpace(mesh, 'CG', degree)
      dpdx = Function(V)
      dpdx.vector()[:] = dPdX * p_.vector()
      
      The space for dpdx must be continuous Lagrange of some order
      
    """
    DG = FunctionSpace(mesh, 'DG', 0)
    CG = FunctionSpace(mesh, 'CG', degree, constrained_domain=constrained_domain)
    CG1 = FunctionSpace(mesh, 'CG', 1, constrained_domain=constrained_domain)
    C = assemble(TrialFunction(CG)*TestFunction(CG)*dx)
    G = assemble(TrialFunction(DG)*TestFunction(CG)*dx)
    dg = Function(DG)
    if isinstance(i, (tuple, list)):
        CC = []
        for ii in i:
            dP = assemble(TrialFunction(CG1).dx(ii)*TestFunction(DG)*dx)
            A = Matrix(G)
            compiled_gradient_module.compute_weighted_gradient_matrix(A, dP, C, dg)
            CC.append(C.copy())
        return CC
    else:
        dP = assemble(TrialFunction(CG1).dx(i)*TestFunction(DG)*dx)
        compiled_gradient_module.compute_weighted_gradient_matrix(G, dP, C, dg)
        return C
Beispiel #15
0
 def save_pressure(self, is_tent, pressure):
     super(Problem, self).save_pressure(is_tent, pressure)
     self.tc.start('computePG')
     # Report pressure gradient
     p_in = assemble((1.0/self.area) * pressure * self.dsIn)
     p_out = assemble((1.0/self.area) * pressure * self.dsOut)
     computed_gradient = (p_in - p_out)/20.0
     # 20.0 is a length of a pipe NT should depend on mesh length (implement through metadata or function of mesh)
     self.tc.end('computePG')
     self.tc.start('errorP')
     error = errornorm(self.sol_p, pressure, norm_type="l2", degree_rise=0)
     self.listDict['p2' if is_tent else 'p']['list'].append(error)
     print("Normalized pressure error norm:", error/self.p_normalization_factor[0])
     self.listDict['pg2' if is_tent else 'pg']['list'].append(computed_gradient)
     if not is_tent:
         self.listDict['apg']['list'].append(self.analytic_gradient)
     self.listDict['pgE2' if is_tent else 'pgE']['list'].append(computed_gradient-self.analytic_gradient)
     self.listDict['pgEA2' if is_tent else 'pgEA']['list'].append(abs(computed_gradient-self.analytic_gradient))
     self.tc.end('errorP')
     if self.doSaveDiff:
         sol_pg_expr = Expression(("0", "0", "pg"), pg=self.analytic_gradient / self.pg_normalization_factor[0])
         # sol_pg = interpolate(sol_pg_expr, self.pgSpace)
         # plot(sol_p, title="sol")
         # plot(pressure, title="p")
         # plot(pressure - sol_p, interactive=True, title="diff")
         # exit()
         self.pFunction.assign(pressure-self.sol_p)
         self.fileDict['p2D' if is_tent else 'pD']['file'] << self.pFunction
Beispiel #16
0
 def gp(self, Bt):
     """Assemble discrete pressure gradient. It is crucial to respect any
     constraints placed on the velocity test space by Dirichlet boundary
     conditions."""
     assemble(self.get_dolfin_form("gp"), tensor=Bt)
     for bc in self._bcs:
         bc.apply(Bt)
Beispiel #17
0
 def identity_at_coarse_level(self):
   I = PETScMatrix()
   u = TrialFunction(self.V_coarse)
   v = TestFunction(self.V_coarse)
   assemble(Constant(0)*u*v*dx, tensor=I)
   I.ident_zeros()
   return I
Beispiel #18
0
  def __init__(self, coarse_mesh, nref, p_coarse, p_fine):
    super(LaplaceEigenvalueProblem, self).__init__(coarse_mesh, nref, p_coarse, p_fine)

    print0("Assembling fine-mesh problem")

    self.dirichlet_bdry = lambda x,on_boundary: on_boundary

    bc = DirichletBC(self.V_fine, 0.0, self.dirichlet_bdry)
    u = TrialFunction(self.V_fine)
    v = TestFunction(self.V_fine)
    a = inner(grad(u), grad(v))*dx
    m = u*v*dx

    # Assemble the stiffness matrix and the mass matrix.
    b = v*dx # just need this to feed an argument to assemble_system
    assemble_system(a, b, bc, A_tensor=self.A_fine)
    assemble_system(m, b, bc, A_tensor=self.B_fine)
    # set the diagonal elements of M corresponding to boundary nodes to zero to
    # remove spurious eigenvalues.
    bc.zero(self.B_fine)

    print0("Assembling coarse-mesh problem")

    self.bc_coarse = DirichletBC(self.V_coarse, 0.0, self.dirichlet_bdry)
    u = TrialFunction(self.V_coarse)
    v = TestFunction(self.V_coarse)
    a = inner(grad(u), grad(v))*dx
    m = u*v*dx

    # Assemble the stiffness matrix and the mass matrix, without Dirichlet BCs. Dirichlet DOFs will be removed later.
    assemble(a, tensor=self.A_coarse)
    assemble(m, tensor=self.B_coarse)
Beispiel #19
0
    def initialize(self, V, Q, PS, D):
        super(Problem, self).initialize(V, Q, PS, D)

        print("IC type: " + self.ic)
        print("Velocity scale factor = %4.2f" % self.factor)
        reynolds = 728.761 * self.factor
        print("Computing with Re = %f" % reynolds)

        # set constants for
        self.area = assemble(interpolate(Expression("1.0"), Q) * self.dsIn)  # inflow area

        self.solution = interpolate(Expression(("0.0", "0.0", "factor*(1081.48-43.2592*(x[0]*x[0]+x[1]*x[1]))"),
                                               factor=self.factor), self.vSpace)
        analytic_pressure = womersleyBC.average_analytic_pressure_expr(self.factor)
        self.sol_p = interpolate(analytic_pressure, self.pSpace)
        self.analytic_gradient = womersleyBC.average_analytic_pressure_grad(self.factor)
        self.analytic_pressure_norm = norm(self.sol_p, norm_type='L2')
        self.analytic_v_norm_L2 = norm(self.solution, norm_type='L2')
        self.analytic_v_norm_H1 = norm(self.solution, norm_type='H1')
        self.analytic_v_norm_H1w = sqrt(assemble((inner(grad(self.solution), grad(self.solution)) +
                                                  inner(self.solution, self.solution)) * self.dsWall))
        print("Prepared analytic solution.")

        self.pg_normalization_factor.append(womersleyBC.average_analytic_pressure_grad(self.factor))
        self.p_normalization_factor.append(self.analytic_pressure_norm)
        self.vel_normalization_factor.append(norm(self.solution, norm_type='L2'))

        print('Normalisation factors (vel, p, pg):', self.vel_normalization_factor[0], self.p_normalization_factor[0],
              self.pg_normalization_factor[0])

        one = (interpolate(Expression('1.0'), Q))
        self.outflow_area = assemble(one*self.dsOut)
        print('Outflow area:', self.outflow_area)
    def setup_forms(self, old_solver):
        prob = self.prob

        if old_solver is not None:
            self.old_vel = dfn.interpolate(old_solver.old_vel,
                                                     prob.v_fnc_space)
            self.cur_vel = dfn.interpolate(old_solver.cur_vel,
                                                     prob.v_fnc_space)
        else:
            self.old_vel = dfn.Function(prob.v_fnc_space)
            self.cur_vel = dfn.Function(prob.v_fnc_space)

        # Assemble matrices from variational forms. Ax = Ls
        self.a = dfn.inner(dfn.grad(prob.v), dfn.grad(prob.vt)) * dfn.dx
        self.A = dfn.assemble(self.a)

        if params['bcs'] is 'test':
            self.bcs = get_test_bcs(prob.v_fnc_space, test_bc)
        else:
            self.bcs = get_normal_bcs(prob.v_fnc_space, test_bc)

        # For the gradient term in the stress update
        self.l_elastic = self.dt * self.mu * \
            dfn.inner(dfn.grad(prob.v), prob.St) * dfn.dx
        self.L_elastic = dfn.assemble(self.l_elastic)
 def mult(self, lamhat, y):
     """
     mult(self, lamhat, y): return y = Hessian * lamhat
     inputs:
         y, lamhat = Function(V).vector()
     """
     self.regularization.assemble_hessian(lamhat)
     setfct(self.lamhat, lamhat)
     self.C = assemble(self.wkformrhsincr)
     if self.PDE.abc:    self.Dp = assemble(self.wkformDprime)
     # solve for phat
     self.PDE.set_fwd()
     self.PDE.ftime = self.ftimeincrfwd
     self.solincrfwd,_ = self.PDE.solve()
     # solve for vhat
     self.PDE.set_adj()
     self.PDE.ftime = self.ftimeincradj
     self.solincradj,_ = self.PDE.solve()
     # Compute Hessian*lamhat
     y.zero()
     index = 0
     if self.PDE.abc:
         self.vD.vector().zero(); self.vhatD.vector().zero(); 
         self.p1D.vector().zero(); self.p2D.vector().zero();
         self.p1hatD.vector().zero(); self.p2hatD.vector().zero();
     for fwd, adj, incrfwd, incradj, fact in \
     zip(self.solfwd, reversed(self.soladj), \
     self.solincrfwd, reversed(self.solincradj), self.factors):
         ttf, tta, ttf2 = incrfwd[1], incradj[1], fwd[1]
         assert isequal(ttf, tta, 1e-16), 'tfwd={}, tadj={}, reldiff={}'.\
         format(ttf, tta, abs(ttf-tta)/ttf)
         assert isequal(ttf, ttf2, 1e-16), 'tfwd={}, tadj={}, reldiff={}'.\
         format(ttf, ttf2, abs(ttf-ttf2)/ttf)
         setfct(self.p, fwd[0])
         setfct(self.v, adj[0])
         setfct(self.phat, incrfwd[0])
         setfct(self.vhat, incradj[0])
         y.axpy(fact, assemble(self.wkformhess))
         if self.PDE.abc:
             if index%2 == 0:
                 self.p2D.vector().axpy(1.0, self.p.vector())
                 self.p2hatD.vector().axpy(1.0, self.phat.vector())
                 setfct(self.dp, self.p2D)
                 setfct(self.dph, self.p2hatD)
                 y.axpy(1.0*0.5*self.invDt, assemble(self.wkformhessD))
                 setfct(self.p2D, -1.0*self.p.vector())
                 setfct(self.p2hatD, -1.0*self.phat.vector())
             else:
                 self.p1D.vector().axpy(1.0, self.p.vector())
                 self.p1hatD.vector().axpy(1.0, self.phat.vector())
                 setfct(self.dp, self.p1D)
                 setfct(self.dph, self.p1hatD)
                 y.axpy(1.0*0.5*self.invDt, assemble(self.wkformhessD))
                 setfct(self.p1D, -1.0*self.p.vector())
                 setfct(self.p1hatD, -1.0*self.phat.vector())
             setfct(self.vD, self.v)
             setfct(self.vhatD, self.vhat)
         index += 1
     # add regularization term
     y.axpy(self.alpha_reg, self.regularization.hessian(lamhat))
Beispiel #22
0
    def __init__(self, Vh, dX, bcs, form = None):
        """
        Constructor:

            :code:`Vh`: the finite element space for the state variable.
            
            :code:`dX`: the integrator on subdomain `X` where observation are presents. \
            E.g. :code:`dX = dl.dx` means observation on all :math:`\Omega` and :code:`dX = dl.ds` means observations on all :math:`\partial \Omega`.
            
            :code:`bcs`: If the forward problem imposes Dirichlet boundary conditions :math:`u = u_D \mbox{ on } \Gamma_D`;  \
            :code:`bcs` is a list of :code:`dolfin.DirichletBC` object that prescribes homogeneuos Dirichlet conditions :math:`u = 0 \mbox{ on } \Gamma_D`.
            
            :code:`form`: if :code:`form = None` we compute the :math:`L^2(X)` misfit: :math:`\int_X (u - u_d)^2 dX,` \
            otherwise the integrand specified in the given form will be used.
        """
        if form is None:
            u, v = dl.TrialFunction(Vh), dl.TestFunction(Vh)
            self.W = dl.assemble(dl.inner(u,v)*dX)
        else:
            self.W = dl.assemble( form )
           
        if bcs is None:
            bcs  = []
        if isinstance(bcs, dl.DirichletBC):
            bcs = [bcs]
            
        if len(bcs):
            Wt = Transpose(self.W)
            [bc.zero(Wt) for bc in bcs]
            self.W = Transpose(Wt)
            [bc.zero(self.W) for bc in bcs]
                
        self.d = dl.Vector(self.W.mpi_comm())
        self.W.init_vector(self.d,1)
        self.noise_variance = None
Beispiel #23
0
def assemble_AA_BB(aa, bb, pp=None, cc=None):
    '''
    Return assembled system matrix [[aa, bb.T], [bb, 0]] and its preconditioner
    [[pp, 0], [cc]] from forms.
    '''
    # Get the blocks
    A = assemble(aa)
    B = assemble(bb)

    n = A.size(0)
    N = n + B.size(0)

    print 'System has size', N

    # Assemble system matrix and get its condition number
    AA = np.zeros((N, N))
    AA[:n, :n] = A.array()
    AA[:n, n:] = B.array().T
    AA[n:, :n] = B.array()
    AA = csr_matrix(AA)         # convert to sparse

    if pp is None and cc is None:
        return AA
    else:
        P = assemble(pp)
        C = assemble(cc)

        BB = np.zeros((N, N))
        BB[:n, :n] = P.array()
        BB[n:, n:] = C.array()
        BB = csr_matrix(BB)

        return AA, BB
def setget_rhs(V, Q, fv, fp, t=None):

    if t is not None:
        fv.t = t
        fp.t = t
    elif hasattr(fv, 't') or hasattr(fp, 't'):
        Warning('No value for t specified')

    v = dolfin.TestFunction(V)
    q = dolfin.TestFunction(Q)

    fv = inner(fv, v) * dx
    fp = inner(fp, q) * dx

    fv = dolfin.assemble(fv)
    fp = dolfin.assemble(fp)

    fv = fv.get_local()
    fv = fv.reshape(len(fv), 1)

    fp = fp.get_local()
    fp = fp.reshape(len(fp), 1)

    rhsvecs = {'fv': fv,
               'fp': fp}

    return rhsvecs
def get_voltage_current_matrix(phi, physical_indices, dx,
                               Sigma,
                               omega,
                               v_ref
                               ):
    '''Compute the matrix that relates the voltages with the currents in the
    coil rings. (The relationship is indeed linear.)

    This is according to :cite:`KP02`.

    The entry :math:`J_{k,l}` in the resulting matrix is the contribution of
    the potential generated by coil :math:`l` to the current in coil :math:`k`.
    '''
    mesh = phi[0].function_space().mesh()
    r = Expression('x[0]', degree=1, domain=mesh)

    num_coil_rings = len(phi)
    J = numpy.empty((num_coil_rings, num_coil_rings), dtype=numpy.complex)
    for l, pi0 in enumerate(physical_indices):
        partial_phi_r, partial_phi_i = phi[l].split()
        for k, pi1 in enumerate(physical_indices):
            # -1i*omega*int_{coil_k} sigma phi.
            int_r = assemble(Sigma[pi1] * partial_phi_r * dx(pi1))
            int_i = assemble(Sigma[pi1] * partial_phi_i * dx(pi1))
            J[k][l] = -1j * omega * (int_r + 1j * int_i)
        # v_ref/(2*pi) * int_{coil_l} sigma/r.
        # 1/r doesn't explode since we only evaluate it in the coils where
        # r!=0.
        # For assemble() to work, a mesh needs to be supplied either implicitly
        # by the integrand, or explicitly. Since the integrand doesn't contain
        # mesh information here, pass it through explicitly.
        J[l][l] += v_ref / (2 * pi) \
            * assemble(Sigma[pi0] / r * dx(pi0))
    return J
Beispiel #26
0
    def __init__(self, p_, Space, i=0, bcs=[], name="grad", method={}):

        assert len(p_.ufl_shape) == 0
        assert i >= 0 and i < Space.mesh().geometry().dim()

        solver_type = method.get('solver_type', 'cg')
        preconditioner_type = method.get('preconditioner_type', 'default')
        solver_method = method.get('method', 'default')
        low_memory_version = method.get('low_memory_version', False)

        OasisFunction.__init__(self, p_.dx(i), Space, bcs=bcs, name=name,
                               method=solver_method, solver_type=solver_type,
                               preconditioner_type=preconditioner_type)

        self.i = i
        Source = p_.function_space()
        if not low_memory_version:
            self.matvec = [
                A_cache[(self.test * TrialFunction(Source).dx(i) * dx, ())], p_]

        if solver_method.lower() == "gradient_matrix":
            from fenicstools import compiled_gradient_module
            DG = FunctionSpace(Space.mesh(), 'DG', 0)
            G = assemble(TrialFunction(DG) * self.test * dx())
            dg = Function(DG)
            dP = assemble(TrialFunction(p_.function_space()).dx(i)
                          * TestFunction(DG) * dx())
            self.WGM = compiled_gradient_module.compute_weighted_gradient_matrix(
                G, dP, dg)
Beispiel #27
0
def test_krylov_solver_options_prefix(pushpop_parameters):
    "Test set/get PETScKrylov solver prefix option"

    # Set backend
    parameters["linear_algebra_backend"] = "PETSc"

    # Prefix
    prefix = "test_foo_"

    # Create solver and set prefix
    solver = PETScKrylovSolver()
    solver.set_options_prefix(prefix)

    # Check prefix (pre solve)
    assert solver.get_options_prefix() == prefix

    # Solve a system of equations
    mesh = UnitSquareMesh(4, 4)
    V = FunctionSpace(mesh, "Lagrange", 1)
    u, v = TrialFunction(V), TestFunction(V)
    a, L = u*v*dx, Constant(1.0)*v*dx
    A, b = assemble(a), assemble(L)
    solver.set_operator(A)
    solver.solve(b.copy(), b)

    # Check prefix (post solve)
    assert solver.get_options_prefix() == prefix
Beispiel #28
0
    def __init__(self, aneurysm, near_vessel, *args, **kwargs):
        Field.__init__(self, *args, **kwargs)
        
        self.aneurysm = aneurysm
        self.near_vessel = near_vessel

        self.Vnv = assemble(Constant(1)*dx(near_vessel[1], domain=near_vessel[0].mesh(), subdomain_data=near_vessel[0]))
        self.Va = assemble(Constant(1)*dx(aneurysm[1], domain=aneurysm[0].mesh(), subdomain_data=aneurysm[0]))
Beispiel #29
0
    def __init__(self, cparams, dtype_u, dtype_f):
        """
        Initialization routine

        Args:
            cparams: 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)
        """

        # define the Dirichlet boundary
        def Boundary(x, on_boundary):
            return on_boundary

        # these parameters will be used later, so assert their existence
        assert 'c_nvars' in cparams
        assert 'nu' in cparams
        assert 't0' in cparams
        assert 'family' in cparams
        assert 'order' in cparams
        assert 'refinements' in cparams

        # add parameters as attributes for further reference
        for k,v in cparams.items():
            setattr(self,k,v)

        df.set_log_level(df.WARNING)

        # set mesh and refinement (for multilevel)
        mesh = df.UnitIntervalMesh(self.c_nvars)
        # mesh = df.UnitSquareMesh(self.c_nvars[0],self.c_nvars[1])
        for i in range(self.refinements):
            mesh = df.refine(mesh)

        # define function space for future reference
        self.V = df.FunctionSpace(mesh, self.family, self.order)
        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_heat2d,self).__init__(self.V,dtype_u,dtype_f)

        # Stiffness term (Laplace)
        u = df.TrialFunction(self.V)
        v = df.TestFunction(self.V)
        a_K = -1.0*df.inner(df.nabla_grad(u), self.nu*df.nabla_grad(v))*df.dx

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

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

        # set forcing term as expression
        self.g = df.Expression('-sin(a*x[0]) * (sin(t) - b*a*a*cos(t))',a=np.pi,b=self.nu,t=self.t0,degree=self.order)
        # self.g = df.Expression('-sin(a*x[0]) * sin(a*x[1]) * (sin(t) - b*2*a*a*cos(t))',a=np.pi,b=self.nu,t=self.t0,degree=self.order)
        # set boundary values
        self.bc = df.DirichletBC(self.V, df.Constant(0.0), Boundary)
Beispiel #30
0
    def compute(self, get):
        u = get("Velocity")
        assemble(dot(u[1].dx(0)-u[0].dx(1), self.q)*dx(), tensor=self.L)
        self.bc.apply(self.L)

        self.solver.solve(self.psi.vector(), self.L)
        #solve(self.A, self.psi.vector(), self.L)

        return self.psi
Beispiel #31
0
    def compile_continuation_data(self, load, iteration, perturbed):
        model = self.model
        u = self.solver.u
        alpha = self.solver.alpha

        if not perturbed:
            self.continuation_data_i = {}

            self.continuation_data_i["elastic_energy"] = assemble(model.elastic_energy_density(model.eps(u), alpha)*model.dx)
            if self.user_density is not None:
                self.continuation_data_i["elastic_energy"] += assemble(self.user_density*model.dx)
            self.continuation_data_i["dissipated_energy"] = assemble(model.damage_dissipation_density(alpha)*model.dx)

            self.continuation_data_i["total_energy"] = self.continuation_data_i["elastic_energy"] + self.continuation_data_i["dissipated_energy"]
            self.continuation_data_i["load"] = load
            self.continuation_data_i["iteration"] = iteration
            self.continuation_data_i["alpha_l2"] = alpha.vector().norm('l2')
            self.continuation_data_i["alpha_h1"] = norm(alpha, 'h1')
            self.continuation_data_i["alpha_max"] = np.max(alpha.vector()[:])
            self.continuation_data_i["eigs"] = self.stability.eigs

        else:
            elastic_post = assemble(model.elastic_energy_density(model.eps(u), alpha)*model.dx)
            if self.user_density is not None:
                elastic_post += assemble(self.user_density*model.dx)

            dissipated_post = assemble(model.damage_dissipation_density(alpha)*model.dx)

            self.continuation_data_i["elastic_energy_diff"] = elastic_post-self.continuation_data_i["elastic_energy"]
            self.continuation_data_i["dissipated_energy_diff"] = dissipated_post-self.continuation_data_i["dissipated_energy"]
            self.continuation_data_i["total_energy_diff"] = self.continuation_data_i["elastic_energy_diff"]\
                    +self.continuation_data_i["dissipated_energy_diff"]

            # ColorPrint.print_info('energy    {:4e}'.format(elastic_energy_post + dissipated_energy_post))
            # ColorPrint.print_info('estimate  {:4e}'.format(stability.en_estimate))
            # ColorPrint.print_info('en-est    {:4e}'.format(elastic_energy_post + dissipated_energy_post-stability.en_estimate))
        pass
 def gradient(self, z_v):
     self.z.vector().set_local(z_v)
     grad = self.solver.gradient(self.z, self.data) + dl.assemble(
         self.solver.grad_reg)[:]
     return grad
Beispiel #33
0
def get_stokessysmats(V,
                      Q,
                      nu=None,
                      bccontrol=False,
                      cbclist=None,
                      cbshapefuns=None):
    """ Assembles the system matrices for Stokes equation

    in mixed FEM formulation, namely

    .. math::

        \\begin{bmatrix} A & -J' \\\\ J & 0 \\end{bmatrix}\
        \\colon V \\times Q \\to V' \\times Q'

    as the discrete representation of

    .. math::

        \\begin{bmatrix} -\\Delta & \\text{grad} \\\\ \
        \\text{div} & 0 \\end{bmatrix}

    plus the velocity and pressure mass matrices

    for a given trial and test space W = V * Q
    not considering boundary conditions.

    Parameters
    ----------
    V : dolfin.VectorFunctionSpace
        Fenics VectorFunctionSpace for the velocity
    Q : dolfin.FunctionSpace
        Fenics FunctionSpace for the pressure
    nu : float, optional
        viscosity parameter - defaults to 1
    bccontrol : boolean, optional
        whether boundary control (via penalized Robin conditions)
        is applied, defaults to `False`
    cbclist : list, optional
        list of dolfin's Subdomain classes describing the control boundaries
    cbshapefuns : list, optional
        list of spatial shape functions of the control boundaries

    Returns
    -------
    stokesmats, dictionary
        a dictionary with the following keys:
            * ``M``: the mass matrix of the velocity space,
            * ``A``: the stiffness matrix \
                :math:`\\nu \\int_\\Omega (\\nabla \\phi_i, \\nabla \\phi_j)`
            * ``JT``: the gradient matrix,
            * ``J``: the divergence matrix, and
            * ``MP``: the mass matrix of the pressure space
            * ``Apbc``: (N, N) sparse matrix, \
                the contribution of the Robin conditions to `A` \
                :math:`\\nu \\int_\\Gamma (\\phi_i, \\phi_j)`
            * ``Bpbc``: (N, k) sparse matrix, the input matrix of the Robin \
                conditions :math:`\\nu \\int_\\Gamma (\\phi_i, g_k)`, \
                where :math:`g_k` is the shape function associated with the \
                j-th control boundary segment

    """

    u = dolfin.TrialFunction(V)
    p = dolfin.TrialFunction(Q)
    v = dolfin.TestFunction(V)
    q = dolfin.TestFunction(Q)

    if nu is None:
        nu = 1
        print('No viscosity provided -- we set `nu=1`')

    ma = inner(u, v) * dx
    mp = inner(p, q) * dx
    aa = nu * inner(grad(u), grad(v)) * dx
    grada = div(v) * p * dx
    diva = q * div(u) * dx

    # Assemble system
    M = dolfin.assemble(ma)
    A = dolfin.assemble(aa)
    Grad = dolfin.assemble(grada)
    Div = dolfin.assemble(diva)
    MP = dolfin.assemble(mp)

    # Convert DOLFIN representation to scipy arrays
    Ma = mat_dolfin2sparse(M)
    MPa = mat_dolfin2sparse(MP)
    Aa = mat_dolfin2sparse(A)
    JTa = mat_dolfin2sparse(Grad)
    Ja = mat_dolfin2sparse(Div)

    stokesmats = {'M': Ma, 'A': Aa, 'JT': JTa, 'J': Ja, 'MP': MPa}

    if bccontrol:
        amatrobl, bmatrobl = [], []
        mesh = V.mesh()
        for bc, bcfun in zip(cbclist, cbshapefuns):
            # get an instance of the subdomain class
            Gamma = bc()

            # bparts = dolfin.MeshFunction('size_t', mesh,
            #                              mesh.topology().dim() - 1)

            boundaries = dolfin.FacetFunction("size_t", mesh)
            boundaries.set_all(0)
            Gamma.mark(boundaries, 1)

            ds = dolfin.Measure('ds', domain=mesh, subdomain_data=boundaries)

            # Gamma.mark(bparts, 0)

            # Robin boundary form
            arob = dolfin.inner(u, v) * ds(1)  # , subdomain_data=bparts)
            brob = dolfin.inner(v, bcfun) * ds(1)  # , subdomain_data=bparts)

            amatrob = dolfin.assemble(arob)  # , exterior_facet_domains=bparts)
            bmatrob = dolfin.assemble(brob)  # , exterior_facet_domains=bparts)

            amatrob = mat_dolfin2sparse(amatrob)
            amatrob.eliminate_zeros()
            amatrobl.append(amatrob)
            bmatrobl.append(bmatrob.array().reshape((V.dim(), 1)))  # [ININDS]

        amatrob = amatrobl[0]
        for amatadd in amatrobl[1:]:
            amatrob = amatrob + amatadd
        bmatrob = np.hstack(bmatrobl)

        stokesmats.update({'amatrob': amatrob, 'bmatrob': bmatrob})

    return stokesmats
Beispiel #34
0
 ndim = 2
 nx = 64
 ny = 64
 mesh = dl.UnitSquareMesh(nx, ny)
 Vh = dl.FunctionSpace(mesh, "CG", 1)
 
 T = dl.Expression(code_AnisTensor2D)
 T.theta0 = 2.
 T.theta1 = .5
 T.alpha = math.pi/4
 
 u = dl.TrialFunction(Vh)
 v = dl.TestFunction(Vh)
 a = dl.inner(T*dl.grad(u), dl.grad(v))*dl.dx
 
 A = dl.assemble(a)
 
 e = dl.Expression(code_Mollifier)
 e.o = 2
 e.l = 0.2
 e.addLocation(.1,.1)
 e.addLocation(.1,.9)
 e.addLocation(.5,.5)
 e.addLocation(.9,.1)
 e.addLocation(.9,.9)
 e.theta0 = 1./T.theta0
 e.theta1 = 1./T.theta1
 e.alpha  = T.alpha
 
 m = dl.interpolate(e, Vh)
 
Beispiel #35
0
 def j(self, t, u):
     return dol.assemble(u * self.dx_obs) / self.t_end
Beispiel #36
0
 def compute(geo):
     vol = dolfin.assemble(r * geo.dx("molecule"))
     return Qmol / vol if vol > 0. else 0.
Beispiel #37
0
def normal_velocity(mode, solver):
    return dolf.assemble((dolf.dot(mode[1], solver.domain.n)) *
                         solver.domain.ds(boundary5.surface_index))
    RectangleMesh = 2.548s
    msrh.Rectangle = 2.886s

1000x1000
Serial (ccgo1):
    UnitSquareMesh = 30.083s
    RectangleMesh = 30.216s
    msrh.Rectangle = 53.257s

Parallel 16 cores (ccgo1):
    UnitSquareMesh = 6.686s
    RectangleMesh = 6.537s
    msrh.Rectangle = 23.670s
"""

import dolfin as dl
from mshr import Rectangle, generate_mesh

mesh = dl.UnitSquareMesh(20, 20)

#mesh = dl.RectangleMesh(dl.Point(0.,0.), dl.Point(1.,1.), 1000, 1000)

#domain= Rectangle(dl.Point(0.,0.), dl.Point(1.,1.))
#mesh = generate_mesh(domain, 893)

V = dl.FunctionSpace(mesh, 'Lagrange', 3)
test, trial = dl.TestFunction(V), dl.TrialFunction(V)
u = dl.interpolate(dl.Expression('x[0]*x[1]'), V)
M = dl.assemble(dl.inner(test, trial) * dl.dx)
print u.vector().size(), len(V.dofmap().dofs())  # only to check size of mesh
Beispiel #39
0
    def __init__(self, fenics_2d_part, loads, boundary_conditions, element):
        """

        The FacetFunction must be the same for all BC and facet loads. Its type of value must be 'size_t' (unsigned integers).

        Parameters
        ----------
        fenics_2d_part : FEnicsPart
            [description]
        loads : [type]
            [description]
        boundary_conditions : list or tuple
            All the boundary conditions.
            Each of them is describe by a tuple or a dictionnary.
            Only one periodic BC can be prescribed.
            Format:
                if Periodic BC :
                    {'type': 'Periodic', 'constraint': PeriodicDomain}
                    or
                    ('Periodic', PeriodicDomain)
                if Dirichlet BC :
                    {
                        'type': 'Dirichlet',
                        'constraint': the prescribed value,
                        'facet_function': facet function,
                        'facet_idx': facet function index}
                    or
                    ('Dirichlet', the prescribed value, facet function, facet function index)
                    or
                    ('Dirichlet', the prescribed value, indicator function)
                        where the indicator function is python function like :
                        def clamped(x, on_boundary):
                            return on_boundary and x[0] < tolerance
        element: tuple or dict
        Ex: ('CG', 2) or {'family':'Lagrange', degree:2}
        """
        self.part = fenics_2d_part

        # * Boundary conditions
        self.per_bc = None
        self.Dirichlet_bc = list()
        for bc in boundary_conditions:
            if isinstance(bc, dict):
                bc_ = bc
                bc = [bc_["type"], bc_["constraint"]]
                try:
                    bc.append(bc_["facet_function"])
                    bc.append(bc_["facet_idx"])
                except KeyError:
                    pass
            bc_type, *bc_data = bc
            if bc_type == "Periodic":
                if self.per_bc is not None:
                    raise AttributeError(
                        "Only one periodic boundary condition can be prescribed."
                    )
                self.per_bc = bc_data[0]
            elif bc_type == "Dirichlet":
                if len(bc_data) == 2 or len(bc_data) == 3:
                    bc_data = tuple(bc_data)
                else:
                    raise AttributeError(
                        "Too much parameter for the definition of a Dirichlet BC."
                    )
                self.Dirichlet_bc.append(bc_data)

        self.measures = {self.part.dim: fe.dx, self.part.dim - 1: fe.ds}

        # * Function spaces
        try:
            self.elmt_family = family = element["family"]
            self.elmt_degree = degree = element["degree"]
        except TypeError:  # Which means that element is not a dictionnary
            self.element_family, self.element_degree = element
            family, degree = element
        cell = self.part.mesh.ufl_cell()
        Voigt_strain_dim = int(self.part.dim * (self.part.dim + 1) / 2)
        strain_deg = degree - 1 if degree >= 1 else 0
        strain_FE = fe.VectorElement("DG",
                                     cell,
                                     strain_deg,
                                     dim=Voigt_strain_dim)
        self.scalar_fspace = fe.FunctionSpace(
            self.part.mesh,
            fe.FiniteElement(family, cell, degree),
            constrained_domain=self.per_bc,
        )
        self.displ_fspace = fe.FunctionSpace(
            self.part.mesh,
            fe.VectorElement(family, cell, degree, dim=self.part.dim),
            constrained_domain=self.per_bc,
        )
        self.strain_fspace = fe.FunctionSpace(self.part.mesh,
                                              strain_FE,
                                              constrained_domain=self.per_bc)

        self.v = fe.TestFunction(self.displ_fspace)
        self.u = fe.TrialFunction(self.displ_fspace)
        self.a = (fe.inner(
            mat.sigma(self.part.elasticity_tensor, mat.epsilon(self.u)),
            mat.epsilon(self.v),
        ) * self.measures[self.part.dim])
        self.K = fe.assemble(self.a)

        # * Create suitable objects for Dirichlet boundary conditions
        for i, bc_data in enumerate(self.Dirichlet_bc):
            self.Dirichlet_bc[i] = fe.DirichletBC(self.displ_fspace, *bc_data)
        # ? Vu comment les conditions aux limites de Dirichlet interviennent dans le problème, pas sûr que ce soit nécessaire que toutes soient définies avec la même facetfunction

        # * Taking into account the loads
        if loads:
            self.set_loads(loads)
        else:
            self.loads_data = None
            self.load_integrals = None
        # * Prepare attribute for the solver
        self.solver = None
Beispiel #40
0
    Echi = df.FiniteElement("Lagrange", mesh.ufl_cell(), 2)

    pbc = PeriodicBC(Lx, Ly)
    wall = Wall(Lx, Ly)
    notwall = NotWall(Lx, Ly)

    subd = df.MeshFunction("size_t", mesh, mesh.topology().dim()-1)
    subd.set_all(0)
    wall.mark(subd, 1)
    notwall.mark(subd, 0)

    S = df.FunctionSpace(mesh, Echi, constrained_domain=pbc)

    one = df.interpolate(df.Constant(1.), S)
    V_Omega = df.assemble(one*df.dx)

    n = df.FacetNormal(mesh)

    chi = df.TrialFunction(S)
    chi_ = df.Function(S, name="chi")
    psi = df.TestFunction(S)

    ds = df.Measure("ds", domain=mesh, subdomain_data=subd)

    F_chi = (n[0]*psi*ds(1)
             + df.inner(df.grad(chi), df.grad(psi))*df.dx)

    a_chi, L_chi = df.lhs(F_chi), df.rhs(F_chi)

    problem_chi2 = df.LinearVariationalProblem(a_chi, L_chi, chi_, bcs=[])
 def callback(arg):
     return assemble(arg)
Beispiel #42
0
    def __init__(
            self,
            a_k,
            u,
            a_m=None,  # optional, for eigpb of the type (K-lambda M)x=0
            bcs=None,
            restricted_dofs_is=None,
            slepc_options='',
            option_prefix='eigen_',
            comm=MPI.comm_world,
            slepc_eigensolver=None,
            initial_guess=None):
        """
        Solver object for constrained eigenvalue pb of the type:
            - K z y = \\lmbda <z, y>, forall y \\in V_h(\\Omega')
            - K z y = \\lmbda <z, y>, forall y \\in {inactive constraints}

            where \\Omega' \\subseteq \\Omega
            where {inactive constraints} is a proper subset
        """
        self.comm = comm

        self.slepc_options = slepc_options
        self.V = u.function_space()
        self.u = u
        self.index_set = None

        if type(bcs) == list:
            self.bcs = bcs
        elif type(bcs) == dolfin.fem.dirichletbc.DirichletBC:
            self.bcs = [bcs]
        else:
            self.bcs = None

        if type(a_k) == ufl.form.Form:
            # a form to be assembled
            self.K = dolfin.as_backend_type(assemble(a_k)).mat()
        elif type(a_k) == petsc4py.PETSc.Mat:
            # an assembled petsc matrix
            self.K = a_k

        if a_m is not None and type(a_m) == ufl.form.Form:
            self.M = dolfin.as_backend_type(assemble(a_m)).mat()
        elif a_m is not None and type(a_m) == petsc4py.PETSc.Mat:
            self.M = a_m

        if self.bcs:
            self.index_set = self.get_interior_index_set(self.bcs, self.V)

        if restricted_dofs_is:
            self.index_set = restricted_dofs_is

        self.K, self.M = self.restrictOperator(self.index_set)
        self.projector = self.createProjector(self.index_set)

        if slepc_eigensolver:
            self.E = slepc_eigensolver
        else:
            self.E = self.eigensolver_setup(prefix=option_prefix)

        if a_m:
            self.E.setOperators(self.K, self.M)
        else:
            self.E.setOperators(self.K)
Beispiel #43
0
    def __init__(self, mesh, Vh, t_init, t_final, t_1, dt, wind_velocity,
                 gls_stab, Prior):
        self.mesh = mesh
        self.Vh = Vh
        self.t_init = t_init
        self.t_final = t_final
        self.t_1 = t_1
        self.dt = dt
        self.sim_times = np.arange(self.t_init, self.t_final + .5 * self.dt,
                                   self.dt)

        u = dl.TrialFunction(Vh[STATE])
        v = dl.TestFunction(Vh[STATE])

        kappa = dl.Constant(.001)
        dt_expr = dl.Constant(self.dt)

        r_trial = u + dt_expr * (-dl.div(kappa * dl.nabla_grad(u)) +
                                 dl.inner(wind_velocity, dl.nabla_grad(u)))
        r_test = v + dt_expr * (-dl.div(kappa * dl.nabla_grad(v)) +
                                dl.inner(wind_velocity, dl.nabla_grad(v)))

        h = dl.CellSize(mesh)
        vnorm = dl.sqrt(dl.inner(wind_velocity, wind_velocity))
        if gls_stab:
            tau = dl.Min((h * h) / (dl.Constant(2.) * kappa), h / vnorm)
        else:
            tau = dl.Constant(0.)

        self.M = dl.assemble(dl.inner(u, v) * dl.dx)
        self.M_stab = dl.assemble(dl.inner(u, v + tau * r_test) * dl.dx)
        self.Mt_stab = dl.assemble(dl.inner(u + tau * r_trial, v) * dl.dx)
        Nvarf = (dl.inner(kappa * dl.nabla_grad(u), dl.nabla_grad(v)) +
                 dl.inner(wind_velocity, dl.nabla_grad(u)) * v) * dl.dx
        Ntvarf = (dl.inner(kappa * dl.nabla_grad(v), dl.nabla_grad(u)) +
                  dl.inner(wind_velocity, dl.nabla_grad(v)) * u) * dl.dx
        self.N = dl.assemble(Nvarf)
        self.Nt = dl.assemble(Ntvarf)
        stab = dl.assemble(tau * dl.inner(r_trial, r_test) * dl.dx)
        self.L = self.M + dt * self.N + stab
        self.Lt = self.M + dt * self.Nt + stab

        boundaries = dl.FacetFunction("size_t", mesh)
        boundaries.set_all(0)

        class InsideBoundary(dl.SubDomain):
            def inside(self, x, on_boundary):
                x_in = x[0] > dl.DOLFIN_EPS and x[0] < 1 - dl.DOLFIN_EPS
                y_in = x[1] > dl.DOLFIN_EPS and x[1] < 1 - dl.DOLFIN_EPS
                return on_boundary and x_in and y_in

        Gamma_M = InsideBoundary()
        Gamma_M.mark(boundaries, 1)
        ds_marked = dl.Measure("ds")[boundaries]

        self.Q = dl.assemble(self.dt * dl.inner(u, v) * ds_marked(1))

        self.Prior = Prior

        self.solver = dl.PETScKrylovSolver("gmres", "ilu")
        self.solver.set_operator(self.L)

        self.solvert = dl.PETScKrylovSolver("gmres", "ilu")
        self.solvert.set_operator(self.Lt)

        self.ud = self.generate_vector(STATE)
        self.noise_variance = 0
# Commented out below  is the option for creating a ParaView readable file to visualize the difference
# between the solution of the two approaches over the surface of the cube.
# The error values over the elememts of the mesh is expected to vary and cause error in the magnitude
# of up to 3e-3. This observation is due to the difference in the calculation of the solution for the solid.
# In addition to the constitutive law, the PoroelasticProblem applies the Lagrange multiplier
# subjecting the constitutive law to the constraint evoked by the influence of the fluid mass divergence,
# density of the fluid and in sum the difference of the fluid influence in each compartment
# changing the determinante J.
# This difference in calculation leads to the error observed.


    #diff = project(dU-u, dU.function_space())
    #poro.write_file(f4, diff, 'du', t)

    domain_area += df.assemble(df.div(dU)*dx)*(1-phi)
    sum_fluid_mass += df.assemble(Mf*dx)
    sum_disp += df.assemble(dU[0]*ds(4))


[f1[i].close() for i in range(N)]
f2.close()
[f3[i].close() for i in range(N)]
f4.close()
#
# The function 'write_config' inherited by the class 'ParamParser' of the module
# param_parser is executed on the configuration files to be created.
#
params.write_config('../data/{}/{}.cfg'.format(data_dir, data_dir))
#
# Finally, the result for the expected sum fluid mass, the error between the
Beispiel #45
0
 def avg(u, dx):
     return dolfin.assemble(u * dx) / dolfin.assemble(
         dolfin.Constant(1.) * dx)
Beispiel #46
0
def block_assemble(lhs, rhs=None, bcs=None,
                   symmetric=False, signs=None, symmetric_mod=None):
    """
    Assembles block matrices, block vectors or block systems.
    Input can be arrays of variational forms or block matrices/vectors.

    Arguments:

            symmetric : Boundary conditions are applied so that symmetry of the system
                        is preserved. If only the left hand side of the system is given,
                        then a matrix represententing the rhs corrections is returned
                        along with a symmetric matrix.

        symmetric_mod : Matrix describing symmetric corrections for assembly of the
                        of the rhs of a variational system.

                signs : An array to specify the signs of diagonal blocks. The sign
                        of the blocks are computed if the argument is not provided.
    """
    error_msg = {'incompatibility' : 'A and b do not have compatible dimensions.',
                 'symm_mod error'  : 'symmetric_mod argument only accepted when assembling a vector',
                 'not square'      : 'A must be square for symmetric assembling',
                 'invalid bcs'     : 'Expecting a list or list of lists of DirichletBC.',
                 'invalid signs'   : 'signs should be a list of length n containing only 1 or -1',
                 'mpi and symm'    : 'Symmetric application of BC not yet implemented in parallel'}
    # Check arguments
    from numpy import ndarray
    has_rhs = True if isinstance(rhs, ndarray) else rhs != None
    has_lhs = True if isinstance(rhs, ndarray) else rhs != None

    if symmetric:
        from dolfin import MPI, mpi_comm_world
        if MPI.size(mpi_comm_world()) > 1:
            raise NotImplementedError(error_msg['mpi and symm'])
    if has_lhs and has_rhs:
        A, b = map(block_tensor,[lhs,rhs])
        n, m = A.blocks.shape
        if not ( isinstance(b,block_vec) and  len(b.blocks) is m):
            raise TypeError(error_msg['incompatibility'])
    else:
        A, b = block_tensor(lhs), None
        if isinstance(A,block_vec):
            A, b = None, A
            n, m = 0, len(b.blocks)
        else:
            n,m = A.blocks.shape
    if A and symmetric and (m is not n):
        raise RuntimeError(error_msg['not square'])
    if symmetric_mod and ( A or not b ):
        raise RuntimeError(error_msg['symmetric_mod error'])
    # First assemble everything needing assembling.
    from dolfin import assemble
    assemble_if_form = lambda x: assemble(x, keep_diagonal=True) if _is_form(x) else x
    if A:
        A.blocks.flat[:] = map(assemble_if_form,A.blocks.flat)
    if b:
        #b.blocks.flat[:] = map(assemble_if_form, b.blocks.flat)
        b = block_vec(map(assemble_if_form, b.blocks.flat))
    # If there are no boundary conditions then we are done.
    if bcs is None:
        if A:
            return [A,b] if b else A
        else:
            return b

    # check if arguments are forms, in which case bcs have to be split
    from ufl import Form
    if isinstance(lhs, Form):
        from splitting import split_bcs
        bcs = split_bcs(bcs, m)
    # Otherwise check that boundary conditions are valid.
    if not hasattr(bcs,'__iter__'):
        raise TypeError(error_msg['invalid bcs'])
    if len(bcs) is not m:
        raise TypeError(error_msg['invalid bcs'])
    from dolfin import DirichletBC
    for bc in bcs:
        if isinstance(bc,DirichletBC) or bc is None:
            pass
        else:
            if not hasattr(bc,'__iter__'):
                raise TypeError(error_msg['invalid bcs'])
            else:
                for bc_i in bc:
                    if isinstance(bc_i,DirichletBC):
                        pass
                    else:
                        raise TypeError(error_msg['invalid bcs'])
    bcs = [bc if hasattr(bc,'__iter__') else [bc] if bc else bc for bc in bcs]
    # Apply BCs if we are only assembling the righ hand side
    if not A:
        if symmetric_mod:
            b.allocate(symmetric_mod)
        for i in xrange(m):
            if bcs[i]:
                if isscalar(b[i]):
                    b[i], val = create_vec_from(bcs[i][0]), b[i]
                    b[i][:] = val
                for bc in bcs[i]: bc.apply(b[i])
        if symmetric_mod:
            b.allocate(symmetric_mod)
            b -= symmetric_mod*b
        return b
    # If a signs argument is passed, check if it is valid.
    # Otherwise guess.
    if signs and symmetric:
        if ( hasattr(signs,'__iter__')  and len(signs)==m ):
            for sign in signs:
                if sign not in (-1,1):
                    raise TypeError(error_msg['invalid signs'])
        else:
            raise TypeError(error_msg['invalid signs'])
    elif symmetric:
        from numpy.random import random
        signs = [0]*m
        for i in xrange(m):
            if isscalar(A[i,i]):
                signs[i] = -1 if A[i,i] < 0 else 1
            else:
                x = A[i,i].create_vec(dim=1)
                x.set_local(random(x.local_size()))
                signs[i] = -1 if x.inner(A[i,i]*x) < 0 else 1
    # Now apply boundary conditions.
    if b:
        b.allocate(A)
    elif symmetric:
        # If we are preserving symmetry but don't have the rhs b,
        # then we need to store the symmetric corretions to b
        # as a matrix which we call A_mod
        b, A_mod = A.create_vec(), A.copy()
    for i in xrange(n):
        if bcs[i]:
            for bc in bcs[i]:
                # Apply BCs to the diagonal block.
                if isscalar(A[i,i]):
                    A[i,i] = _new_square_matrix(bc,A[i,i])
                    if symmetric:
                        A_mod[i,i] = A[i,i].copy()
                if symmetric:
                    bc.zero_columns(A[i,i],b[i],signs[i])
                    bc.apply(A_mod[i,i])
                elif b:
                    bc.apply(A[i,i],b[i])
                else:
                    bc.apply(A[i,i])
                # Zero out the rows corresponding to BC dofs.
                for j in range(i) + range(i+1,n):
                    if A[i,j] is 0:
                        continue
                    assert not isscalar(A[i,j])
                    bc.zero(A[i,j])
                # If we are not preserving symmetry then we are done at this point.
                # Otherwise, we need to zero out the columns as well
                if symmetric:
                    for j in range(i) + range(i+1,n):
                        if A[j,i] is 0:
                            continue
                        assert not isscalar(A[j,i])
                        bc.zero_columns(A[j,i],b[j])
                        bc.zero(A_mod[i,j])

    result = [A]
    if symmetric:
        for i in range(n):
            for j in range(n):
                A_mod[i,j] -= A[i,j]
        result += [A_mod]
    if b:
        result += [b]
    return result[0] if len(result)==1 else result
Beispiel #47
0
def stress(mode, solver):
    return dolf.assemble(
        _stress(mode, solver) * solver.domain.ds(boundary5.surface_index))
Beispiel #48
0
 def assemble_lhs(self):
     if self.tensor_lhs is None:
         self.tensor_lhs = dolfin.assemble(self.form_lhs)
     else:
         dolfin.assemble(self.form_lhs, tensor=self.tensor_lhs)
     return self.tensor_lhs
    dolfin.File(os.path.join(results_outdir_functions, "stress_field.pvd")) << stress_field

    dolfin.File(os.path.join(results_outdir_functions,
        "maximal_compressive_stress_field.pvd")) << maximal_compressive_stress_field

    dolfin.File(os.path.join(results_outdir_functions,
        "fraction_compressive_stress_field.pvd")) << fraction_compressive_stress_field


if __name__ == "__main__":

    if SAVE_RESULTS:
        save_functions()

    phasefield_fraction = dolfin.assemble(p*dolfin.dx) \
                        / dolfin.assemble(1*dolfin.dx(domain=mesh))

    strain_energy = dolfin.assemble(W)

    m_arr = m.vector().get_local()
    u_arr = u.vector().get_local()

    m.vector()[:] = 1.0
    equilibrium_solve()

    strain_energy_ref = dolfin.assemble(W)

    m.vector()[:] = m_arr
    u.vector()[:] = u_arr
Beispiel #50
0
 def __init__(self, Vh):
     test = dl.TestFunction(Vh[STATE])
     f = dl.Constant(1.0)
     self.f = dl.assemble(f * test * dl.dx)
Beispiel #51
0
def les_setup(u_, mesh, assemble_matrix, CG1Function, nut_krylov_solver, bcs,
              **NS_namespace):
    """
    Set up for solving the Germano Dynamic LES model applying
    Lagrangian Averaging.
    """

    # Create function spaces
    CG1 = FunctionSpace(mesh, "CG", 1)
    p, q = TrialFunction(CG1), TestFunction(CG1)
    dim = mesh.geometry().dim()

    # Define delta and project delta**2 to CG1
    delta = pow(CellVolume(mesh), 1. / dim)
    delta_CG1_sq = project(delta, CG1)
    delta_CG1_sq.vector().set_local(delta_CG1_sq.vector().array()**2)
    delta_CG1_sq.vector().apply("insert")

    # Define nut_
    Sij = sym(grad(u_))
    magS = sqrt(2 * inner(Sij, Sij))
    Cs = Function(CG1)
    nut_form = Cs**2 * delta**2 * magS
    # Create nut_ BCs
    ff = FacetFunction("size_t", mesh, 0)
    bcs_nut = []
    for i, bc in enumerate(bcs['u0']):
        bc.apply(u_[0].vector())  # Need to initialize bc
        m = bc.markers()  # Get facet indices of boundary
        ff.array()[m] = i + 1
        bcs_nut.append(DirichletBC(CG1, Constant(0), ff, i + 1))
    nut_ = CG1Function(nut_form,
                       mesh,
                       method=nut_krylov_solver,
                       bcs=bcs_nut,
                       bounded=True,
                       name="nut")

    # Create functions for holding the different velocities
    u_CG1 = as_vector([Function(CG1) for i in range(dim)])
    u_filtered = as_vector([Function(CG1) for i in range(dim)])
    dummy = Function(CG1)
    ll = LagrangeInterpolator()

    # Assemble required filter matrices and functions
    G_under = Function(CG1, assemble(TestFunction(CG1) * dx))
    G_under.vector().set_local(1. / G_under.vector().array())
    G_under.vector().apply("insert")
    G_matr = assemble(inner(p, q) * dx)

    # Set up functions for Lij and Mij
    Lij = [Function(CG1) for i in range(dim * dim)]
    Mij = [Function(CG1) for i in range(dim * dim)]
    # Check if case is 2D or 3D and set up uiuj product pairs and
    # Sij forms, assemble required matrices
    Sijcomps = [Function(CG1) for i in range(dim * dim)]
    Sijfcomps = [Function(CG1) for i in range(dim * dim)]
    # Assemble some required matrices for solving for rate of strain terms
    Sijmats = [assemble_matrix(p.dx(i) * q * dx) for i in range(dim)]
    if dim == 3:
        tensdim = 6
        uiuj_pairs = ((0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2))
    else:
        tensdim = 3
        uiuj_pairs = ((0, 0), (0, 1), (1, 1))

    # Set up Lagrange functions
    JLM = Function(CG1)
    JLM.vector()[:] += 1E-32
    JMM = Function(CG1)
    JMM.vector()[:] += 1

    return dict(Sij=Sij,
                nut_form=nut_form,
                nut_=nut_,
                delta=delta,
                bcs_nut=bcs_nut,
                delta_CG1_sq=delta_CG1_sq,
                CG1=CG1,
                Cs=Cs,
                u_CG1=u_CG1,
                u_filtered=u_filtered,
                ll=ll,
                Lij=Lij,
                Mij=Mij,
                Sijcomps=Sijcomps,
                Sijfcomps=Sijfcomps,
                Sijmats=Sijmats,
                JLM=JLM,
                JMM=JMM,
                dim=dim,
                tensdim=tensdim,
                G_matr=G_matr,
                G_under=G_under,
                dummy=dummy,
                uiuj_pairs=uiuj_pairs)
Beispiel #52
0
v, T_hat = df.TestFunctions(mixed_fs)

residual_form = get_residual_form(displacements_function, v, density_function,
                                  temperature_function, T_hat, KAPPA, K, ALPHA)

residual_form -=  (df.dot(f_r, v) * dss(10) + df.dot(f_t, v) * dss(14)  + \
                    q*T_hat*dss(5) + q_half*T_hat*dss(6) + q_quart*T_hat*dss(7))
print("get residual_form-------")
# print('ssssssss',df.assemble(T_hat*df.dx).get_local())
pde_problem.add_state('mixed_states', mixed_function, residual_form, 'density')
'''
4. 3. Add outputs
'''

# Add output-avg_density to the PDE problem:
volume = df.assemble(df.Constant(1.) * df.dx(domain=mesh))
avg_density_form = density_function / (df.Constant(
    1. * volume)) * df.dx(domain=mesh)
pde_problem.add_scalar_output('avg_density', avg_density_form, 'density')
print("Add output-avg_density-------")

# Add output-compliance to the PDE problem:

compliance_form = df.dot(f_r, displacements_function) * dss(10) +\
                    df.dot(f_t, displacements_function) * dss(14)
pde_problem.add_scalar_output('compliance', compliance_form, 'mixed_states')
print("Add output-compliance-------")

compliance_form = df.dot(f_r, displacements_function) * dss(10) +\
                    df.dot(f_t, displacements_function) * dss(14)
pde_problem.add_scalar_output('compliance', compliance_form, 'mixed_states')
    def solve(self, J, grad, H, m):

            
            
        
        
        rtol          = self.parameters["rel_tolerance"]
        atol          = self.parameters["abs_tolerance"]
        gdm_tol       = self.parameters["gdm_tolerance"]
        max_iter      = self.parameters["max_iter"]
        c_armijo      = self.parameters["c_armijo"] 
        max_backtrack = self.parameters["max_backtracking_iter"]
        prt_level     = self.parameters["print_level"]
        cg_coarse_tol = self.parameters["cg_coarse_tolerance"]
        
        Jn = dl.assemble( J(m)   )
        gn = dl.assemble( grad(m) )
        g0_norm = gn.norm("l2")
        gn_norm = g0_norm
        tol = max(g0_norm*rtol, atol)
        dm = dl.Vector()
        
        self.converged = False
        self.reason = 0
        
        if prt_level > 0:
            print( "{0:>3} {1:>15} {2:>15} {3:>15} {4:>15} {5:>15} {6:>7}".format(
                "It", "Energy", "||g||", "(g,du)", "alpha", "tol_cg", "cg_it") )
        
        for self.it in range(max_iter):
            Hn = dl.assemble( H(m) )
            
            Hn.init_vector(dm,1)
            solver = dl.PETScKrylovSolver("cg", "petsc_amg")
            solver.set_operator(Hn)
            solver.parameters["nonzero_initial_guess"] = False
            cg_tol = min(cg_coarse_tol, math.sqrt( gn_norm/g0_norm) )
            solver.parameters["relative_tolerance"] = cg_tol
            lin_it = solver.solve(dm,-gn)
            
            self.total_cg_iter += lin_it
            

            dm_gn = dm.inner(gn)
            
            if(-dm_gn < gdm_tol):
                self.converged=True
                self.reason = 3
                break
             
            m_backtrack = m.copy(deepcopy=True)
            alpha = 1.   
            bk_converged = False
            
            #Backtrack
            for j in range(max_backtrack):
                m.assign(m_backtrack)
                m.vector().axpy(alpha, dm)
                Jnext = dl.assemble( J(m) )
                if Jnext < Jn + alpha*c_armijo*dm_gn:
                    Jn = Jnext
                    bk_converged = True
                    break
                
                alpha = alpha/2.
                
            if not bk_converged:
                self.reason = 2
                break
                   
            gn = dl.assemble( grad(m) )
            gn_norm = gn.norm("l2")
            
            if prt_level > 0:
                print( "{0:3d} {1:15e} {2:15e} {3:15e} {4:15e} {5:15e} {6:7d}".format(
                        self.it, Jn, gn_norm, dm_gn, alpha, cg_tol, lin_it) )
                
            if gn_norm < tol:
                self.converged = True
                self.reason = 1
                break
            
        self.final_grad_norm = gn_norm
        
        if prt_level > -1:
            print( self.termination_reasons[self.reason] )
            if self.converged:
                print( "Inexact Newton CG converged in ", self.it, \
                "nonlinear iterations and ", self.total_cg_iter, "linear iterations." )
            else:
                print( "Inexact Newton CG did NOT converge after ", self.it, \
                "nonlinear iterations and ", self.total_cg_iter, "linear iterations.")
            print ("Final norm of the gradient", self.final_grad_norm)
            print ("Value of the cost functional", Jn)
                
                
print(
    f"Relative observation error: {obs_err/np.linalg.norm(obs_data)*100:.4f}%")

p = dl.plot(z, vmax=vmax, vmin=vmin)
plt.colorbar(p)
plt.savefig("z_map.png", dpi=200)

plt.cla()
plt.clf()
p = dl.plot(dl.exp(z))
plt.colorbar(p)
plt.savefig("z_map_exp.png", dpi=200)

#  plt.cla()
#  plt.clf()
#  p = dl.plot(z_true, vmax=vmax, vmin=vmin)
#  plt.colorbar(p)
#  plt.savefig("z_true.png", dpi=200)

reconst_err = dl.assemble(dl.inner(z - z_true, z - z_true) * dl.dx)
z_true_norm = dl.assemble(dl.inner(z_true, z_true) * dl.dx)
rel_r_err = np.sqrt(reconst_err / z_true_norm)
print(f"Relative reconstruction error: {rel_r_err * 100:.4f}%")
print(f"Reconstruction error: {reconst_err:.4f}")

rel_err = 100 * np.abs(z_true.vector()[:] -
                       z.vector()[:]) / np.sqrt(z_true_norm)
z_err = dl.Function(V)
z_err.vector().set_local(rel_err)
np.save('rel_err', rel_err)
Beispiel #55
0
def ass_convmat_asmatquad(W=None, invindsw=None):
    """ assemble the convection matrix H, so that N(v)v = H[v.v]

    for the inner nodes.

    Notes
    -----
    Implemented only for 2D problems

    """
    mesh = W.mesh()
    deg = W.ufl_element().degree()
    fam = W.ufl_element().family()

    V = dolfin.FunctionSpace(mesh, fam, deg)

    # this is very specific for V being a 2D VectorFunctionSpace
    invindsv = invindsw[::2] / 2

    v = dolfin.TrialFunction(V)
    vt = dolfin.TestFunction(V)

    def _pad_csrmats_wzerorows(smat, wheretoput='before'):
        """add zero rows before/after each row

        """
        indpeter = smat.indptr
        auxindp = np.c_[indpeter, indpeter].flatten()
        if wheretoput == 'after':
            smat.indptr = auxindp[1:]
        else:
            smat.indptr = auxindp[:-1]

        smat._shape = (2 * smat.shape[0], smat.shape[1])

        return smat

    def _shuff_mrg_csrmats(xm, ym):
        """shuffle merge csr mats [xxx],[yyy] -> [xyxyxy]

        """
        xm.indices = 2 * xm.indices
        ym.indices = 2 * ym.indices + 1
        xm._shape = (xm.shape[0], 2 * xm.shape[1])
        ym._shape = (ym.shape[0], 2 * ym.shape[1])
        return xm + ym

    nklist = []
    for i in invindsv:
        # for i in range(V.dim()):
        # iterate for the columns

        # get the i-th basis function
        bi = dolfin.Function(V)
        bvec = np.zeros((V.dim(), ))
        bvec[i] = 1
        bi.vector()[:] = bvec

        # assemble for the i-th basis function
        nxi = dolfin.assemble(v * bi.dx(0) * vt * dx)
        nyi = dolfin.assemble(v * bi.dx(1) * vt * dx)

        nxim = mat_dolfin2sparse(nxi)
        nxim.eliminate_zeros()

        nyim = mat_dolfin2sparse(nyi)
        nyim.eliminate_zeros()

        # resorting of the arrays and inserting zero columns
        nxyim = _shuff_mrg_csrmats(nxim, nyim)
        nxyim = nxyim[invindsv, :][:, invindsw]
        nyxxim = _pad_csrmats_wzerorows(nxyim.copy(), wheretoput='after')
        nyxyim = _pad_csrmats_wzerorows(nxyim.copy(), wheretoput='before')

        # tile the arrays in horizontal direction
        nklist.extend([nyxxim, nyxyim])

    hmat = sps.hstack(nklist, format='csc')
    return hmat
 def gradient(self, z_v):
     self.z.vector().set_local(z_v)
     self.solver._k.assign(self.z)
     self.grad, self.cost = self.solver_r.grad_reduced(self.z)
     self.grad = self.grad + dl.assemble(self.solver.grad_reg)
     return self.grad
Beispiel #57
0
    u_1.assign(u_)

    converged = False
    while not converged:
        if parameters["anneal"]:
            tau.assign(
                anneal_func(
                    t+dt.get(),
                    parameters["tau"],
                    parameters["tau_ramp"],
                    parameters["t_ramp"]))

        # Compute energy
        u_.assign(u_1)
        Eout_0 = df.assemble(geo_map.form(E_0))
        Eout_2 = df.assemble(geo_map.form(E_2))
        E_before = Eout_0 + Eout_2

        try:
            solver.solve()
            converged = True
        except:
            info_blue("Did not converge. Chopping timestep.")
            dt.chop()
            info_blue("New timestep is: dt = {}".format(dt.get()))

        Eout_0 = df.assemble(geo_map.form(E_0))
        Eout_2 = df.assemble(geo_map.form(E_2))
        E_after = Eout_0 + Eout_2
        dE = E_after - E_before
    editor.close()
    return mesh


mesh = UnitSquareMesh(200, 200)
# mesh = create_dolfin_mesh(*meshzoo.triangle(1500, corners=[[0, 0], [1, 0], [0, 1]]))


V = FunctionSpace(mesh, "CG", 1)

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

n = FacetNormal(mesh)
# A = assemble(dot(grad(u), grad(v)) * dx - dot(n, grad(u)) * v * ds)
A = assemble(dot(grad(u), grad(v)) * dx - dot(n, grad(u)) * v * ds)
M = assemble(u * v * dx)

f = Expression("sin(pi * x[0]) * sin(pi * x[1])", element=V.ufl_element())
x = project(f, V)

Ax = A * x.vector()
Minv_Ax = Function(V).vector()
solve(M, Minv_Ax, Ax)
val = Ax.inner(Minv_Ax)

print(val)


# Exact value
x = sympy.Symbol("x")
Beispiel #59
0
    def __init__(self, Vh, dt, save, out_path, subdmn_path, mesh_tag,
                 qoi_type):

        self.Vh = Vh
        self._param_dim = Vh[PARAMETER].dim()
        self.dt = dt
        self._out_path = out_path
        self._file = None
        self._qoi_type = qoi_type
        if save:
            self._file = [None] * 5
            for i in range(5):
                names = [
                    "susceptible", "exposed", "infected", "recovered",
                    "deceased"
                ]
                self._file[i] = dl.File(out_path + names[i] + '.pvd',
                                        "compressed")

        self.m = dl.Function(Vh[PARAMETER])
        self.gamma = [None] * 5
        self.sigma = None
        self.beta = [None] * 5
        self.nu = [None] * 5
        self.A = None

        self.help = dl.Function(Vh[STATE])

        self.p = dl.TestFunction(self.Vh[STATE])
        self.u_trial = dl.TrialFunction(self.Vh[STATE])
        self.M = dl.assemble(self.u_trial * self.p * dl.dx)

        self.z = dl.assemble(dl.Constant(1.0) * self.p * dl.dx)

        self.u_0 = [dl.Function(self.Vh[STATE]) for i in range(5)]
        self.u_k = [dl.Function(self.Vh[STATE]) for i in range(5)]

        self.H = [None] * 5
        self.b = [None] * 5

        self.a = [None] * 5
        self.L = [None] * 5

        # load subdomains
        self.subdmn_path = subdmn_path
        if qoi_type == 'district':
            subdomain = dl.MeshFunction("size_t", self.Vh[STATE].mesh(), 2)
            dl.File(self.subdmn_path + 'subdomain_' + mesh_tag +
                    '.xml.gz') >> subdomain
            dx_dist = dl.Measure('dx',
                                 domain=self.Vh[STATE].mesh(),
                                 subdomain_data=subdomain)

            # for integration over districts
            self.z_dist = [
                dl.assemble(dl.Constant(1.0) * self.p * dx_dist(i))
                for i in range(25)
            ]

            # read area factor (integration of unit function over district subdomain is
            # smaller than the district area)
            self.dist_area_factor = np.load(self.subdmn_path + 'area_factor_' +
                                            mesh_tag + '.npy')
        else:
            self.z_dist = []
            self.dist_area_factor = []
# As long as the for loop continues, the theoretical solution and the currently
# approximated solution of the sum of the fluid mass are printed to the screen.
#
# Upon exiting the for loop, the XDMFFiles created are closed by calling the
# 'close()' function.

for Mf, Uf, p, Us, t in pprob.solve():

    dU, L = Us.split(True)

    [poro.write_file(f1[i], Uf[i], 'uf{}'.format(i), t) for i in range(N)]
    poro.write_file(f2, Mf, 'mf', t)
    [poro.write_file(f3[i], p[i], 'p{}'.format(i), t) for i in range(N)]
    poro.write_file(f4, dU, 'du', t)

    domain_area += df.assemble(df.div(dU) * dx) * (1 - phi)
    sum_fluid_mass += df.assemble(Mf * dx)
    theor_fluid_mass += qi * rho * dt
    theor_sol = theor_fluid_mass * domain_area
    sum_disp += df.assemble(dU[0] * ds(4))
    avg_error.append(
        np.sqrt(((df.assemble(Mf * dx) - theor_sol) / theor_sol)**2))
    print(theor_sol, df.assemble(Mf * dx))

[f1[i].close() for i in range(N)]
f2.close()
[f3[i].close() for i in range(N)]
f4.close()
#
# The final error is calculated by normalizing the avg_error by the number of elements
# in the list of errors.