コード例 #1
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  # 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)
コード例 #2
0
    def update_time(self, actual_time, step_number):
        super(Problem, self).update_time(actual_time, step_number)
        if self.actual_time > 0.5 and int(round(self.actual_time * 1000)) % 1000 == 0:
            self.isWholeSecond = True
            seconds = int(round(self.actual_time))
            self.second_list.append(seconds)
            self.N1 = seconds*self.stepsInSecond
            self.N0 = (seconds-1)*self.stepsInSecond
        else:
            self.isWholeSecond = False

        self.solution = self.assemble_solution(self.actual_time)

        # Update boundary condition
        self.tc.start('updateBC')
        self.v_in.assign(self.solution)
        self.tc.end('updateBC')

        # construct analytic pressure (used for computing pressure and force errors)
        self.tc.start('analyticP')
        analytic_pressure = womersleyBC.analytic_pressure(self.factor, self.actual_time)
        self.sol_p = interpolate(analytic_pressure, self.pSpace)
        self.tc.end('analyticP')

        self.tc.start('analyticVnorms')
        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))
        self.listDict['av_norm_L2']['list'].append(self.analytic_v_norm_L2)
        self.listDict['av_norm_H1']['list'].append(self.analytic_v_norm_H1)
        self.listDict['av_norm_H1w']['list'].append(self.analytic_v_norm_H1w)
        self.tc.end('analyticVnorms')
コード例 #3
0
    def permeability_tensor(self, K):
        FS = self.geometry.f0.function_space()
        TS = TensorFunctionSpace(self.geometry.mesh, 'P', 1)
        d = self.geometry.dim()
        fibers = Function(FS)
        fibers.vector()[:] = self.geometry.f0.vector().get_local()
        fibers.vector()[:] /= df.norm(self.geometry.f0)
        if self.geometry.s0 is not None:
            # normalize vectors
            sheet = Function(FS)
            sheet.vector()[:] = self.geometry.s0.vector().get_local()
            sheet.vector()[:] /= df.norm(self.geometry.s0)
            if d == 3:
                csheet = Function(FS)
                csheet.vector()[:] = self.geometry.n0.vector().get_local()
                csheet.vector()[:] /= df.norm(self.geometry.n0)
        else:
            return Constant(1)

        from ufl import diag
        factor = 10
        if d == 3:
            ftensor = df.as_matrix(((fibers[0], sheet[0], csheet[0]),
                                    (fibers[1], sheet[1], csheet[1]),
                                    (fibers[2], sheet[2], csheet[2])))
            ktensor = diag(df.as_vector([K, K / factor, K / factor]))
        else:
            ftensor = df.as_matrix(
                ((fibers[0], sheet[0]), (fibers[1], sheet[1])))
            ktensor = diag(df.as_vector([K, K / factor]))

        permeability = df.project(
            df.dot(df.dot(ftensor, ktensor), df.inv(ftensor)), TS)
        return permeability
コード例 #4
0
    def update_time(self, actual_time, step_number):
        super(Problem, self).update_time(actual_time, step_number)
        if self.actual_time > 0.5 and abs(
                math.modf(actual_time)[0]) < 0.5 * self.metadata['dt']:
            self.second_list.append(int(round(self.actual_time)))

        self.solution = self.assemble_solution(self.actual_time)

        # Update boundary condition
        self.tc.start('updateBC')
        self.v_in.assign(self.onset_factor * self.solution)
        self.tc.end('updateBC')

        # construct analytic pressure (used for computing pressure and force errors)
        self.tc.start('analyticP')
        analytic_pressure = womersleyBC.analytic_pressure(
            self.factor, self.actual_time)
        self.sol_p = interpolate(analytic_pressure, self.pSpace)
        self.tc.end('analyticP')

        self.tc.start('analyticVnorms')
        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))
        self.listDict['av_norm_L2']['list'].append(self.analytic_v_norm_L2)
        self.listDict['av_norm_H1']['list'].append(self.analytic_v_norm_H1)
        self.listDict['av_norm_H1w']['list'].append(self.analytic_v_norm_H1w)
        self.tc.end('analyticVnorms')
コード例 #5
0
ファイル: test_boussinesq.py プロジェクト: nschloe/flow
def test_boussinesq_with_supg():
    u1, _, theta1 = compute_boussinesq(target_time=1.0, lcar=0.1, supg=True)
    ref = 3.9591568082077104e-06
    assert abs(norm(u1, 'L2') - ref) < 1.0e-6 * ref
    ref = 40.225818361936234
    assert abs(norm(theta1, 'L2') - ref) < 1.0e-6 * ref
    return
コード例 #6
0
ファイル: steady_cylinder.py プロジェクト: j-hr/projection
    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)
コード例 #7
0
ファイル: test_bcs.py プロジェクト: jakobes/Ocellaris
def debug_phi_plot(phi, phia, phih, plotname, compare_historical=False, **plotargs):
    """
    Only used while developing the tests, left here in case more tests are
    added that need some debug plotting as well
    """
    diff = phia.copy(deepcopy=True)
    diff.vector().axpy(-1, phih.vector())
    diff.vector().apply('insert')

    na = dolfin.norm(phia)
    nh = dolfin.norm(phih)
    nd = dolfin.norm(diff)
    nd2 = dolfin.errornorm(phi, phih)

    from matplotlib import pyplot

    pyplot.figure(figsize=(10, 20))

    pyplot.subplot(311)
    c = dolfin.plot(phia, **plotargs)
    pyplot.colorbar(c)
    pyplot.title('Analytical (norm: %g)' % na)

    pyplot.subplot(312)
    c = dolfin.plot(phih, **plotargs)
    pyplot.colorbar(c)
    pyplot.title('Numerical (norm: %g)' % nh)

    pyplot.subplot(313)
    c = dolfin.plot(diff, **plotargs)
    pyplot.colorbar(c)
    pyplot.title('Diff (norm: %g, errornorm: %g, rel: %g)' % (nd, nd2, nd2 / na))

    pyplot.tight_layout()
    pyplot.savefig(plotname)
    pyplot.close()

    if not compare_historical:
        return
    hist_file = plotname + '.npy'

    comm = phih.function_space().mesh().mpi_comm()
    mpi_size = dolfin.MPI.size(comm)
    if mpi_size != 1:
        return

    import os

    arr = phih.vector().get_local()
    if not os.path.isfile(hist_file):
        numpy.save(hist_file, arr)
        return

    hist = numpy.load(hist_file)
    print('hist', hist[:5])
    print('arr ', arr[:5])
    print('diff', (hist - arr)[:5])
    print('maxabs', abs(hist - arr).max())

    assert abs(hist - arr).max() < 1e-12
コード例 #8
0
ファイル: test_boussinesq.py プロジェクト: nschloe/flow
def test_boussinesq():
    u1, _, theta1 = compute_boussinesq(target_time=1.0, lcar=0.1, supg=False)
    ref = 3.959158183043053e-06
    assert abs(norm(u1, 'L2') - ref) < 1.0e-6 * ref
    ref = 40.225818326711604
    assert abs(norm(theta1, 'L2') - ref) < 1.0e-6 * ref
    return
コード例 #9
0
    def update_time(self, actual_time, step_number):
        super(Problem, self).update_time(actual_time, step_number)
        if self.actual_time > 0.5 and int(round(self.actual_time * 1000)) % 1000 == 0:
            self.isWholeSecond = True
            seconds = int(round(self.actual_time))
            self.second_list.append(seconds)
            self.N1 = seconds*self.stepsInSecond
            self.N0 = (seconds-1)*self.stepsInSecond
        else:
            self.isWholeSecond = False

        # Update boundary condition
        self.tc.start('updateBC')
        if not self.ic == 'correct':
            self.v_in.t = self.actual_time
        self.tc.end('updateBC')

        self.tc.start('analyticVnorms')
        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))
        self.listDict['av_norm_L2']['list'].append(self.analytic_v_norm_L2)
        self.listDict['av_norm_H1']['list'].append(self.analytic_v_norm_H1)
        self.listDict['av_norm_H1w']['list'].append(self.analytic_v_norm_H1w)
        self.tc.end('analyticVnorms')
コード例 #10
0
ファイル: solver.py プロジェクト: benjthrussell/symsolver
 def compute_errors( self, dphi_k, phi_k ):
     
     # compute residual of solution at this iteration - assemble form into a vector
     F = d.assemble( self.weak_residual_form( phi_k ) )
     
     # ... and compute norm. L2 is note yet implemented
     if self.norm_res=='L2':
         message = "UV_ERROR: L2 norm not implemented for residuals. Please use a different norm ('l2' or 'linf')"
         raise L2_Not_Implemented_For_F, message
     
     F_norm = d.norm( F, norm_type=self.norm_res )
     
     # now compute norm of change in the solution
     # this nested if is to preserve the structure of the original built-in FEniCS norm function 
     # within the modified rD_norm function
     if self.norm_change=='L2':
         # if you are here, you are computing the norm of a function object, as an integral
         # over the whole domain, and you need the r^2 factor in the measure (i.e. r^2 dr )
         dphi_norm = rD_norm( dphi_k, self.physics.D, func_degree, norm_type=self.norm_change )
         
     else:
         # if you are here, you are computing the norm of a vector. For this, the built-in norm function is
         # sufficient. The norm is either linf (max abs value at vertices) or l2 (Euclidean norm)
         dphi_norm = d.norm( dphi_k.vector(), norm_type=self.norm_change )
         
     return dphi_norm, F_norm
コード例 #11
0
ファイル: womersley_cylinder.py プロジェクト: j-hr/projection
    def update_time(self, actual_time, step_number):
        super(Problem, self).update_time(actual_time, step_number)
        if self.actual_time > 0.5 and abs(math.modf(actual_time)[0]) < 0.5*self.metadata['dt']:
            self.second_list.append(int(round(self.actual_time)))

        self.solution = self.assemble_solution(self.actual_time)

        # Update boundary condition
        self.tc.start('updateBC')
        self.v_in.assign(self.onset_factor * self.solution)
        self.tc.end('updateBC')

        # construct analytic pressure (used for computing pressure and force errors)
        self.tc.start('analyticP')
        analytic_pressure = womersleyBC.analytic_pressure(self.factor, self.actual_time)
        self.sol_p = interpolate(analytic_pressure, self.pSpace)
        self.tc.end('analyticP')

        self.tc.start('analyticVnorms')
        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))
        self.listDict['av_norm_L2']['list'].append(self.analytic_v_norm_L2)
        self.listDict['av_norm_H1']['list'].append(self.analytic_v_norm_H1)
        self.listDict['av_norm_H1w']['list'].append(self.analytic_v_norm_H1w)
        self.tc.end('analyticVnorms')
コード例 #12
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  # TODO modify by nu_factor
        print("Computing with Re = %f" % reynolds)

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

        if self.doErrControl:
            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)
            print("Prepared analytic solution.")

        # 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])
コード例 #13
0
    def compute(self, get):
        u = get(self.valuename)

        if u is None:
            return None

        norm_type = self.params.norm_type

        if isinstance(u, Function):
            norm_type = norm_type if norm_type != "default" else "L2"
            return norm(u, norm_type)
        elif isinstance(u, Vector):
            norm_type = norm_type if norm_type != "default" else "l2"
            return norm(u, norm_type)
        else:
            if isinstance(u, (int, long, float)):
                u = [u]

            assert hasattr(u, "__len__")

            if self.params.norm_type == 'default':
                norm_type = 'l2'

            if self.params.norm_type == 'linf':
                return max([abs(_u) for _u in u])

            else:
                # Extract norm type
                p = int(norm_type[1:])
                return sum(abs(_u)**p for _u in u)**(1. / p)
コード例 #14
0
def compute_norms(err,
                  vector_norms=["l2", "linf"],
                  function_norms=["L2", "H1"],
                  show=True,
                  tablefmt="simple",
                  save=False):
    """ Compute norms, output to terminal, etc. """
    info_split("Vector norms:", ", ".join(vector_norms))
    info_split("Function norms:", ", ".join(function_norms))

    headers = ["Fields"] + vector_norms + function_norms

    table = []
    for field in err.keys():
        row = [field]
        for norm_type in vector_norms:
            row.append(df.norm(err[field].vector(), norm_type=norm_type))
        for norm_type in function_norms:
            row.append(df.norm(err[field], norm_type=norm_type))
        table.append(row)

    from tabulate import tabulate
    tab_string = tabulate(table, headers, tablefmt=tablefmt, floatfmt="e")
    if show:
        info("\n" + tab_string + "\n")

    if save and rank == 0:
        info_split("Saving to file:", save)
        with open(save, "w") as outfile:
            outfile.write(tab_string)
コード例 #15
0
def calc_err(f_num, f_ana, normtype='l2'):
    """
    Calculate scaled L2 error
    """
    f_err = dolfin.Function(f_num.function_space())
    f_err.vector()[:] = f_ana.vector()[:] - f_num.vector()[:]
    if normtype == 'l2':
        return dolfin.norm(f_err) / dolfin.norm(f_ana)
    else:
        return dolfin.norm(f_err, normtype)
コード例 #16
0
def targetmediumparameters(Vl, X, myplot=None):
    """
    Arguments:
        Vl = function space
        X = x dimension of domain
    """
    # medium parameters:
    H1, H2, H3, TT = 0.9, 0.1, 0.5, 0.25
    CC = [2.5, 2.0, 2.0, 2.0]
    RR = [2.15, 2.1, 2.1, 2.1]
    #CC = [5.0, 2.0, 3.0, 4.0]
    #RR = [2.0, 2.1, 2.2, 2.5]
    LL, AA, BB = [], [], []
    for cc, rr in zip(CC, RR):
        ll = rr * cc * cc
        LL.append(ll)
        AA.append(1. / ll)
        BB.append(1. / rr)
    # velocity is in [km/s]
    c = createparam(CC, Vl, X, H1, H2, H3, TT)
    if not myplot == None:
        myplot.set_varname('c_target')
        myplot.plot_vtk(c)
    # density is in [10^12 kg/km^3]=[g/cm^3]
    # assume rocks shale-sand-shale + salt inside small rectangle
    # see Marmousi2 print-out
    rho = createparam(RR, Vl, X, H1, H2, H3, TT)
    if not myplot == None:
        myplot.set_varname('rho_target')
        myplot.plot_vtk(rho)
    # bulk modulus is in [10^12 kg/km.s^2]=[GPa]
    lam = createparam(LL, Vl, X, H1, H2, H3, TT)
    if not myplot == None:
        myplot.set_varname('lambda_target')
        myplot.plot_vtk(lam)
    #
    af = createparam(AA, Vl, X, H1, H2, H3, TT)
    if not myplot == None:
        myplot.set_varname('alpha_target')
        myplot.plot_vtk(af)
    bf = createparam(BB, Vl, X, H1, H2, H3, TT)
    if not myplot == None:
        myplot.set_varname('beta_target')
        myplot.plot_vtk(bf)
    # Check:
    ones = dl.interpolate(dl.Constant('1.0'), Vl)
    check1 = af.vector() * lam.vector()
    erra = dl.norm(check1 - ones.vector())
    assert erra < 1e-16
    check2 = bf.vector() * rho.vector()
    errb = dl.norm(check2 - ones.vector())
    assert errb < 1e-16

    return af, bf, c, lam, rho
コード例 #17
0
def test1():
    # setup meshes
    P = 0.3
    ref1 = 4
    ref2 = 14
    mesh1 = UnitSquare(2, 2)
    mesh2 = UnitSquare(2, 2)
    # refinement loops
    for level in range(ref1):
        mesh1 = refine(mesh1)
    for level in range(ref2):
        # mark and refine
        markers = CellFunction("bool", mesh2)
        markers.set_all(False)
        # randomly refine mesh
        for i in range(mesh2.num_cells()):
            if random() <= P:
                markers[i] = True
        mesh2 = refine(mesh2, markers)

    # create joint meshes
    mesh1j, parents1 = create_joint_mesh([mesh2], mesh1)
    mesh2j, parents2 = create_joint_mesh([mesh1], mesh2)

    # evaluate errors  joint meshes
    ex1 = Expression("sin(2*A*x[0])*sin(2*A*x[1])", A=10)
    V1 = FunctionSpace(mesh1, "CG", 1)
    V2 = FunctionSpace(mesh2, "CG", 1)
    V1j = FunctionSpace(mesh1j, "CG", 1)
    V2j = FunctionSpace(mesh2j, "CG", 1)
    f1 = interpolate(ex1, V1)
    f2 = interpolate(ex1, V2)
    # interpolate on respective joint meshes
    f1j = interpolate(f1, V1j)
    f2j = interpolate(f2, V2j)
    f1j1 = interpolate(f1j, V1)
    f2j2 = interpolate(f2j, V2)
    # evaluate error with regard to original mesh
    e1 = Function(V1)
    e2 = Function(V2)
    e1.vector()[:] = f1.vector() - f1j1.vector()
    e2.vector()[:] = f2.vector() - f2j2.vector()
    print "error on V1:", norm(e1, "L2")
    print "error on V2:", norm(e2, "L2")

    plot(f1j, title="f1j")
    plot(f2j, title="f2j")
    plot(mesh1, title="mesh1")
    plot(mesh2, title="mesh2")
    plot(mesh1j, title="joint mesh from mesh1")
    plot(mesh2j, title="joint mesh from mesh2", interactive=True)
コード例 #18
0
    def compute_what(self, mhat):
        """ Compute update direction for what, given mhat """
        self.wxhat.vector().zero()
        self.wxhat.vector().axpy(
            1.0, self.invMwd * (self.Ax * mhat - self.gwx.vector()))
        normwxhat = norm(self.wxhat.vector())

        self.wyhat.vector().zero()
        self.wyhat.vector().axpy(
            1.0, self.invMwd * (self.Ay * mhat - self.gwy.vector()))
        normwyhat = norm(self.wyhat.vector())

        if self.parameters['print']:
            print '[TVPD] |what|={}'.format(
                np.sqrt(normwxhat**2 + normwyhat**2))
コード例 #19
0
ファイル: stokes_heat.py プロジェクト: prklVIP/maelstrom
 def solve(self, problem, vector):
     res = vector.copy()
     problem.F(res, vector)
     nrm = norm(res)
     nrm0 = nrm
     k = 0
     self._report(k, nrm, nrm0)
     while nrm > self.parameters['absolute_tolerance'] \
             or nrm / nrm0 > self.parameters['relative_tolerance']:
         problem.F(res, vector)
         vector[:] += res
         nrm = norm(res)
         k += 1
         self._report(k, nrm, nrm0)
     return
コード例 #20
0
ファイル: stokes_heat.py プロジェクト: nschloe/maelstrom
 def solve(self, problem, vector):
     res = vector.copy()
     problem.F(res, vector)
     nrm = norm(res)
     nrm0 = nrm
     k = 0
     self._report(k, nrm, nrm0)
     while nrm > self.parameters['absolute_tolerance'] \
             or nrm / nrm0 > self.parameters['relative_tolerance']:
         problem.F(res, vector)
         vector[:] += res
         nrm = norm(res)
         k += 1
         self._report(k, nrm, nrm0)
     return
コード例 #21
0
def targetmediumparameters(Vl, X, myplot=None):
    """
    Arguments:
        Vl = function space
        X = x dimension of domain
    """
    # medium parameters:
    size = 0.4
    AA = [1.0, 1.4]
    BB = [1.0, 2.0]
    CC, LL, RR = [], [], []
    for aa, bb in zip(AA, BB):
        cc = np.sqrt(bb / aa)
        rr = 1. / bb
        ll = 1. / aa
        CC.append(cc)
        RR.append(rr)
        LL.append(ll)
    c = createparam(CC, Vl, X, size)
    if not myplot == None:
        myplot.set_varname('c_target')
        myplot.plot_vtk(c)
    rho = createparam(RR, Vl, X, size)
    if not myplot == None:
        myplot.set_varname('rho_target')
        myplot.plot_vtk(rho)
    lam = createparam(LL, Vl, X, size)
    if not myplot == None:
        myplot.set_varname('lambda_target')
        myplot.plot_vtk(lam)
    at = createparam(AA, Vl, X, size)
    if not myplot == None:
        myplot.set_varname('alpha_target')
        myplot.plot_vtk(at)
    bt = createparam(BB, Vl, X, size)
    if not myplot == None:
        myplot.set_varname('beta_target')
        myplot.plot_vtk(bt)
    # Check:
    ones = dl.interpolate(dl.Constant('1.0'), Vl)
    check1 = at.vector() * lam.vector()
    erra = dl.norm(check1 - ones.vector())
    assert erra < 1e-16, erra
    check2 = bt.vector() * rho.vector()
    errb = dl.norm(check2 - ones.vector())
    assert errb < 1e-16, errb

    return at, bt, c, lam, rho
コード例 #22
0
ファイル: womersley_cylinder.py プロジェクト: j-hr/projection
 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_out - p_in)/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('analyticP')
     analytic_gradient = womersleyBC.analytic_pressure_grad(self.factor, self.actual_time)
     if not is_tent:
         self.last_analytic_pressure_norm = norm(self.sol_p, norm_type='L2')
         self.listDict['ap_norm']['list'].append(self.last_analytic_pressure_norm)
     self.tc.end('analyticP')
     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(analytic_gradient)
     self.listDict['pgE2' if is_tent else 'pgE']['list'].append(computed_gradient-analytic_gradient)
     self.listDict['pgEA2' if is_tent else 'pgEA']['list'].append(abs(computed_gradient-analytic_gradient))
     self.tc.end('errorP')
     if self.doSaveDiff:
         # sol_pg_expr = Expression(("0", "0", "pg"), pg=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
コード例 #23
0
def compvperror(reffemp=None, vref=None, pref=None,
                curfemp=None, vcur=None, pcur=None):
    try:
        verf, perf = dts.expand_vp_dolfunc(vc=vref-vcur, pc=pref-pcur,
                                           zerodiribcs=True, **reffemp)
        verr = dolfin.norm(verf)
        perr = dolfin.norm(perf)
        # vreff, preff = dts.expand_vp_dolfunc(vc=vref, pc=pref, **reffemp)
        # vcurf, pcurf = dts.expand_vp_dolfunc(vc=vcur, pc=pcur, **curfemp)
        # verr = dolfin.norm(vreff - vcurf)
        # perr = dolfin.norm(preff - pcurf)
    except ValueError:  # obviously not the same FEM spaces
        vreff, preff = dts.expand_vp_dolfunc(vc=vref, pc=pref, **reffemp)
        vcurf, pcurf = dts.expand_vp_dolfunc(vc=vcur, pc=pcur, **curfemp)
        verr = dolfin.errornorm(vreff, vcurf)
        perr = dolfin.errornorm(preff, pcurf)
    return verr, perr
コード例 #24
0
 def compute_div(self, is_tent, velocity):
     self.tc.start('divNorm')
     div_list = self.listDict['d2' if is_tent else 'd']['list']
     div_list.append(norm(velocity, 'Hdiv0'))
     if self.isWholeSecond:
         self.listDict['d2' if is_tent else 'd']['slist'].append(
             sum([i*i for i in div_list[self.N0:self.N1]])/self.stepsInSecond)
     self.tc.end('divNorm')
コード例 #25
0
def _check_space_order(problem, method):
    mesh_generator, solution, weak_F = problem()

    # Translate data into FEniCS expressions.
    fenics_sol = Expression(smp.prining.ccode(solution['value']),
                            degree=solution['degree'],
                            t=0.0
                            )

    # Create initial solution.
    theta0 = Expression(fenics_sol.cppcode,
                        degree=solution['degree'],
                        t=0.0,
                        cell=triangle
                        )

    # Estimate the error component in space.
    # Leave out too rough discretizations to avoid showing spurious errors.
    N = [2 ** k for k in range(2, 8)]
    dt = 1.0e-8
    Err = []
    H = []
    for n in N:
        mesh = mesh_generator(n)
        H.append(MPI.max(mesh.hmax()))
        V = FunctionSpace(mesh, 'CG', 3)
        # Create boundary conditions.
        fenics_sol.t = dt
        #bcs = DirichletBC(V, fenics_sol, 'on_boundary')
        # Create initial state.
        theta_approx = method(V,
                              weak_F,
                              theta0,
                              0.0, dt,
                              bcs=[solution],
                              tol=1.0e-12,
                              verbose=True
                              )
        # Compute the error.
        fenics_sol.t = dt
        Err.append(errornorm(fenics_sol, theta_approx)
                   / norm(fenics_sol, mesh=mesh)
                   )
        print('n: %d    error: %e' % (n, Err[-1]))

    from matplotlib import pyplot as pp
    # Compare with order 1, 2, 3 curves.
    for o in [2, 3, 4]:
        pp.loglog([H[0], H[-1]],
                  [Err[0], Err[0] * (H[-1] / H[0]) ** o],
                  color='0.5'
                  )
    # Finally, the actual data.
    pp.loglog(H, Err, '-o')
    pp.xlabel('h_max')
    pp.ylabel('||u-u_h|| / ||u||')
    pp.show()
    return
コード例 #26
0
def testsplitassign():
    USEi = True

    mesh = dl.UnitSquareMesh(40, 40)
    V1 = dl.FunctionSpace(mesh, "Lagrange", 2)
    V2 = dl.FunctionSpace(mesh, "Lagrange", 2)
    if USEi:
        V1V2 = createMixedFSi([V1, V2])
        splitassign = SplitAndAssigni([V1, V2], mesh.mpi_comm())
    else:
        V1V2 = createMixedFS(V1, V2)
        splitassign = SplitAndAssign(V1, V2, mesh.mpi_comm())

    mpirank = dl.MPI.rank(mesh.mpi_comm())

    u = dl.interpolate(dl.Expression(("x[0]*x[1]", "11+x[0]+x[1]"), degree=10),
                       V1V2)
    uu = dl.Function(V1V2)
    u1, u2 = u.split(deepcopy=True)
    u1v, u2v = splitassign.split(u.vector())
    u11 = dl.interpolate(dl.Expression("x[0]*x[1]", degree=10), V1)
    u22 = dl.interpolate(dl.Expression("11+x[0]+x[1]", degree=10), V2)
    a,b,c,d= dl.norm(u1.vector()-u1v), dl.norm(u2.vector()-u2v),\
    dl.norm(u1.vector()-u11.vector()), dl.norm(u2.vector()-u22.vector())
    if mpirank == 0:
        print '\nSplitting an interpolated function:', a, b, c, d

    if USEi:
        uv = splitassign.assign([u1v, u2v])
    else:
        uv = splitassign.assign(u1v, u2v)
    dl.assign(uu.sub(0), u11)
    dl.assign(uu.sub(1), u22)
    a, b = dl.norm(uv - u.vector()), dl.norm(uv - uu.vector())
    if mpirank == 0:
        print 'Putting it back together:', a, b

    for ii in xrange(10):
        u.vector()[:] = np.random.randn(len(u.vector().array()))
        u1, u2 = u.split(deepcopy=True)
        u1v, u2v = splitassign.split(u.vector())
        if USEi:
            uv = splitassign.assign([u1v, u2v])
        else:
            uv = splitassign.assign(u1v, u2v)
        a, b = dl.norm(u1.vector() - u1v), dl.norm(u2.vector() - u2v)
        c = dl.norm(uv - u.vector())
        if mpirank == 0:
            print 'Splitting random numbers:', a, b
            print 'Putting it back together:', c
コード例 #27
0
def test_residual(problem):
    mesh_size = 16
    mesh_generator, _, f, _ = problem()
    mesh, dx, _ = mesh_generator(mesh_size)

    # from dolfin import plot, interactive
    # plot(mesh)
    # interactive()

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

    Mu = {0: 1.0}
    Sigma = {0: 1.0}
    omega = 1.0
    convections = {}
    rhs = {0: f["value"]}

    # solve equation system
    phi_list = maxwell.solve(
        V,
        dx,
        Mu=Mu,
        Sigma=Sigma,
        omega=omega,
        f_list=[rhs],
        f_degree=f["degree"],
        convections=convections,
        tol=1.0e-15,
        bcs=None,
        verbose=False,
    )
    phi = phi_list[0]

    # build residuals
    Res_r, Res_i, Rhs_r, Rhs_i = _build_residuals(V, dx, phi, omega, Mu, Sigma,
                                                  convections, rhs,
                                                  f["degree"])

    # Assert that the norm of the residual is smaller than a tolerance times
    # the norm of the right-hand side. This is a typical Krylov criterion.
    nrm_rhs = sqrt(norm(Rhs_r)**2 + norm(Rhs_i)**2)
    nrm_res = sqrt(norm(Res_r)**2 + norm(Res_i)**2)
    assert nrm_res < 1.0e-13 * nrm_rhs

    return
コード例 #28
0
    def grad(self, m):
        """ compute the gradient at m """
        setfct(self.m, m)
        self._assemble_invMw()

        self.gwx.vector().zero()
        self.gwx.vector().axpy(1.0, assemble(self.misfitwx))
        normgwx = norm(self.gwx.vector())

        self.gwy.vector().zero()
        self.gwy.vector().axpy(1.0, assemble(self.misfitwy))
        normgwy = norm(self.gwy.vector())

        if self.parameters['print']:
            print '[TVPD] |gw|={}'.format(np.sqrt(normgwx**2 + normgwy**2))

        return self.Htvx*(self.wx.vector() - self.invMwd*self.gwx.vector()) \
        + self.Htvy*(self.wy.vector() - self.invMwd*self.gwy.vector())
コード例 #29
0
def targetmediumparameters(Vl, X, myplot=None):
    """
    Arguments:
        Vl = function space
        X = x dimension of domain
    """
    # velocity is in [km/s]
    c = createparam(Vl, DD, CC[0], CC[1], CC[2])
    if not myplot == None:
        myplot.set_varname('c_target')
        myplot.plot_vtk(c)
    # density is in [10^12 kg/km^3]=[g/cm^3]
    # assume rocks shale-sand-shale + salt inside small rectangle
    # see Marmousi2 print-out
    rho = createparam(Vl, DD, RR[0], RR[1], RR[2])
    if not myplot == None:
        myplot.set_varname('rho_target')
        myplot.plot_vtk(rho)
    # bulk modulus is in [10^12 kg/km.s^2]=[GPa]
    lam = createparam(Vl, DD, LL[0], LL[1], LL[2])
    if not myplot == None:
        myplot.set_varname('lambda_target')
        myplot.plot_vtk(lam)
    #
    af = createparam(Vl, DD, AA[0], AA[1], AA[2])
    if not myplot == None:
        myplot.set_varname('alpha_target')
        myplot.plot_vtk(af)
    bf = createparam(Vl, DD, BB[0], BB[1], BB[2])
    if not myplot == None:
        myplot.set_varname('beta_target')
        myplot.plot_vtk(bf)
    # Check:
    ones = dl.interpolate(dl.Constant('1.0'), Vl)
    check1 = af.vector() * lam.vector()
    erra = dl.norm(check1 - ones.vector())
    assert erra < 1e-16
    check2 = bf.vector() * rho.vector()
    errb = dl.norm(check2 - ones.vector())
    assert errb < 1e-16

    return af, bf, c, lam, rho
コード例 #30
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)
コード例 #31
0
def get_umax(u):
    # Compute the maximum velocity.
    # First get a vector with the squared norms, then get the maximum value of
    # it. This assumes that the maximum is attained in a node, and that the
    # vectors express the value in certain control points (nodes, edge
    # midpoints etc.).
    usplit = u.split(deepcopy=True)
    vec = usplit[0].vector() * usplit[0].vector()
    for k in range(1, len(u)):
        vec += usplit[k].vector() * usplit[k].vector()
    return numpy.sqrt(norm(vec, "linf"))
コード例 #32
0
ファイル: fenics_utils.py プロジェクト: SpuqTeam/spuq
def error_norm(vec1, vec2, normstr="L2"):
        e = 0.0
        if isinstance(vec1, MultiVector):
            assert isinstance(vec2, MultiVector)
            assert vec1.active_indices() == vec2.active_indices()
            for mi in vec1.keys():
                V = vec1[mi]._fefunc.function_space()
                errfunc = Function(V, vec1[mi]._fefunc.vector() - vec2[mi]._fefunc.vector())
                if isinstance(normstr, str):
                    e += norm(errfunc, normstr) ** 2
                else:
                    e += normstr(errfunc) ** 2
            return sqrt(e)
        else:
            V = vec1.function_space()
            errfunc = Function(V, vec1.vector() - vec2.vector())
            if isinstance(normstr, str):
                return norm(errfunc, normstr)
            else:
                return normstr(errfunc)
コード例 #33
0
ファイル: solver.py プロジェクト: scaramouche-00/phienics
    def compute_errors( self, du_k, u_k ):
        r"""
        Computes measures of error at a given iteration.
        
        With reference to Eq. :eq:`Eq_residual_criterion` and Eq. :eq:`Eq_change_criterion`, 
        this function computes the norm of the residual :math:`|| \mathcal{F}[u^{(k)}] ||` and 
        the norm of the change in the solution :math:`|| u^{(k)}-u^{(k-1)} ||` at one given iteration.

        *Parameters*
            du_k
                difference in the solution over the whole domain at this iteration. 
            u_k
                solution at this iteration, for the computation of the residual :math:`||F(u_k)||`

        """
        
        # compute residual of solution at this iteration - assemble form into a vector
        F = d.assemble( self.weak_residual_form( u_k ) )
        
        # ... and compute norm. L2 is note yet implemented
        if self.norm_res=='L2':
            message = "L2 norm not implemented for residuals. Please use a different norm ('l2' or 'linf')"
            raise NotImplementedError(message)

        # the built-in norm function is fine because it's computing the linf or Euclidean norm here
        F_norm = d.norm( F, norm_type=self.norm_res )
        
        # now compute norm of change in the solution
        # this nested if is to preserve the structure of the original built-in FEniCS norm function 
        # within the modified r2_norm function
        if self.norm_change=='L2':
            # if you are here, you are computing the norm of a function object, as an integral
            # over the whole domain, and you need the r^2 factor in the measure (i.e. r^2 dr )
            du_norm = r2_norm( du_k, self.fem.func_degree, norm_type=self.norm_change )
            
        else:
            # if you are here, you are computing the norm of a vector. For this, the built-in norm function is
            # sufficient. The norm is either linf (max abs value at vertices) or l2 (Euclidean norm)
            du_norm = d.norm( du_k.vector(), norm_type=self.norm_change )

        return du_norm, F_norm
コード例 #34
0
ファイル: flux_module.py プロジェクト: mhanus/GOAT
  def eigenvalue_residual_norm(self, norm_type='l2'):
    r = PETScVector()
    y = PETScVector()

    self.B.mult(self.sln_vec, r)
    self.A.mult(self.sln_vec, y)
    r.apply("insert")
    y.apply("insert")

    r -= self.keff * y

    return norm(r, norm_type)
コード例 #35
0
def _check_spatial_order(problem, method):
    mesh_generator, solution, weak_F = problem()

    # Translate data into FEniCS expressions.
    fenics_sol = Expression(sympy.printing.ccode(solution['value']),
                            degree=solution['degree'],
                            t=0.0)

    # Create initial solution.
    theta0 = Expression(fenics_sol.cppcode,
                        degree=solution['degree'],
                        t=0.0,
                        cell=triangle)

    # Estimate the error component in space.
    # Leave out too rough discretizations to avoid showing spurious errors.
    N = [2**k for k in range(2, 8)]
    dt = 1.0e-8
    Err = []
    H = []
    for n in N:
        mesh = mesh_generator(n)
        H.append(MPI.max(mesh.hmax()))
        V = FunctionSpace(mesh, 'CG', 5)
        # Create boundary conditions.
        fenics_sol.t = dt
        # bcs = DirichletBC(V, fenics_sol, 'on_boundary')
        # Create initial state.
        theta_approx = method(V,
                              weak_F,
                              theta0,
                              0.0,
                              dt,
                              bcs=[solution],
                              tol=1.0e-12,
                              verbose=True)
        # Compute the error.
        fenics_sol.t = dt
        Err.append(
            errornorm(fenics_sol, theta_approx) / norm(fenics_sol, mesh=mesh))
        print('n: %d    error: %e' % (n, Err[-1]))

    # Plot order curves for comparison.
    for order in [2, 3, 4]:
        plt.loglog([H[0], H[-1]], [Err[0], Err[0] * (H[-1] / H[0])**order],
                   color='0.5')
    # Finally, the actual data.
    plt.loglog(H, Err, '-o')
    plt.xlabel('h_max')
    plt.ylabel('||u-u_h|| / ||u||')
    plt.show()
    return
コード例 #36
0
ファイル: postprocessor.py プロジェクト: bcrestel/fenicstools
 def __init__(self, meth, Vm, mtrue, maxnbLS=15):
     self.meth = meth
     if self.meth == 'Newt': self.Newt = True
     else:   self.Newt = False
     self.Vm = Vm
     self.mtrue = interpolate(mtrue, self.Vm)
     self.diff = Function(self.Vm)
     self.normmtrue = norm(self.mtrue)   # Note: this is a global value
     self.maxnbLS = maxnbLS
     self._createoutputlines()
     self.index = 0
     self.gradnorminit = None
     self.printrank = 0
コード例 #37
0
ファイル: postprocessor.py プロジェクト: bcrestel/fenicstools
 def __init__(self, meth, Vm, mtrue, maxnbLS=15):
     self.meth = meth
     if self.meth == 'Newt': self.Newt = True
     else: self.Newt = False
     self.Vm = Vm
     self.mtrue = interpolate(mtrue, self.Vm)
     self.diff = Function(self.Vm)
     self.normmtrue = norm(self.mtrue)  # Note: this is a global value
     self.maxnbLS = maxnbLS
     self._createoutputlines()
     self.index = 0
     self.gradnorminit = None
     self.printrank = 0
コード例 #38
0
def comp_cont_error(v, fpbc, Q):
    """Compute the L2 norm of the residual of the continuity equation
            Bv = g
    """

    q = TrialFunction(Q)
    divv = assemble(q*div(v)*dx)

    conRhs = Function(Q)
    conRhs.vector().set_local(fpbc)

    ContEr = norm(conRhs.vector() - divv)

    return ContEr
コード例 #39
0
    def __abs__(self):
        """
        Overloading the abs operator for mesh types

        Returns:
            float: absolute maximum of all mesh values
        """

        # take absolute values of the mesh values

        absval = df.norm(self.values, 'L2')

        # return maximum
        return absval
コード例 #40
0
ファイル: fenics_mesh.py プロジェクト: torbjoernk/pySDC
    def __abs__(self):
        """
        Overloading the abs operator for mesh types

        Returns:
            absolute maximum of all mesh values
        """

        # take absolute values of the mesh values

        absval = df.norm(self.values,'L2')

        # return maximum
        return absval
コード例 #41
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
コード例 #42
0
def test_bndModel():

    Lx, Ly, Nx, Ny, NxyMicro = 2.0, 0.5, 12, 4, 50
    singleScaleFile = resultFolder + "bar_single_scale.xdmf"
    multiScaleFile = resultFolder + "bar_multiscale_standalone_%s.xdmf"
    start = timer()
    print("simulating single scale")
    os.system("python bar_single_scale.py %d %d" % (Nx, Ny))
    end = timer()
    print('finished in ', end - start)

    for bndModel in ['per', 'lin', 'MR', 'lag']:
        suffix = "{0} {1} {2} {3} > log_{3}.txt".format(
            Nx, Ny, NxyMicro, bndModel)

        start = timer()
        print("simulating using " + bndModel)
        os.system("python bar_multiscale_standalone.py " + suffix)
        end = timer()
        print('finished in ', end - start)

    mesh = df.RectangleMesh(df.Point(0.0, 0.0), df.Point(Lx, Ly), Nx, Ny,
                            "right/left")

    Uh = df.VectorFunctionSpace(mesh, "Lagrange", 1)

    uh0 = df.Function(Uh)

    with df.XDMFFile(resultFolder + "bar_single_scale.xdmf") as f:
        f.read_checkpoint(uh0, 'u')

    error = {}
    ehtemp = df.Function(Uh)

    for bndModel in ['per', 'lin', 'MR', 'lag']:

        with df.XDMFFile(multiScaleFile % bndModel) as f:
            f.read_checkpoint(ehtemp, 'u')

        ehtemp.vector().set_local(ehtemp.vector().get_local()[:] -
                                  uh0.vector().get_local()[:])

        error[bndModel] = df.norm(ehtemp)
        print(error[bndModel])

    assert np.abs(error['lin'] - error['lag']) < 1e-12
    assert np.abs(error['per'] - 0.006319071443377064) < 1e-12
    assert np.abs(error['lin'] - 0.007901978018038507) < 1e-12
    assert np.abs(error['MR'] - 0.0011744201374588351) < 1e-12
コード例 #43
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 / self.args.nufactor
        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", degree=1), 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'))

        one = (interpolate(Expression('1.0', degree=1), Q))
        self.outflow_area = assemble(one * self.dsOut)
        print('Outflow area:', self.outflow_area)
コード例 #44
0
def test_iterate_gamma(problem):

    target_gamma = 0.1
    gamma = problem.material.activation

    if has_dolfin_adjoint:
        dolfin.parameters["adjoint"]["stop_annotating"] = False
        dolfin_adjoint.adj_reset()

    iterate(problem, gamma, target_gamma)

    assert all(gamma.vector().get_local() == target_gamma)
    assert dolfin.norm(problem.state.vector()) > 0

    if has_dolfin_adjoint:
        assert dolfin_adjoint.replay_dolfin(tol=1e-12)
コード例 #45
0
ファイル: problem.py プロジェクト: mhanus/EVC
  def rayleigh_quotient(self, vec, A=None, B=None):
    if A is None:
      A = self.A_fine
      B = self.B_fine

    r = PETScVector()
    A.mult(vec, r)
    nom = MPI_sum( numpy.dot(r, vec) )

    if B.size(0) > 0:
      B.mult(vec, r)
      denom = MPI_sum( numpy.dot(r, vec) )
    else:
      denom = sqr(norm(r, norm_type='l2'))

    return nom/denom
コード例 #46
0
def test_parallel():

    Lx, Ly, Ny, Nx, NxyMicro = 0.5, 2.0, 12, 5, 50
    bndModel = 'per'
    suffix = "%d %d %d %s > log_%s.txt" % (Nx, Ny, NxyMicro, bndModel,
                                           bndModel)

    start = timer()
    print("simulating single core")
    os.system("python bar_multiscale_standalone.py " + suffix)
    end = timer()
    print('finished in ', end - start)

    for nProc in [1, 2, 3, 4]:
        start = timer()
        print("simulating using nProc", nProc)
        os.system("mpirun -n %d python bar_multiscale_parallel.py " % nProc +
                  suffix)
        end = timer()
        print('finished in ', end - start)

    mesh = df.RectangleMesh(df.Point(0.0, 0.0), df.Point(Lx, Ly), Nx, Ny,
                            "right/left")

    Uh = df.VectorFunctionSpace(mesh, "Lagrange", 1)

    uh0 = df.Function(Uh)

    with df.XDMFFile("bar_multiscale_standalone_%s.xdmf" % bndModel) as f:
        f.read_checkpoint(uh0, 'u')

    error = {}
    ehtemp = df.Function(Uh)

    for nProc in [1, 2, 3, 4]:

        with df.XDMFFile("bar_multiscale_parallel_%s_np%d.xdmf" %
                         (bndModel, nProc)) as f:
            f.read_checkpoint(ehtemp, 'u')

        ehtemp.vector().set_local(ehtemp.vector().get_local()[:] -
                                  uh0.vector().get_local()[:])

        error[nProc] = df.norm(ehtemp)

    assert np.max(np.array(list(error.values()))) < 1e-13
コード例 #47
0
ファイル: problem.py プロジェクト: mhanus/EVC
  def residual_norm(self, vec, lam, norm_type='l2', A=None, B=None):
    if A is None:
      A = self.A_fine
      B = self.B_fine

    r = PETScVector()
    A.mult(vec, r)

    if B.size(0) > 0:
      y = PETScVector()
      B.mult(vec, y)
    else:
      y = 1

    r -= lam*y

    return norm(r,norm_type)
コード例 #48
0
ファイル: ErrorNorm.py プロジェクト: jakobes/cbcpost-fork
    def compute(self, get):
        u = get(self.valuename1)
        uh = get(self.valuename2)

        if u is None:
            return None

        if isinstance(uh, Function):
            norm_type = self.params.norm_type if self.params.norm_type != "default" else "L2"
            err = errornorm(u, uh, norm_type=norm_type, degree_rise=self.params.degree_rise)
            if self.params.relative:
                return err/(norm(u, norm_type=norm_type)+DOLFIN_EPS)
            else:
                return err
        else:
            if isinstance(u, (int, long, float)):
                u = [u]
            if isinstance(uh, (int, long, float)):
                uh = [uh]

            assert hasattr(u, "__len__")
            assert hasattr(uh, "__len__")
            assert len(u) == len(uh)

            if self.params.norm_type == 'default':
                norm_type = 'l2'
            else:
                norm_type = self.params.norm_type

            if norm_type == 'linf':
                err = max([abs(_u-_uh) for _u,_uh in zip(u,uh)])
                if self.params.relative:
                    return err/(max([abs(_u) for _u in u])+DOLFIN_EPS)
                else:
                    return err

            else:
                # Extract norm type
                p = int(norm_type[1:])
                err = sum(abs(_u-_uh)**p for _u, _uh in zip(u,uh))**(1./p)
                if self.params.relative:
                    return err/(sum(abs(_u)**p for _u in u)**(1./p)+DOLFIN_EPS)
                else:
                    return err
コード例 #49
0
ファイル: evc_solver.py プロジェクト: mhanus/EVC
  def solve(self, max_it, res_norm_tol, smoothing_steps=None, norm_type='l2'):
    self.num_it_coarse = 0
    self.num_it_fine = 0

    if smoothing_steps is None:
      smoothing_steps = self.problem.beta/2+1

    for i in xrange(max_it):
      if self.verbosity >= 1:
        print0(pid+"Iteration {}".format(i))

      self.update_coarse_level()
      self.solve_on_coarse_level()
      self.prolongate()
      self.smooth_on_fine_level(smoothing_steps)

      self.vec_fine *= 1./norm(self.vec_fine, norm_type)

      if self.problem.residual_norm(norm_type) <= res_norm_tol:
        self.num_it = i+1
        break

    self.lam = self.problem.rayleigh_quotient(self.vec_fine)
    self.num_it_fine_smoothing = self.num_it * smoothing_steps
コード例 #50
0
ファイル: general_problem.py プロジェクト: j-hr/projection
 def compute_div(self, is_tent, velocity):
     self.tc.start('divNorm')
     div_list = self.listDict['d2' if is_tent else 'd']['list']
     div_list.append(norm(velocity, 'Hdiv0'))
     self.tc.end('divNorm')
コード例 #51
0
ファイル: residual_estimator.py プロジェクト: SpuqTeam/spuq
    def evaluateLocalProjectionError(cls, w, mu, m, coeff_field, pde, Lambda, maxh=0.0, local=True, projection_degree_increase=1, refine_mesh=1):
        """Evaluate the local projection error according to EGSZ (6.4).

        Localisation of the global projection error (4.8) by (6.4)
        ..math::
            \zeta_{\mu,T,m}^{\mu\pm e_m} := ||a_m/\overline{a}||_{L^\infty(D)} \alpha_{\mu_m\pm 1}\int_T | \nabla( \Pi_{\mu\pm e_m}^\mu(\Pi_\mu^{\mu\pm e_m} w_{N,mu\pm e_)m})) - w_{N,mu\pm e_)m} |^2\;dx

        The sum :math:`\zeta_{\mu,T,m}^{\mu+e_m} + \zeta_{\mu,T,m}^{\mu-e_m}` is returned.
        """

        # determine ||a_m/\overline{a}||_{L\infty(D)} (approximately)
        a0_f = coeff_field.mean_func
        am_f, _ = coeff_field[m]
        if isinstance(a0_f, tuple):
            assert isinstance(am_f, tuple)
            a0_f = a0_f[0]
            am_f = am_f[0]
        # create discretisation space
        V_coeff, _, _, _ = w[mu].basis.refine_maxh(maxh)
        # interpolate coefficient functions on mesh
        f_coeff = V_coeff.new_vector(sub_spaces=0)
#        print "evaluateLocalProjectionError"
#        print f_coeff.num_sub_spaces
#        print a0_f.value_shape()
        f_coeff.interpolate(a0_f)
        amin = f_coeff.min_val
        f_coeff.interpolate(am_f)
        ammax = f_coeff.max_val
        ainfty = ammax / amin
        assert isinstance(ainfty, float)
        logger.debug("==== local projection error for mu = %s ====", mu)
        logger.debug("amin = %f  amax = %f  ainfty = %f", amin, ammax, ainfty)

        # prepare polynom coefficients
        _, am_rv = coeff_field[m]
        beta = am_rv.orth_polys.get_beta(mu[m])

        # mu+1
        mu1 = mu.inc(m)
        if mu1 in Lambda:
            logger.debug("[LPE-A] local projection error for mu = %s with %s", mu, mu1)

            # debug---
#            if True:
#                from dolfin import Function, inner
#                V1 = w[mu]._fefunc.function_space();
#                ufl = V1.ufl_element();
#                V2 = FunctionSpace(V1.mesh(), ufl.family(), ufl.degree() + 1)
#                f1 = Function(V1)
#                f1.interpolate(w[mu1]._fefunc)
#                f12 = Function(V2)
#                f12.interpolate(f1)
#                f2 = Function(V2)
#                f2.interpolate(w[mu1]._fefunc)
#                err2 = Function(V2, f2.vector() - f12.vector())
#                aerr = a0_f * inner(nabla_grad(err2), nabla_grad(err2)) * dx
#                perr = sqrt(assemble(aerr))
#                logger.info("DEBUG A --- global projection error %s - %s: %s", mu1, mu, perr)
            # ---debug

            # evaluate H1 semi-norm of projection error
            error1, sum_up = w.get_projection_error_function(mu1, mu, 1 + projection_degree_increase, refine_mesh=refine_mesh)
            logger.debug("global projection error norms: L2 = %s and H1 = %s", norm(error1._fefunc, "L2"), norm(error1._fefunc, "H1"))
#            pe = weighted_H1_norm(a0_f, error1, local)  # TODO: this should be the energy error!
#            pe = sum_up(pe)     # summation for cells according to reference mesh refinement
            if local:
                energynorm = pde.get_energy_norm(mesh=error1._fefunc.function_space().mesh())
                pe = energynorm(error1._fefunc)
                pe = np.array([e ** 2 for e in pe])     # square norms
                pe = sum_up(pe)                         # summation for cells according to reference mesh refinement
                pe = np.sqrt(pe)                        # take square root again for summed norm
                logger.debug("summed local projection errors: %s", sqrt(sum([e ** 2 for e in pe])))
#                # DEBUG---                
#                pe2 = weighted_H1_norm(a0_f, error1, local)  # TODO: this should be the energy error!
#                pe2 = np.array([e ** 2 for e in pe2])     # square norms
#                pe2 = sum_up(pe2)                         # summation for cells according to reference mesh refinement
#                pe2 = np.sqrt(pe2)                        # take square root again for summed norm
#                logger.warn("[A] summed local projection errors: %s = %s \t weights: %s = %s", sqrt(sum([e ** 2 for e in pe])), sqrt(sum([e2 ** 2 for e2 in pe2])), a0_f((0, 0)), pde._a0((0, 0)))
#                # ---DEBUG
            else:
                pe = pde.energy_norm(error1._fefunc)
                logger.debug("global projection error: %s", pe)
            zeta1 = beta[1] * pe
        else:
            if local:
                zeta1 = np.zeros(w[mu].basis.mesh.num_cells())
            else:
                zeta1 = 0

        # mu -1
        mu2 = mu.dec(m)
        if mu2 in Lambda:
            logger.debug("[LPE-B] local projection error for mu = %s with %s", mu, mu2)

            # debug---
#            if True:
#                from dolfin import Function, inner
#                V1 = w[mu]._fefunc.function_space();
#                ufl = V1.ufl_element();
#                V2 = FunctionSpace(V1.mesh(), ufl.family(), ufl.degree() + 1)
#                f1 = Function(V1)
#                f1.interpolate(w[mu2]._fefunc)
#                f12 = Function(V2)
#                f12.interpolate(f1)
#                f2 = Function(V2)
#                f2.interpolate(w[mu2]._fefunc)
#                err2 = Function(V2, f2.vector() - f12.vector())
#                aerr = a0_f * inner(nabla_grad(err2), nabla_grad(err2)) * dx
#                perr = sqrt(assemble(aerr))
#                logger.info("DEBUG B --- global projection error %s - %s: %s", mu2, mu, perr)
            # ---debug
            
            # evaluate H1 semi-norm of projection error
            error2, sum_up = w.get_projection_error_function(mu2, mu, 1 + projection_degree_increase, refine_mesh=refine_mesh)
            logger.debug("global projection error norms: L2 = %s and H1 = %s", norm(error2._fefunc, "L2"), norm(error2._fefunc, "H1"))
#            pe = weighted_H1_norm(a0_f, error2, local)  # TODO: this should be the energy error!
#            pe = sum_up(pe)     # summation for cells according to reference mesh refinement
            if local:
                energynorm = pde.get_energy_norm(mesh=error2._fefunc.function_space().mesh())
                pe = energynorm(error2._fefunc)
                pe = np.array([e ** 2 for e in pe])     # square norms
                pe = sum_up(pe)                         # summation for cells according to reference mesh refinement
                pe = np.sqrt(pe)                        # take square root again for summed norm
                logger.debug("summed local projection errors: %s", sqrt(sum([e ** 2 for e in pe])))
#                # DEBUG---
#                from dolfin import plot
##                plot(w[mu]._fefunc)
##                plot(error2._fefunc, interactive=True)                
#                pe2 = weighted_H1_norm(a0_f, error2, local)  # TODO: this should be the energy error!
#                pe2 = np.array([e ** 2 for e in pe2])     # square norms
#                pe2 = sum_up(pe2)                         # summation for cells according to reference mesh refinement
#                pe2 = np.sqrt(pe2)                        # take square root again for summed norm
#                logger.warn("[B] summed local projection errors: %s = %s \t weights: %s = %s", sqrt(sum([e ** 2 for e in pe])), sqrt(sum([e2 ** 2 for e2 in pe2])), a0_f((0, 0)), pde._a0((0, 0)))
#                # ---DEBUG                
            else:
                pe = pde.energy_norm(error2._fefunc)
                logger.debug("global projection error: %s", pe)
            zeta2 = beta[-1] * pe
        else:
            if local:
                zeta2 = np.zeros(w[mu].basis.mesh.num_cells())
            else:
                zeta2 = 0

        logger.debug("beta[-1] = %s  beta[1] = %s  ainfty = %s", beta[-1], beta[1], ainfty)
        zeta = ainfty * (zeta1 + zeta2)
        return zeta
コード例 #52
0
            'u_tent_plot': Function(Vplot), 'u_last_plot': Function(Vplot)}
state_NR = {'name': 'NR', 'u_prev': Function(V), 'u_tent': Function(V), 'u_last': Function(V),
            'pressure': Function(Q), 'p_tent': Function(Q), 'rot': True, 'null': True,
            'u_tent_plot': Function(Vplot), 'u_last_plot': Function(Vplot)}

# states = [state_B_, state_BR, state_N_, state_NR]
states = [state_B_]

t = timestep
step = 1
while t < time + 1e-6:
    print('t = ', t)
    v_in_expr.t = t
    for state in states:
        solve_cycle(state)
        n = norm(state['u_last'])
        print(n)
        plot_state(state, t)
        interactive()
        if math.isnan(n):
            exit('Failed')
        if n > 5 * v_in * length:
            exit('Norm too big!')
    t += timestep
    step += 1





コード例 #53
0
ファイル: flux_module.py プロジェクト: mhanus/GOAT
 def fixed_source_residual_norm(self, norm_type='l2'):
   y = PETScVector()
   self.A.mult(self.sln_vec, y)
   y.apply("insert")
   return norm(self.Q - y, norm_type)
コード例 #54
0
def solve_maxwell(V, dx,
                  Mu, Sigma,  # dictionaries
                  omega,
                  f_list,  # list of dictionaries
                  convections,  # dictionary
                  bcs=None,
                  tol=1.0e-12,
                  compute_residuals=True,
                  verbose=False
                  ):
    '''Solve the complex-valued time-harmonic Maxwell system in 2D cylindrical
    coordinates.

    :param V: function space for potentials
    :param dx: measure
    :param omega: current frequency
    :type omega: float
    :param f_list: list of right-hand sides
    :param convections: convection terms by subdomains
    :type convections: dictionary
    :param bcs: Dirichlet boundary conditions
    :param tol: solver tolerance
    :type tol: float
    :param verbose: solver verbosity
    :type verbose: boolean
    :rtype: list of functions
    '''
    # For the exact solution of the magnetic scalar potential, see
    # <http://www.physics.udel.edu/~jim/PHYS809_10F/Class_Notes/Class_26.pdf>.
    # Here, the value of \phi along the rotational axis is specified as
    #
    #    phi(z) = 2 pi I / c * (z/|z| - z/sqrt(z^2 + a^2))
    #
    # where 'a' is the radius of the coil. This expression contradicts what is
    # specified by [Chaboudez97]_ who claim that phi=0 is the natural value
    # at the symmetry axis.
    #
    # For more analytic expressions, see
    #
    #     Simple Analytic Expressions for the Magnetic Field of a Circular
    #     Current Loop;
    #     James Simpson, John Lane, Christopher Immer, and Robert Youngquist;
    #     <http://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/20010038494_2001057024.pdf>.
    #

    # Check if boundary conditions on phi are explicitly provided.
    if not bcs:
        # Create Dirichlet boundary conditions.
        # In the cylindrically symmetric formulation, the magnetic vector
        # potential is given by
        #
        #    A = e^{i omega t} phi(r,z) e_{theta}.
        #
        # It is natural to demand phi=0 along the symmetry axis r=0 to avoid
        # discontinuities there.
        # Also, this makes sure that the system is well-defined (see comment
        # below).
        #
        def xzero(x, on_boundary):
            return on_boundary and abs(x[0]) < DOLFIN_EPS
        bcs = DirichletBC(V * V, (0.0, 0.0), xzero)
        #
        # Concerning the boundary conditions for the rest of the system:
        # At the other boundaries, it is not uncommon (?) to set so-called
        # impedance boundary conditions; see, e.g.,
        #
        #    Chaboudez et al.,
        #    Numerical Modeling in Induction Heating for Axisymmetric
        #    Geometries,
        #    IEEE Transactions on Magnetics, vol. 33, no. 1, Jan 1997,
        #    <http://www.esi-group.com/products/casting/publications/Articles_PDF/InductionaxiIEEE97.pdf>.
        #
        # or
        #
        #    <ftp://ftp.math.ethz.ch/pub/sam-reports/reports/reports2010/2010-39.pdf>.
        #
        # TODO review those, references don't seem to be too accurate
        # Those translate into Robin-type boundary conditions (and are in fact
        # sometimes called that, cf.
        # https://en.wikipedia.org/wiki/Robin_boundary_condition).
        # The classical reference is
        #
        #     Impedance boundary conditions for imperfectly conducting
        #     surfaces,
        #     T.B.A. Senior,
        #     <http://link.springer.com/content/pdf/10.1007/BF02920074>.
        #
        #class OuterBoundary(SubDomain):
        #    def inside(self, x, on_boundary):
        #        return on_boundary and abs(x[0]) > DOLFIN_EPS
        #boundaries = FacetFunction('size_t', mesh)
        #boundaries.set_all(0)
        #outer_boundary = OuterBoundary()
        #outer_boundary.mark(boundaries, 1)
        #ds = Measure('ds')[boundaries]
        ##n = FacetNormal(mesh)
        ##a += - 1.0/Mu[i] * dot(grad(r*ur), n) * vr * ds(1) \
        ##     - 1.0/Mu[i] * dot(grad(r*ui), n) * vi * ds(1)
        ##L += - 1.0/Mu[i] * 1.0 * vr * ds(1) \
        ##     - 1.0/Mu[i] * 1.0 * vi * ds(1)
        ## This is -n.grad(r u) = u:
        #a += 1.0/Mu[i] * ur * vr * ds(1) \
        #   + 1.0/Mu[i] * ui * vi * ds(1)

    # Create the system matrix, preconditioner, and the right-hand sides.
    # For preconditioners, there are two approaches. The first one, described
    # in
    #
    #     Algebraic Multigrid for Complex Symmetric Systems;
    #     D. Lahaye, H. De Gersem, S. Vandewalle, and K. Hameyer;
    #     <https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=877730>
    #
    # doesn't work too well here.
    # The matrix P, created in _build_system(), provides a better alternative.
    # For more details, see documentation in _build_system().
    #
    A, P, b_list, M, W = _build_system(V, dx,
                                       Mu, Sigma,  # dictionaries
                                       omega,
                                       f_list,  # list of dicts
                                       convections,  # dict
                                       bcs
                                       )

    #from matplotlib import pyplot as pp
    #rows, cols, values = M.data()
    #from scipy.sparse import csr_matrix
    #M_matrix = csr_matrix((values, cols, rows))
    ##from matplotlib import pyplot as pp
    ###pp.spy(M_matrix, precision=1e-3, marker='.', markersize=5)
    ##pp.spy(M_matrix)
    ##pp.show()
    ## colormap
    #cmap = pp.cm.gray_r
    #M_dense = M_matrix.todense()
    #from matplotlib.colors import LogNorm
    #im = pp.imshow(abs(M_dense), cmap=cmap, interpolation='nearest', norm=LogNorm())
    ##im = pp.imshow(abs(M_dense), cmap=cmap, interpolation='nearest')
    ##im = pp.imshow(abs(A_r), cmap=cmap, interpolation='nearest')
    ##im = pp.imshow(abs(A_i), cmap=cmap, interpolation='nearest')
    #pp.colorbar()
    #pp.show()
    #exit()
    #print A
    #rows, cols, values = A.data()
    #from scipy.sparse import csr_matrix
    #A_matrix = csr_matrix((values, cols, rows))

    ###pp.spy(A_matrix, precision=1e-3, marker='.', markersize=5)
    ##pp.spy(A_matrix)
    ##pp.show()

    ## colormap
    #cmap = pp.cm.gray_r
    #A_dense = A_matrix.todense()
    ##A_r = A_dense[0::2][0::2]
    ##A_i = A_dense[1::2][0::2]
    #cmap.set_bad('r')
    ##im = pp.imshow(abs(A_dense), cmap=cmap, interpolation='nearest', norm=LogNorm())
    #im = pp.imshow(abs(A_dense), cmap=cmap, interpolation='nearest')
    ##im = pp.imshow(abs(A_r), cmap=cmap, interpolation='nearest')
    ##im = pp.imshow(abs(A_i), cmap=cmap, interpolation='nearest')
    #pp.colorbar()
    #pp.show()

    # prepare solver
    solver = KrylovSolver('gmres', 'amg')
    solver.set_operators(A, P)

    # The PDE for A has huge coefficients (order 10^8) all over. Hence, if
    # relative residual is set to 10^-6, the actual residual will still be of
    # the order 10^2. While this isn't too bad (after all the equations are
    # upscaled by a large factor), one can choose a very small relative
    # tolerance here to get a visually pleasing residual norm.
    solver.parameters['relative_tolerance'] = 1.0e-12
    solver.parameters['absolute_tolerance'] = 0.0
    solver.parameters['maximum_iterations'] = 100
    solver.parameters['report'] = verbose
    solver.parameters['monitor_convergence'] = verbose

    phi_list = []
    for k, b in enumerate(b_list):
        with Message('Computing coil ring %d/%d...' % (k + 1, len(b_list))):
            # Define goal functional for adaptivity.
            # Adaptivity not working for subdomains, cf.
            # https://bugs.launchpad.net/dolfin/+bug/872105.
            #(phi_r, phi_i) = split(phi)
            #M = (phi_r*phi_r + phi_i*phi_i) * dx(2)
            phi_list.append(Function(W))
            phi_list[-1].rename('phi%d' % k, 'phi%d' % k)
            solver.solve(phi_list[-1].vector(), b)

        ## Adaptive mesh refinement.
        #_adaptive_mesh_refinement(dx,
        #                          phi_list[-1],
        #                          Mu, Sigma, omega,
        #                          convections,
        #                          f_list[k]
        #                          )
        #exit()

        if compute_residuals:
            # Sanity check: Compute residuals.
            # This is quite the good test that we haven't messed up
            # real/imaginary in the above formulation.
            r_r, r_i = _build_residuals(V, dx, phi_list[-1],
                                        omega, Mu, Sigma,
                                        convections, voltages
                                        )

            def xzero(x, on_boundary):
                return on_boundary and abs(x[0]) < DOLFIN_EPS

            subdomain_indices = Mu.keys()

            # Solve an FEM problem to get the corresponding residual function
            # out.
            # This is exactly what we need here! :)
            u = TrialFunction(V)
            v = TestFunction(V)
            a = zero() * dx(0)
            for i in subdomain_indices:
                a += u * v * dx(i)

            # TODO don't hard code the boundary conditions like this
            R_r = Function(V)
            solve(a == r_r, R_r,
                  bcs=DirichletBC(V, 0.0, xzero)
                  )

            # TODO don't hard code the boundary conditions like this
            R_i = Function(V)
            solve(a == r_i, R_i,
                  bcs=DirichletBC(V, 0.0, xzero)
                  )

            nrm_r = norm(R_r)
            info('||r_r|| = %e' % nrm_r)
            nrm_i = norm(R_i)
            info('||r_i|| = %e' % nrm_i)
            res_norm = sqrt(nrm_r * nrm_r + nrm_i * nrm_i)
            info('||r|| = %e' % res_norm)

            plot(R_r, title='R_r')
            plot(R_i, title='R_i')
            interactive()
            #exit()
    return phi_list
コード例 #55
0
    def ab2tr_step0(u0,
                    P,
                    f,  # right-hand side
                    rho,
                    mu,
                    dudt_bcs=[],
                    p_bcs=[],
                    eps=1.0e-4,  # relative error tolerance
                    verbose=True
                    ):
        # Make sure that the initial velocity is divergence-free.
        alpha = norm(u0, 'Hdiv0')
        if abs(alpha) > DOLFIN_EPS:
            warn('Initial velocity not divergence-free (||u||_div = %e).'
                 % alpha
                 )
        # Get the initial u0' and p0 by solving the linear equation system
        #
        #     [M   C] [u0']   [f0 - (K+N(u0)u0)]
        #     [C^T 0] [p0 ] = [ g0'            ],
        #
        # i.e.,
        #
        #     rho u0' + nabla(p0) = f0 + mu\Delta(u0) - rho u0.nabla(u0),
        #     div(u0')            = 0.
        #
        W = u0.function_space()
        WP = W*P

        # Translate the boundary conditions into product space. See
        # <http://fenicsproject.org/qa/703/boundary-conditions-in-product-space>.
        dudt_bcs_new = []
        for dudt_bc in dudt_bcs:
            dudt_bcs_new.append(DirichletBC(WP.sub(0),
                                            dudt_bc.value(),
                                            dudt_bc.user_sub_domain()))
        p_bcs_new = []
        for p_bc in p_bcs:
            p_bcs_new.append(DirichletBC(WP.sub(1),
                                         p_bc.value(),
                                         p_bc.user_sub_domain()))

        new_bcs = dudt_bcs_new + p_bcs_new

        (u, p) = TrialFunctions(WP)
        (v, q) = TestFunctions(WP)

        #a = rho * dot(u, v) * dx + dot(grad(p), v) * dx \
        a = rho * inner(u, v) * dx - p * div(v) * dx \
            - div(u) * q * dx
        L = _rhs_weak(u0, v, f, rho, mu)

        A, b = assemble_system(a, L, new_bcs)

        # Similar preconditioner as for the Stokes problem.
        # TODO implement something better!
        prec = rho * inner(u, v) * dx \
            - p*q*dx
        M, _ = assemble_system(prec, L, new_bcs)

        solver = KrylovSolver('gmres', 'amg')

        solver.parameters['monitor_convergence'] = verbose
        solver.parameters['report'] = verbose
        solver.parameters['absolute_tolerance'] = 0.0
        solver.parameters['relative_tolerance'] = 1.0e-6
        solver.parameters['maximum_iterations'] = 10000

        # Associate operator (A) and preconditioner matrix (M)
        solver.set_operators(A, M)
        #solver.set_operator(A)

        # Solve
        up = Function(WP)
        solver.solve(up.vector(), b)

        # Get sub-functions
        dudt0, p0 = up.split()

        # Choosing the first step size for the trapezoidal rule can be tricky.
        # Chapters 2.7.4a, 2.7.4e of the book
        #
        #     Incompressible flow and the finite element method,
        #     volume 1: advection-diffusion;
        #     P.M. Gresho, R.L. Sani,
        #
        # give some hints.
        #
        #     eps ... relative error tolerance
        #     tau ... estimate of the initial 'time constant'
        tau = None
        if tau:
            dt0 = tau * eps**(1.0/3.0)
        else:
            # Choose something 'reasonably small'.
            dt0 = 1.0e-3
        # Alternative:
        # Use a dissipative scheme like backward Euler or BDF2 for the first
        # couple of steps. This makes sure that noisy initial data is damped
        # out.
        return dudt0, p0, dt0
コード例 #56
0
    def _pressure_poisson(self,
                          p1, p0,
                          mu, ui,
                          divu,
                          p_bcs=None,
                          p_n=None,
                          rotational_form=False,
                          tol=1.0e-10,
                          verbose=True
                          ):
        '''Solve the pressure Poisson equation

            - \Delta phi = -div(u),
            boundary conditions,

        for

            \nabla p = u.
        '''
        P = p1.function_space()
        p = TrialFunction(P)
        q = TestFunction(P)

        a2 = dot(grad(p), grad(q)) * dx
        L2 = -divu * q * dx
        if p0:
            L2 += dot(grad(p0), grad(q)) * dx
        if p_n:
            n = FacetNormal(P.mesh())
            L2 += dot(n, p_n) * q * ds

        if rotational_form:
            L2 -= mu * dot(grad(div(ui)), grad(q)) * dx

        if p_bcs:
            solve(a2 == L2, p1,
                  bcs=p_bcs,
                  solver_parameters={
                      'linear_solver': 'iterative',
                      'symmetric': True,
                      'preconditioner': 'hypre_amg',
                      'krylov_solver': {'relative_tolerance': tol,
                                        'absolute_tolerance': 0.0,
                                        'maximum_iterations': 100,
                                        'monitor_convergence': verbose}
                  })
        else:
            # If we're dealing with a pure Neumann problem here (which is the
            # default case), this doesn't hurt CG if the system is consistent,
            # cf.
            #
            #    Iterative Krylov methods for large linear systems,
            #    Henk A. van der Vorst.
            #
            # And indeed, it is consistent: Note that
            #
            #    <1, rhs> = \sum_i 1 * \int div(u) v_i
            #             = 1 * \int div(u) \sum_i v_i
            #             = \int div(u).
            #
            # With the divergence theorem, we have
            #
            #    \int div(u) = \int_\Gamma n.u.
            #
            # The latter term is 0 iff inflow and outflow are exactly the same
            # at any given point in time. This corresponds with the
            # incompressibility of the liquid.
            #
            # In turn, this hints towards penetrable boundaries to require
            # Dirichlet conditions on the pressure.
            #
            A = assemble(a2)
            b = assemble(L2)
            #
            # In principle, the ILU preconditioner isn't advised here since it
            # might destroy the semidefiniteness needed for CG.
            #
            # The system is consistent, but the matrix has an eigenvalue 0.
            # This does not harm the convergence of CG, but when
            # preconditioning one has to take care that the preconditioner
            # preserves the kernel.  ILU might destroy this (and the
            # semidefiniteness). With AMG, the coarse grid solves cannot be LU
            # then, so try Jacobi here.
            # <http://lists.mcs.anl.gov/pipermail/petsc-users/2012-February/012139.html>
            #
            prec = PETScPreconditioner('hypre_amg')
            PETScOptions.set('pc_hypre_boomeramg_relax_type_coarse', 'jacobi')
            solver = PETScKrylovSolver('cg', prec)
            solver.parameters['absolute_tolerance'] = 0.0
            solver.parameters['relative_tolerance'] = tol
            solver.parameters['maximum_iterations'] = 100
            solver.parameters['monitor_convergence'] = verbose
            # Create solver and solve system
            A_petsc = as_backend_type(A)
            b_petsc = as_backend_type(b)
            p1_petsc = as_backend_type(p1.vector())
            solver.set_operator(A_petsc)
            try:
                solver.solve(p1_petsc, b_petsc)
            except RuntimeError as error:
                info('')
                # Check if the system is indeed consistent.
                #
                # If the right hand side is flawed (e.g., by round-off errors),
                # then it may have a component b1 in the direction of the null
                # space, orthogonal the image of the operator:
                #
                #     b = b0 + b1.
                #
                # When starting with initial guess x0=0, the minimal achievable
                # relative tolerance is then
                #
                #    min_rel_tol = ||b1|| / ||b||.
                #
                # If ||b|| is very small, which is the case when ui is almost
                # divergence-free, then min_rel_to may be larger than the
                # prescribed relative tolerance tol.
                #
                # Use this as a consistency check, i.e., bail out if
                #
                #     tol < min_rel_tol = ||b1|| / ||b||.
                #
                # For computing ||b1||, we use the fact that the null space is
                # one-dimensional, i.e.,  b1 = alpha e,  and
                #
                #     e.b = e.(b0 + b1) = e.b1 = alpha ||e||^2,
                #
                # so  alpha = e.b/||e||^2  and
                #
                #     ||b1|| = |alpha| ||e|| = e.b / ||e||
                #
                e = Function(P)
                e.interpolate(Constant(1.0))
                evec = e.vector()
                evec /= norm(evec)
                alpha = b.inner(evec)
                normB = norm(b)
                info('Linear system convergence failure.')
                info(error.message)
                message = ('Linear system not consistent! '
                           '<b,e> = %g, ||b|| = %g, <b,e>/||b|| = %e, tol = %e.') \
                           % (alpha, normB, alpha/normB, tol)
                info(message)
                if tol < abs(alpha) / normB:
                    info('\int div(u)  =  %e' % assemble(divu * dx))
                    #n = FacetNormal(Q.mesh())
                    #info('\int_Gamma n.u = %e' % assemble(dot(n, u)*ds))
                    #info('\int_Gamma u[0] = %e' % assemble(u[0]*ds))
                    #info('\int_Gamma u[1] = %e' % assemble(u[1]*ds))
                    ## Now plot the faulty u on a finer mesh (to resolve the
                    ## quadratic trial functions).
                    #fine_mesh = Q.mesh()
                    #for k in range(1):
                    #    fine_mesh = refine(fine_mesh)
                    #V1 = FunctionSpace(fine_mesh, 'CG', 1)
                    #W1 = V1*V1
                    #uplot = project(u, W1)
                    ##uplot = Function(W1)
                    ##uplot.interpolate(u)
                    #plot(uplot, title='u_tentative')
                    #plot(uplot[0], title='u_tentative[0]')
                    #plot(uplot[1], title='u_tentative[1]')
                    plot(divu, title='div(u_tentative)')
                    interactive()
                    exit()
                    raise RuntimeError(message)
                else:
                    exit()
                    raise RuntimeError('Linear system failed to converge.')
            except:
                exit()
        return
コード例 #57
0
ファイル: navier_stokes.py プロジェクト: nschloe/maelstrom
def compute_pressure(
    P,
    p0,
    mu,
    ui,
    u,
    my_dx,
    p_bcs=None,
    rotational_form=False,
    tol=1.0e-10,
    verbose=True,
):
    """Solve the pressure Poisson equation

    .. math::

        \\begin{align}
          -\\frac{1}{r} \\div(r \\nabla (p_1-p_0)) =
              -\\frac{1}{r} \\div(r u),\\\\
          \\text{(with boundary conditions)},
        \\end{align}

    for :math:`\\nabla p = u`.

    The pressure correction is based on the update formula

    .. math::
        \\frac{\\rho}{dt} (u_{n+1}-u^*)
            + \\begin{pmatrix}
                \\text{d}\\phi/\\text{d}r\\\\
                \\text{d}\\phi/\\text{d}z\\\\
                \\frac{1}{r} \\text{d}\\phi/\\text{d}\\theta
              \\end{pmatrix}
                = 0

    with :math:`\\phi = p_{n+1} - p^*` and

    .. math::

         \\frac{1}{r} \\frac{\\text{d}}{\\text{d}r} (r u_r^{(n+1)})
       + \\frac{\\text{d}}{\\text{d}z}  (u_z^{(n+1)})
       + \\frac{1}{r} \\frac{\\text{d}}{\\text{d}\\theta} (u_{\\theta}^{(n+1)})
           = 0

    With the assumption that u does not change in the direction
    :math:`\\theta`, one derives

    .. math::

       - \\frac{1}{r}   \\div(r \\nabla \\phi) =
           \\frac{1}{r} \\frac{\\rho}{dt}   \\div(r (u_{n+1} - u^*))\\\\
       - \\frac{1}{r} \\langle n, r \\nabla \\phi\\rangle =
           \\frac{1}{r} \\frac{\\rho}{dt} \\langle n, r (u_{n+1} - u^*)\\rangle

    In its weak form, this is

    .. math::

      \\int r \\langle\\nabla\\phi, \\nabla q\\rangle \\,2 \\pi =
           - \\frac{\\rho}{dt} \\int \\div(r u^*) q \\, 2 \\pi
           - \\frac{\\rho}{dt} \\int_{\\Gamma}
                 \\langle n,  r (u_{n+1}-u^*)\\rangle q \\, 2\\pi.

    (The terms :math:`1/r` cancel with the volume elements :math:`2\\pi r`.)
    If the Dirichlet boundary conditions are applied to both :math:`u^*` and
    :math:`u_n` (the latter in the velocity correction step), the boundary
    integral vanishes.

    If no Dirichlet conditions are given (which is the default case), the
    system has no unique solution; one eigenvalue is 0. This however, does not
    hurt CG convergence if the system is consistent, cf. :cite:`vdV03`. And
    indeed it is consistent if and only if

    .. math::
        \\int_\\Gamma r \\langle n, u\\rangle = 0.

    This condition makes clear that for incompressible Navier-Stokes, one
    either needs to make sure that inflow and outflow always add up to 0, or
    one has to specify pressure boundary conditions.

    Note that, when using a multigrid preconditioner as is done here, the
    coarse solver must be chosen such that it preserves the nullspace of the
    problem.
    """
    W = ui.function_space()
    r = SpatialCoordinate(W.mesh())[0]

    p = TrialFunction(P)
    q = TestFunction(P)
    a2 = dot(r * grad(p), grad(q)) * 2 * pi * my_dx
    # The boundary conditions
    #     n.(p1-p0) = 0
    # are implicitly included.
    #
    # L2 = -div(r*u) * q * 2*pi*my_dx
    div_u = 1 / r * (r * u[0]).dx(0) + u[1].dx(1)
    L2 = -div_u * q * 2 * pi * r * my_dx
    if p0:
        L2 += r * dot(grad(p0), grad(q)) * 2 * pi * my_dx

    # In the Cartesian variant of the rotational form, one makes use of the
    # fact that
    #
    #     curl(curl(u)) = grad(div(u)) - div(grad(u)).
    #
    # The same equation holds true in cylindrical form. Hence, to get the
    # rotational form of the splitting scheme, we need to
    #
    # rotational form
    if rotational_form:
        # If there is no dependence of the angular coordinate, what is
        # div(grad(div(u))) in Cartesian coordinates becomes
        #
        #     1/r div(r * grad(1/r div(r*u)))
        #
        # in cylindrical coordinates (div and grad are in cylindrical
        # coordinates). Unfortunately, we cannot write it down that
        # compactly since u_phi is in the game.
        # When using P2 elements, this value will be 0 anyways.
        div_ui = 1 / r * (r * ui[0]).dx(0) + ui[1].dx(1)
        grad_div_ui = as_vector((div_ui.dx(0), div_ui.dx(1)))
        L2 -= r * mu * dot(grad_div_ui, grad(q)) * 2 * pi * my_dx
        # div_grad_div_ui = 1/r * (r * grad_div_ui[0]).dx(0) \
        #     + (grad_div_ui[1]).dx(1)
        # L2 += mu * div_grad_div_ui * q * 2*pi*r*dx
        # n = FacetNormal(Q.mesh())
        # L2 -= mu * (n[0] * grad_div_ui[0] + n[1] * grad_div_ui[1]) \
        #     * q * 2*pi*r*ds

    p1 = Function(P)
    if p_bcs:
        solve(
            a2 == L2,
            p1,
            bcs=p_bcs,
            solver_parameters={
                "linear_solver": "iterative",
                "symmetric": True,
                "preconditioner": "hypre_amg",
                "krylov_solver": {
                    "relative_tolerance": tol,
                    "absolute_tolerance": 0.0,
                    "maximum_iterations": 100,
                    "monitor_convergence": verbose,
                },
            },
        )
    else:
        # If we're dealing with a pure Neumann problem here (which is the
        # default case), this doesn't hurt CG if the system is consistent,
        # cf. :cite:`vdV03`. And indeed it is consistent if and only if
        #
        #   \int_\Gamma r n.u = 0.
        #
        # This makes clear that for incompressible Navier-Stokes, one
        # either needs to make sure that inflow and outflow always add up
        # to 0, or one has to specify pressure boundary conditions.
        #
        # If the right-hand side is very small, round-off errors may impair
        # the consistency of the system. Make sure the system we are
        # solving remains consistent.
        A = assemble(a2)
        b = assemble(L2)
        # Assert that the system is indeed consistent.
        e = Function(P)
        e.interpolate(Constant(1.0))
        evec = e.vector()
        evec /= norm(evec)
        alpha = b.inner(evec)
        normB = norm(b)
        # Assume that in every component of the vector, a round-off error
        # of the magnitude DOLFIN_EPS is present. This leads to the
        # criterion
        #    |<b,e>| / (||b||*||e||) < DOLFIN_EPS
        # as a check whether to consider the system consistent up to
        # round-off error.
        #
        # TODO think about condition here
        # if abs(alpha) > normB * DOLFIN_EPS:
        if abs(alpha) > normB * 1.0e-12:
            # divu = 1 / r * (r * u[0]).dx(0) + u[1].dx(1)
            adivu = assemble(((r * u[0]).dx(0) + u[1].dx(1)) * 2 * pi * my_dx)
            info("\\int 1/r * div(r*u) * 2*pi*r  =  {:e}".format(adivu))
            n = FacetNormal(P.mesh())
            boundary_integral = assemble((n[0] * u[0] + n[1] * u[1]) * 2 * pi * r * ds)
            info("\\int_Gamma n.u * 2*pi*r = {:e}".format(boundary_integral))
            message = (
                "System not consistent! "
                "<b,e> = {:g}, ||b|| = {:g}, <b,e>/||b|| = {:e}.".format(
                    alpha, normB, alpha / normB
                )
            )
            info(message)
            # # Plot the stuff, and project it to a finer mesh with linear
            # # elements for the purpose.
            # plot(divu, title='div(u_tentative)')
            # # Vp = FunctionSpace(Q.mesh(), 'CG', 2)
            # # Wp = MixedFunctionSpace([Vp, Vp])
            # # up = project(u, Wp)
            # fine_mesh = Q.mesh()
            # for k in range(1):
            #     fine_mesh = refine(fine_mesh)
            # V = FunctionSpace(fine_mesh, 'CG', 1)
            # W = V * V
            # # uplot = Function(W)
            # # uplot.interpolate(u)
            # uplot = project(u, W)
            # plot(uplot[0], title='u_tentative[0]')
            # plot(uplot[1], title='u_tentative[1]')
            # # plot(u, title='u_tentative')
            # interactive()
            # exit()
            raise RuntimeError(message)
        # Project out the roundoff error.
        b -= alpha * evec

        #
        # In principle, the ILU preconditioner isn't advised here since it
        # might destroy the semidefiniteness needed for CG.
        #
        # The system is consistent, but the matrix has an eigenvalue 0.
        # This does not harm the convergence of CG, but when
        # preconditioning one has to make sure that the preconditioner
        # preserves the kernel. ILU might destroy this (and the
        # semidefiniteness). With AMG, the coarse grid solves cannot be LU
        # then, so try Jacobi here.
        # <http://lists.mcs.anl.gov/pipermail/petsc-users/2012-February/012139.html>
        #
        prec = PETScPreconditioner("hypre_amg")
        from dolfin import PETScOptions

        PETScOptions.set("pc_hypre_boomeramg_relax_type_coarse", "jacobi")
        solver = PETScKrylovSolver("cg", prec)
        solver.parameters["absolute_tolerance"] = 0.0
        solver.parameters["relative_tolerance"] = tol
        solver.parameters["maximum_iterations"] = 100
        solver.parameters["monitor_convergence"] = verbose
        # Create solver and solve system
        A_petsc = as_backend_type(A)
        b_petsc = as_backend_type(b)
        p1_petsc = as_backend_type(p1.vector())
        solver.set_operator(A_petsc)
        solver.solve(p1_petsc, b_petsc)
    return p1
コード例 #58
0
ファイル: test_maxwell.py プロジェクト: nschloe/maelstrom
def test(show=False):
    problem = problems.Crucible()
    # The voltage is defined as
    #
    #     v(t) = Im(exp(i omega t) v)
    #          = Im(exp(i (omega t + arg(v)))) |v|
    #          = sin(omega t + arg(v)) |v|.
    #
    # Hence, for a lagging voltage, arg(v) needs to be negative.
    voltages = [
        38.0 * numpy.exp(-1j * 2 * pi * 2 * 70.0 / 360.0),
        38.0 * numpy.exp(-1j * 2 * pi * 1 * 70.0 / 360.0),
        38.0 * numpy.exp(-1j * 2 * pi * 0 * 70.0 / 360.0),
        25.0 * numpy.exp(-1j * 2 * pi * 0 * 70.0 / 360.0),
        25.0 * numpy.exp(-1j * 2 * pi * 1 * 70.0 / 360.0),
    ]

    lorentz, joule, Phi = get_lorentz_joule(problem, voltages, show=show)

    # Some assertions
    ref = 1.4627674791126285e-05
    assert abs(norm(Phi[0], "L2") - ref) < 1.0e-3 * ref
    ref = 3.161363929287592e-05
    assert abs(norm(Phi[1], "L2") - ref) < 1.0e-3 * ref
    #
    ref = 12.115309575057681
    assert abs(norm(lorentz, "L2") - ref) < 1.0e-3 * ref
    #
    ref = 1406.336109054347
    V = FunctionSpace(problem.submesh_workpiece, "CG", 1)
    jp = project(joule, V)
    jp.rename("s", "Joule heat source")
    assert abs(norm(jp, "L2") - ref) < 1.0e-3 * ref

    # check_currents = False
    # if check_currents:
    #     r = SpatialCoordinate(problem.mesh)[0]
    #     begin('Currents computed after the fact:')
    #     k = 0
    #     with XDMFFile('currents.xdmf') as xdmf_file:
    #         for coil in coils:
    #             for ii in coil['rings']:
    #                 J_r = sigma[ii] * (
    #                     voltages[k].real/(2*pi*r) + problem.omega * Phi[1]
    #                     )
    #                 J_i = sigma[ii] * (
    #                     voltages[k].imag/(2*pi*r) - problem.omega * Phi[0]
    #                     )
    #                 alpha = assemble(J_r * dx(ii))
    #                 beta = assemble(J_i * dx(ii))
    #                 info('J = {:e} + i {:e}'.format(alpha, beta))
    #                 info(
    #                     '|J|/sqrt(2) = {:e}'.format(
    #                         numpy.sqrt(0.5 * (alpha**2 + beta**2))
    #                     ))
    #                 submesh = SubMesh(problem.mesh, problem.subdomains, ii)
    #                 V1 = FunctionSpace(submesh, 'CG', 1)
    #                 # Those projections may take *very* long.
    #                 # TODO find out why
    #                 j_v1 = [
    #                     project(J_r, V1),
    #                     project(J_i, V1)
    #                     ]
    #                 # show=Trueplot(j_v1[0], title='j_r')
    #                 # plot(j_v1[1], title='j_i')
    #                 current = project(as_vector(j_v1), V1*V1)
    #                 current.rename('j{}'.format(ii), 'current {}'.format(ii))
    #                 xdmf_file.write(current)
    #                 k += 1
    #     end()

    filename = "./maxwell.xdmf"
    with XDMFFile(filename) as xdmf_file:
        xdmf_file.parameters["flush_output"] = True
        xdmf_file.parameters["rewrite_function_mesh"] = False

        # Store phi
        info("Writing out Phi to {}...".format(filename))
        V = FunctionSpace(problem.mesh, "CG", 1)
        phi = Function(V, name="phi")
        Phi0 = project(Phi[0], V)
        Phi1 = project(Phi[1], V)
        omega = problem.omega
        for t in numpy.linspace(0.0, 2 * pi / omega, num=100, endpoint=False):
            # Im(Phi * exp(i*omega*t))
            phi.vector().zero()
            phi.vector().axpy(sin(problem.omega * t), Phi0.vector())
            phi.vector().axpy(cos(problem.omega * t), Phi1.vector())
            xdmf_file.write(phi, t)

        # Show the resulting magnetic field
        #
        #   B_r = -dphi/dz,
        #   B_z = 1/r d(rphi)/dr.
        #
        r = SpatialCoordinate(problem.mesh)[0]
        g = 1.0 / r * grad(r * Phi[0])
        V_element = FiniteElement("CG", V.mesh().ufl_cell(), 1)
        VV = FunctionSpace(V.mesh(), V_element * V_element)

        B_r = project(as_vector((-g[1], g[0])), VV)
        g = 1 / r * grad(r * Phi[1])
        B_i = project(as_vector((-g[1], g[0])), VV)
        info("Writing out B to {}...".format(filename))
        B = Function(VV)
        B.rename("B", "magnetic field")
        if abs(problem.omega) < DOLFIN_EPS:
            B.assign(B_r)
            xdmf_file.write(B)
            # plot(B_r, title='Re(B)')
            # plot(B_i, title='Im(B)')
        else:
            # Write those out to a file.
            lspace = numpy.linspace(
                0.0, 2 * pi / problem.omega, num=100, endpoint=False
            )
            for t in lspace:
                # Im(B * exp(i*omega*t))
                B.vector().zero()
                B.vector().axpy(sin(problem.omega * t), B_r.vector())
                B.vector().axpy(cos(problem.omega * t), B_i.vector())
                xdmf_file.write(B, t)

    filename = "./lorentz-joule.xdmf"
    info("Writing out Lorentz force and Joule heat source to {}...".format(filename))
    with XDMFFile(filename) as xdmf_file:
        xdmf_file.write(lorentz, 0.0)
        # xdmf_file.write(jp, 0.0)

    return
コード例 #59
0
def test_estimator_refinement():
    # define source term
    f = Constant("1.0")
    #    f = Expression("10.*exp(-(pow(x[0] - 0.6, 2) + pow(x[1] - 0.4, 2)) / 0.02)", degree=3)

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

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

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

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

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

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

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

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

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

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

        # setup marking sets
        mesh_markers = defaultdict(set)

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

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

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

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

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

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

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

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

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