Example #1
0
def test_formulation_2_traps_1_material():
    '''
    Test function formulation() with 2 intrinsic traps
    and 1 material
    '''    
    # Set parameters
    dt = 1
    traps = [{
        "energy": 1,
        "density": 2,
        "materials": [1]
        },
        {
        "energy": 1,
        "density": 2,
        "materials": [1]
        }]
    materials = [{
            "alpha": 1,
            "beta": 2,
            "density": 3,
            "borders": [0, 1],
            "E_diff": 4,
            "D_0": 5,
            "id": 1
            }]
    extrinsic_traps = []

    # Prepare
    mesh = fenics.UnitIntervalMesh(10)
    V = fenics.VectorFunctionSpace(mesh, 'P', 1, len(traps)+1)
    u = fenics.Function(V)
    u_n = fenics.Function(V)
    v = fenics.TestFunction(V)

    solutions = list(fenics.split(u))
    previous_solutions = list(fenics.split(u_n))
    testfunctions = list(fenics.split(v))

    mf = fenics.MeshFunction('size_t', mesh, 1, 1)
    dx = fenics.dx(subdomain_data=mf)
    temp = fenics.Expression("300", degree=0)
    flux_ = fenics.Expression("1", degree=0)

    F, expressions = FESTIM.formulation(
        traps, extrinsic_traps, solutions, testfunctions,
        previous_solutions, dt, dx, materials, temp, flux_)
    # Transient sol
    expected_form = ((solutions[0] - previous_solutions[0]) / dt) * \
        testfunctions[0]*dx
    # Diffusion sol
    expected_form += 5 * fenics.exp(-4/8.6e-5/temp) * \
        fenics.dot(
            fenics.grad(solutions[0]), fenics.grad(testfunctions[0]))*dx(1)
    # Source sol
    expected_form += -flux_*testfunctions[0]*dx
    # Transient trap 1
    expected_form += ((solutions[1] - previous_solutions[1]) / dt) * \
        testfunctions[1]*dx
    # Trapping trap 1
    expected_form += - 5 * fenics.exp(-4/8.6e-5/temp)/1/1/2 * \
        solutions[0] * (2 - solutions[1]) * \
        testfunctions[1]*dx(1)
    # Detrapping trap 1
    expected_form += 1e13*fenics.exp(-1/8.6e-5/temp)*solutions[1] * \
        testfunctions[1]*dx(1)
    # Source detrapping sol
    expected_form += ((solutions[1] - previous_solutions[1]) / dt) * \
        testfunctions[0]*dx

    # Transient trap 2
    expected_form += ((solutions[2] - previous_solutions[2]) / dt) * \
        testfunctions[2]*dx
    # Trapping trap 2
    expected_form += - 5 * fenics.exp(-4/8.6e-5/temp)/1/1/2 * \
        solutions[0] * (2 - solutions[2]) * \
        testfunctions[2]*dx(1)
    # Detrapping trap 2
    expected_form += 1e13*fenics.exp(-1/8.6e-5/temp)*solutions[2] * \
        testfunctions[2]*dx(1)
    # Source detrapping 2 sol
    expected_form += ((solutions[2] - previous_solutions[2]) / dt) * \
        testfunctions[0]*dx

    assert expected_form.equals(F) is True
Example #2
0
    def create_step_functionals(self):
        u, v = self._sp.u, self._sp.v
        u0, v0 = self._sp.u0, self._sp.v0
        a0 = self._sp.a0
        bf = self._sp.bf
        ut = self._sp.ut
        F, F0 = self._sp.F, self._sp.F0
        density = self._sp.density

        constitutive_model = self._sp.constitutive_model

        self.d_LHS = fe.inner(u, ut) * density * fe.dx \
                     - pow(self._dt, 2) * self._beta * fe.inner(F * constitutive_model.stress(F), fe.grad(ut)) * fe.dx

        self.d_RHS = density * (fe.inner(u0, ut) * fe.dx
                                + self._dt * fe.inner(v0, ut) * fe.dx
                                + pow(self._dt, 2) * (0.5 - self._beta) * fe.inner(a0, ut) * fe.dx) \
                     - pow(self._dt, 2) * self._beta * (fe.inner(bf, ut) * fe.dx)
Example #3
0
# Define boundary condition
u_D = fs.Expression(u_code, degree=2)


def boundary(x, on_boundary):
    return on_boundary


bc = fs.DirichletBC(V, u_D, boundary)

# Define variational problem
u = fs.Function(V)
v = fs.TestFunction(V)
f = fs.Expression(f_code, degree=2)
F = q(u) * fs.dot(fs.grad(u), fs.grad(v)) * fs.dx - f * v * fs.dx
a, L = fs.lhs(F), fs.rhs(F)

# Create VTK file for saving solution
vtkfile = fs.File('solution.pvd')

#Compute Solution
fs.solve(F == 0, u, bc)

#plot solution
fs.plot(u)

# Compute maximum error at vertices. This computation illustrates
# an alternative to using compute_vertex_values as in poisson.py.
u_e = fs.interpolate(u_D, V)
error_max = np.abs(u_e.vector() - u.vector()).max()
Example #4
0
VW = fn.TestFunctions(
    V)  # test function potential concentration lagrange multi
v, w, mu = VW[0], VW[1:M + 1], VW[M + 1:]

#lets try rot
r = fn.Expression('x[0]', degree=0)

# changing concentrations charges
Rho = 0
for i in range(M):
    if i % 2:
        Rho += -c[i]
    else:
        Rho += c[i]

PoissonLeft = (fn.dot(fn.grad(u),
                      fn.grad(v))) * fn.dx  # weak solution Poisson left
PoissonRight = -(Rho) * v * fn.dx  # weak solution Poisson right
NernstPlanck = 0
for i in range(M):
    if i % 2:
        NernstPlanck += fn.dot(
            (-fn.grad(c[i]) + c[i] * fn.grad(u)), fn.grad(
                w[i])) * fn.dx  # weak solution Nernst-Planck
    else:
        NernstPlanck += fn.dot(
            (-fn.grad(c[i]) - c[i] * fn.grad(u)), fn.grad(
                w[i])) * fn.dx  # weak solution Nernst-Planck

constraint = 0
for i in range(M):
def eps(u):
    return fn.sym(fn.grad(u))
Example #6
0
def explicit(d_, w_, k):
    E = grad(d_["n-1"]) + grad(d_["n-1"]).T \
        + grad(d_["n-1"]).T*grad(d_["n-1"])

    return 0.5 * E
Example #7
0
def cn_before_ab_higher_order(d_, w_, k):
    E = 0.5*(grad(d_["n"]).T + grad(d_["n-1"]).T + grad(d_["n"]) + grad(d_["n-1"]))  \
        + 0.5*((grad(d_["n-1"] + k*(23./12*w_["n-1"] - 4./3*w_["n-2"] + 5/12.*w_["n-3"])).T \
                * grad(d_["n"])) + (grad(d_["n-1"]).T*grad(d_["n-1"])))

    return 0.5 * E
Example #8
0
def k(u, v):
    return inner(sigma(u), sym(grad(v))) * dx
Example #9
0
    "(x[0] >= -0.2) && (x[0] <= 0.2) && near(x[1], 0.75) && on_boundary")
GammaU = fn.CompiledSubDomain(
    "(near(x[0], -0.5) || near(x[0], 0.5) ) && on_boundary")
GammaU.mark(bdry, 31)
FooT.mark(bdry, 32)
ds = fn.Measure("ds", subdomain_data=bdry)

bcU = fn.DirichletBC(Hh.sub(0), u_g, bdry, 31)
bcP = fn.DirichletBC(Hh.sub(2), p_g, bdry, 32)
bcs = [bcU, bcP]

# weak form
PLeft =  2*mu*fn.inner(strain(u),strain(v)) * fn.dx \
         - fn.div(v) * phi * fn.dx \
         + (c0/alpha + 1.0/lmbda)* p * q * fn.dx \
         + kappa/(alpha*nu) * fn.dot(fn.grad(p),fn.grad(q)) * fn.dx \
         - 1.0/lmbda * phi * q * fn.dx \
         - fn.div(u) * psi * fn.dx \
         + 1.0/lmbda * psi * p * fn.dx \
         - 1.0/lmbda * phi * psi * fn.dx

PRight = fn.dot(f, v) * fn.dx + fn.dot(h_g, v) * ds(32)

Sol = fn.Function(Hh)

# solve linear system
fn.solve(PLeft == PRight, Sol, bcs)

u, phi, p = Sol.split()
u.rename("u", "u")
fileU << u
Example #10
0

# -- Spatial domain
ne = 2**7
L = 15
mesh = fe.IntervalMesh(int(ne),0,L)
degQ = 1 
degA = 1
QE     = fe.FiniteElement("Lagrange", cell=mesh.ufl_cell(), degree=degQ)
AE     = fe.FiniteElement("Lagrange", cell=mesh.ufl_cell(), degree=degA)
ME     = fe.MixedElement([AE,QE])
V      = fe.FunctionSpace(mesh,ME)
V_A = V.sub(0)
V_Q = V.sub(1)
(v1,v2) = fe.TestFunctions(V)
dv1 = fe.grad(v1)[0]
dv2 = fe.grad(v2)[0]
(u1,u2) = fe.TrialFunctions(V)
U0 = fe.Function(V)
U0.assign( fe.Expression( ( 'A0', 'Q0' ) , A0=A0, Q0=Q0, degree=1 ) )
Un = fe.Function(V)
Un.assign( fe.Expression( ( 'A0', 'Q0' ) , A0=A0, Q0=Q0, degree=1 ) )
(u01,u02) = fe.split(U0)
(un1,un2) = fe.split(Un)
du01 = fe.grad(u01)[0] ; du02 = fe.grad(u02)[0]
dun1 = fe.grad(un1)[0] ; dun2 = fe.grad(un2)[0]


B0      = getB(u01,u02)
H0      = getH(u01,u02)
HdUdz0  = matMult(H0,[du01, du02])
    A_fenics = fenics.PETScMatrix(A_petsc)
    return A_fenics


if perform_tests:
    import numpy as np
    from time import time

    # Make Laplacian matrix in fenics
    n = 10
    mesh = fenics.UnitCubeMesh(n, n, n)
    V = fenics.FunctionSpace(mesh, 'CG', 1)

    u = fenics.TrialFunction(V)
    v = fenics.TestFunction(V)
    a = fenics.inner(fenics.grad(u),
                     fenics.grad(v)) * fenics.dx + u * v * fenics.dx

    f = fenics.Function(V)
    f.vector()[:] = np.random.randn(V.dim())
    b = f * v * fenics.dx

    b_fenics = fenics.assemble(b)
    b_numpy = b_fenics[:]

    A_fenics = fenics.assemble(a)

    # Test correctness of matrix converters

    A_scipy = convert_fenics_csr_matrix_to_scipy_csr_matrix(A_fenics)
    A_fenics2 = convert_scipy_csr_matrix_to_fenics_csr_matrix(A_scipy)
Example #12
0
    Ct4 = fe.Constant(2)

    d1 = fe.Expression('x[0] - 0', degree=1)
    #d2 = fe.Expression('1 - x[0]', degree=1)
    #d3 = fe.Expression('1 - x[1]', degree=1)
    d = fe.Expression('x[1] - 0', degree=1)

    #d = fe.Constant(10)
    #d = Min(d1, d4)

    xi = nu_trial / nu
    fv1 = xi**3 / (xi**3 + Cv1 * Cv1 * Cv1)
    #fv1 = fe.elem_pow(xi, 3) / (fe.elem_pow(xi, 3) + Cv1 * Cv1 * Cv1)
    fv2 = 1 - xi / (1 + xi * fv1)
    ft2 = Ct3 * fe.exp(-Ct4 * xi * xi)
    Omega = fe.Constant(0.5) * (fe.grad(u) - fe.grad(u).T)
    S = fe.sqrt(EPSILON + fe.Constant(2) * fe.inner(Omega, Omega))
    Stilde = S + nu_trial / (kappa * kappa * d * d) * fv2
    ft2 = Ct3 * fe.exp(fe.Constant(-1) * Ct4 * xi * xi)
    r = Min(nu_trial / (Stilde * kappa * kappa * d * d), 10)
    g = r + Cw2 * (r * r * r * r * r * r - r)
    fw = fe.elem_pow(
        EPSILON +
        abs(g * ((1 + Cw3 * Cw3 * Cw3 * Cw3 * Cw3 * Cw3) /
                 (g * g * g * g * g * g + Cw3 * Cw3 * Cw3 * Cw3 * Cw3 * Cw3))),
        fe.Constant(1. / 6.))

ns_conv = fe.inner(v, fe.grad(u) * u) * fe.dx
ns_press = p * fe.div(v) * fe.dx
s = fe.grad(u) + fe.grad(u).T
if MODEL:
Example #13
0
UC    = fn.Function(V)
uc    = fn.split(UC)                        # trial function potential concentration lagrange multi
u, c, lam = uc[0], uc[1:M+1], uc[M+1:]

VW    = fn.TestFunctions(V)                          # test function potential concentration lagrange multi                     
v, w, mu = VW[0], VW[1:M+1], VW[M+1:]

# changing concentrations charges
Rho = 0
for i in range(M):
    if i%2:
        Rho += -c[i]
    else:
        Rho += c[i]

PoissonLeft     = (fn.dot(alpha*fn.grad(u), fn.grad(v)))*fn.dx                    # weak solution Poisson left
PoissonRight    = -(Rho)*beta*v*fn.dx                                  # weak solution Poisson right
NernstPlanck    = 0
for i in range(M):
    if i%2:
        NernstPlanck += fn.dot(-gamma*fn.grad(c[i]) + c[i]*delta*fn.grad(u),fn.grad(w[i]))*fn.dx     # weak solution Nernst-Planck 
    else:
        NernstPlanck += fn.dot(-gamma*fn.grad(c[i]) - c[i]*delta*fn.grad(u),fn.grad(w[i]))*fn.dx     # weak solution Nernst-Planck

constraint = 0
for i in range(M):
    constraint += lam[i] * w[i] * fn.dx + (c[i] - c_avg) * mu[i] * fn.dx            #constraint a la hoermann
    
        
PNP_xy     = PoissonLeft + PoissonRight + NernstPlanck + constraint        # PNP system
 
Example #14
0
def half_exp_dyn(w0, dt=1.e-5, t_end=1.e-4, show_plots=False):

    u0 = w0.u
    p0 = w0.p
    v0 = w0.v

    bcs_u, bcs_p, bcs_v = load_2d_muscle_bc(V_u, V_pv.sub(0), V_pv.sub(1),
                                            boundaries)

    F = deformation_grad(u0)
    I_1, I_2, J = invariants(F)
    F_iso = isochronic_deformation_grad(F, J)
    #I_1_iso, I_2_iso  = invariants(F_iso)[0:2]
    W = material_mooney_rivlin(I_1, I_2, c_10, c_01)
    g = incompr_constr(J)
    # Lagrange function (without constraint)
    L = -W
    P = first_piola_stress(L, F)
    G = incompr_stress(g, F)

    # a_dyn_u = inner(u1 - u0, eta) * dx - dt * inner(v1, eta) * dx

    u1 = fe.TrialFunction(V_u)
    eta = fe.TestFunction(V_u)

    #u11 = fe.Function(V_u)
    #F1 = deformation_grad(u11)
    #g1 = incompr_constr(fe.det(F1))
    #G1 = incompr_stress(g1, F1)

    (p1, v1) = fe.TrialFunctions(V_pv)
    (q, xi) = fe.TestFunctions(V_pv)

    a_dyn_u = inner(u1 - u0, eta) * dx - dt * inner(v0, eta) * dx

    a_dyn_p = fe.tr(G * grad(v1)) * q * dx
    #a_dyn_v = rho*inner(v1-v0, xi)*dx + dt*(inner(P + p0*G, grad(xi))*dx - inner(B, xi)*dx)
    a_dyn_v = rho * inner(v1 - v0, xi) * dx + dt * (inner(
        P, grad(xi)) * dx + inner(p1 * G, grad(xi)) * dx - inner(B, xi) * dx)

    a_u = fe.lhs(a_dyn_u)
    l_u = fe.rhs(a_dyn_u)

    a_pv = fe.lhs(a_dyn_p + a_dyn_v)
    l_pv = fe.rhs(a_dyn_p + a_dyn_v)

    u1 = fe.Function(V_u)
    pv1 = fe.Function(V_pv)

    sol = []

    vol = fe.assemble(1. * dx)

    A_u = fe.assemble(a_u)
    A_pv = fe.assemble(a_pv)

    for bc in bcs_u:
        bc.apply(A_u)

    t = 0
    while t < t_end:
        print("progress: %f" % (100. * t / t_end))

        # update displacement u
        L_u = fe.assemble(l_u)
        fe.solve(A_u, u1.vector(), L_u)
        u0.assign(u1)

        L_pv = fe.assemble(l_pv)
        for bc in bcs_p + bcs_v:
            bc.apply(A_pv, L_pv)

        fe.solve(A_pv, pv1.vector(), L_pv)

        if fe.norm(pv1.vector()) > 1e8:
            print('ERROR: norm explosion')
            break

        # update initial values for next step
        w0.u = u1
        w0.pv = pv1
        p0.assign(w0.p)
        v0.assign(w0.v)

        t += dt

        if show_plots:
            # plot result
            fe.plot(w0.sub(0), mode='displacement')
            plt.show()

        # save solutions
        sol.append(Solution(t=t))
        sol[-1].upv.assign(w0)

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

    return 0.5 * E
Example #18
0
def eps(v):
    return fnc.sym(fnc.grad(v))
Example #19
0
def cn_before_ab(d_, w_, k):
    E = 0.5*(grad(d_["n"]).T + grad(d_["n-1"]).T + grad(d_["n"]) + grad(d_["n-1"]))  \
        + 0.5*((grad(d_["n-1"] + k*(3./2*w_["n-1"] - 1./2*w_["n-2"])).T * grad(d_["n"])) \
                + (grad(d_["n-1"]).T*grad(d_["n-1"])))

    return 0.5 * E
Example #20
0
def sigma(r):
    return 2.0 * mu * fnc.sym(fnc.grad(r)) + lmbda * fnc.tr(
        fnc.sym(fnc.grad(r))) * fnc.Identity(len(r))
Example #21
0
# Initialize the adapter according to the specific participant
if problem is ProblemType.DIRICHLET:
    precice = Adapter(adapter_config_filename="precice-adapter-config-D.json")
    precice_dt = precice.initialize(coupling_boundary, read_function_space=V, write_object=f_N_function)
elif problem is ProblemType.NEUMANN:
    precice = Adapter(adapter_config_filename="precice-adapter-config-N.json")
    precice_dt = precice.initialize(coupling_boundary, read_function_space=W, write_object=u_D_function)

dt = Constant(0)
dt.assign(np.min([fenics_dt, precice_dt]))

# Define variational problem
u = TrialFunction(V)
v = TestFunction(V)
f = Expression('beta - 2 - 2*alpha', degree=2, alpha=alpha, beta=beta, t=0)
F = u * v / dt * dx + dot(grad(u), grad(v)) * dx - (u_n / dt + f) * v * dx

bcs = [DirichletBC(V, u_D, remaining_boundary)]

# Set boundary conditions at coupling interface once wrt to the coupling
# expression
coupling_expression = precice.create_coupling_expression()
if problem is ProblemType.DIRICHLET:
    # modify Dirichlet boundary condition on coupling interface
    bcs.append(DirichletBC(V, coupling_expression, coupling_boundary))
if problem is ProblemType.NEUMANN:
    # modify Neumann boundary condition on coupling interface, modify weak
    # form correspondingly
    F += v * coupling_expression * dolfin.ds

a, L = lhs(F), rhs(F)
Example #22
0
def k(u, w):
    return fnc.inner(sigma(u), fnc.sym(fnc.grad(w))) * fnc.dx
Example #23
0
    inclusion = Inclusion_3d()
    point0 = "near(x[0], 0) && near(x[1], 0) && near(x[2], 0)"

V = FunctionSpace(mesh, "CG", order, constrained_domain=PeriodicBoundary(dim))

# setting the elements that lies in inclusion and in matrix phase
domains = MeshFunction("size_t", mesh, dim)
domains.set_all(0)
inclusion.mark(domains, 1)
dx = Measure('dx', subdomain_data=domains)


def bilf(up, vp):  # bilinear form
    return inner(mat * up, vp) * dx(0) + inner(inc * up, vp) * dx(1)


bc0 = DirichletBC(V, Constant(0.), point0, method='pointwise')

# SOLVER
u = TrialFunction(V)
v = TestFunction(V)
uE = Function(V)

solve(bilf(grad(u), grad(v)) == -bilf(E, grad(v)), uE, bcs=[bc0])

# POSTPROCESSING evaluation of guaranteed bound
AH11 = assemble(bilf(grad(uE) + E, grad(uE) + E))
print('homogenised component A11 = {} (FEM)'.format(AH11))

print('END')
Example #24
0
    def staggered_solve(self):
        self.U = fe.VectorFunctionSpace(self.mesh, 'CG', 1)
        self.W = fe.FunctionSpace(self.mesh, 'CG', 1)
        self.WW = fe.FunctionSpace(self.mesh, 'DG', 0)

        self.eta = fe.TestFunction(self.U)
        self.zeta = fe.TestFunction(self.W)

        del_x = fe.TrialFunction(self.U)
        del_d = fe.TrialFunction(self.W)

        self.x_new = fe.Function(self.U)
        self.d_new = fe.Function(self.W)

        x_old = fe.Function(self.U)
        d_old = fe.Function(self.W)

        self.H_old = fe.Function(self.WW)

        self.build_weak_form_staggered()
        J_u = fe.derivative(self.G_u, self.x_new, del_x)
        J_d = fe.derivative(self.G_d, self.d_new, del_d)

        self.set_bcs_staggered()
        p_u = fe.NonlinearVariationalProblem(self.G_u, self.x_new, self.BC_u,
                                             J_u)
        p_d = fe.NonlinearVariationalProblem(self.G_d, self.d_new, self.BC_d,
                                             J_d)
        solver_u = fe.NonlinearVariationalSolver(p_u)
        solver_d = fe.NonlinearVariationalSolver(p_d)

        vtkfile_u = fe.File('data/pvd/{}/u.pvd'.format(self.case_name))
        vtkfile_d = fe.File('data/pvd/{}/d.pvd'.format(self.case_name))

        for i, (disp, rp) in enumerate(
                zip(self.displacements, self.relaxation_parameters)):

            print('\n')
            print(
                '================================================================================='
            )
            print('>> Step {}, disp boundary condition = {} [mm]'.format(
                i, disp))
            print(
                '================================================================================='
            )

            self.H_old.assign(
                fe.project(
                    history(self.H_old, self.psi(strain(fe.grad(self.x_new))),
                            self.psi_cr), self.WW))

            self.presLoad.t = disp

            newton_prm = solver_u.parameters['newton_solver']
            newton_prm['maximum_iterations'] = 100
            newton_prm['absolute_tolerance'] = 1e-4
            newton_prm['relaxation_parameter'] = rp

            iteration = 0
            err = 1.

            while err > self.staggered_tol:
                iteration += 1

                solver_d.solve()

                solver_u.solve()

                err_u = fe.errornorm(self.x_new,
                                     x_old,
                                     norm_type='l2',
                                     mesh=None)
                err_d = fe.errornorm(self.d_new,
                                     d_old,
                                     norm_type='l2',
                                     mesh=None)
                err = max(err_u, err_d)

                x_old.assign(self.x_new)
                d_old.assign(self.d_new)

                print(
                    '---------------------------------------------------------------------------------'
                )
                print('>> iteration. {}, error = {:.5}'.format(iteration, err))
                print(
                    '---------------------------------------------------------------------------------'
                )

                if err < self.staggered_tol or iteration >= self.staggered_maxiter:
                    print(
                        '================================================================================='
                    )
                    print('\n')

                    self.x_new.rename("u", "u")
                    self.d_new.rename("d", "d")
                    vtkfile_u << self.x_new
                    vtkfile_d << self.d_new
                    break

            force_upper = float(fe.assemble(self.sigma[1, 1] * self.ds(1)))
            print("Force upper {}".format(force_upper))
            self.delta_u_recorded.append(disp)
            self.sigma_recorded.append(force_upper)
# old results
uold = fn.interpolate(uinit, Mh)
vold = fn.interpolate(fn.Constant(b * pow(a + b, -2)), Mh)

# computation parameters
hsize = 1.0 / nps
t = 0.0
CFL = 5.0
dt = CFL * hsize * hsize
T = 2.0
frequencySave = 100

# weak form
Left  = u/dt * uT * fn.dx + v/dt * vT * fn.dx \
        + c1 * fn.inner(fn.grad(u), fn.grad(uT)) * fn.dx \
        + c2 * fn.inner(fn.grad(v), fn.grad(vT)) * fn.dx

Right = uold * uT/dt * fn.dx + vold * vT/dt * fn.dx \
        + d * (a - uold + uold * uold * vold) * uT * fn.dx \
        + d * (b - uold * uold * vold) * vT * fn.dx

AA = fn.assemble(Left)
solver = fn.LUSolver(AA)
solver.parameters["reuse_factorization"] = True

# time loop
inc = 0

while (t <= T):
Example #26
0
    def monolithic_solve(self):
        self.U = fe.VectorElement('CG', self.mesh.ufl_cell(), 1)
        self.W = fe.FiniteElement("CG", self.mesh.ufl_cell(), 1)
        self.M = fe.FunctionSpace(self.mesh, self.U * self.W)

        self.WW = fe.FunctionSpace(self.mesh, 'DG', 0)

        m_test = fe.TestFunctions(self.M)
        m_delta = fe.TrialFunctions(self.M)
        m_new = fe.Function(self.M)

        self.eta, self.zeta = m_test
        self.x_new, self.d_new = fe.split(m_new)

        self.H_old = fe.Function(self.WW)

        vtkfile_u = fe.File('data/pvd/{}/u.pvd'.format(self.case_name))
        vtkfile_d = fe.File('data/pvd/{}/d.pvd'.format(self.case_name))

        self.build_weak_form_monolithic()
        dG = fe.derivative(self.G, m_new)

        self.set_bcs_monolithic()
        p = fe.NonlinearVariationalProblem(self.G, m_new, self.BC, dG)
        solver = fe.NonlinearVariationalSolver(p)

        for i, (disp, rp) in enumerate(
                zip(self.displacements, self.relaxation_parameters)):

            print('\n')
            print(
                '================================================================================='
            )
            print('>> Step {}, disp boundary condition = {} [mm]'.format(
                i, disp))
            print(
                '================================================================================='
            )

            self.H_old.assign(
                fe.project(
                    history(self.H_old, self.psi(strain(fe.grad(self.x_new))),
                            self.psi_cr), self.WW))

            self.presLoad.t = disp

            newton_prm = solver.parameters['newton_solver']
            newton_prm['maximum_iterations'] = 100
            newton_prm['absolute_tolerance'] = 1e-4
            newton_prm['relaxation_parameter'] = rp

            solver.solve()

            self.x_plot, self.d_plot = m_new.split()
            self.x_plot.rename("u", "u")
            self.d_plot.rename("d", "d")

            vtkfile_u << self.x_plot
            vtkfile_d << self.d_plot

            force_upper = float(fe.assemble(self.sigma[1, 1] * self.ds(1)))
            print("Force upper {}".format(force_upper))
            self.delta_u_recorded.append(disp)
            self.sigma_recorded.append(force_upper)

            print(
                '================================================================================='
            )
Example #27
0
 def update_history(self):
     psi_new = self.psi_plus(strain(fe.grad(self.x_new)))
     return psi_new
Example #28
0
 def get_new_value(self, r: fenics.Function) -> fenics.Expression:
     return 2.0*self.lame_mu*fenics.sym(fenics.grad(r)) \
            + self.lame_lambda*fenics.tr(fenics.sym(fenics.grad(r)))*fenics.Identity(len(r))
Example #29
0
def boundary(x, on_boundary):
    return on_boundary

bc = fs.DirichletBC(V, u_D, boundary)

# Define initial value
u_0 = fs.Expression('exp(-a * pow(x[0], 2) - a * pow(x[1], 2))', degree=2, a=5)
u_n = fs.interpolate(u_0, V)

# Define variational problem
u = fs.TrialFunction(V)
v = fs.TestFunction(V)
f = fs.Constant(0)

F = u * v * fs.dx + dt * fs.dot(fs.grad(u), fs.grad(v)) *fs.dx - (u_n + dt * f) * v * fs.dx
a, L = fs.lhs(F), fs.rhs(F)

# Create VTK file for saving solution
vtkfile = fs.File('heat_gaussian/solution.pvd')

# Time-stepping
u = fs.Function(V)
t = 0
for n in range(num_steps):

    # Update current time
    t += dt

    # Compute solution
    fs.solve(a == L, u, bc)
Example #30
0
def ab_on_F(d_, w_, k):
    F1 = grad(1.5 * d_["n-1"] - 0.5 * d_["n-2"]) - Identity(2)
    F2 = 0.5 * grad(d_["n"] + d_["n-1"])
    E = F1.T * F2 - I

    return 0.5 * E
Example #31
0
def test_formulation_1_trap_2_materials():
    '''
    Test function formulation() with 1 intrinsic trap
    and 2 materials
    '''
    def create_subdomains(x1, x2):
        class domain(FESTIM.SubDomain):
            def inside(self, x, on_boundary):
                return x[0] >= x1 and x[0] <= x2
        domain = domain()
        return domain
    dt = 1
    traps = [{
        "energy": 1,
        "density": 2,
        "materials": [1, 2]
        }]
    materials = [{
            "alpha": 1,
            "beta": 2,
            "density": 3,
            "borders": [0, 0.5],
            "E_diff": 4,
            "D_0": 5,
            "id": 1
            },
            {
            "alpha": 2,
            "beta": 3,
            "density": 4,
            "borders": [0.5, 1],
            "E_diff": 5,
            "D_0": 6,
            "id": 2
            }]
    extrinsic_traps = []
    mesh = fenics.UnitIntervalMesh(10)
    mf = fenics.MeshFunction("size_t", mesh, 1, 1)
    mat1 = create_subdomains(0, 0.5)
    mat2 = create_subdomains(0.5, 1)
    mat1.mark(mf, 1)
    mat2.mark(mf, 2)
    V = fenics.VectorFunctionSpace(mesh, 'P', 1, 2)
    u = fenics.Function(V)
    u_n = fenics.Function(V)
    v = fenics.TestFunction(V)

    solutions = list(fenics.split(u))
    previous_solutions = list(fenics.split(u_n))
    testfunctions = list(fenics.split(v))

    mf = fenics.MeshFunction('size_t', mesh, 1, 1)
    dx = fenics.dx(subdomain_data=mf)
    temp = fenics.Expression("300", degree=0)
    flux_ = fenics.Expression("1", degree=0)

    F, expressions = FESTIM.formulation(
        traps, extrinsic_traps, solutions, testfunctions,
        previous_solutions, dt, dx, materials, temp, flux_)

    # Transient sol
    expected_form = ((solutions[0] - previous_solutions[0]) / dt) * \
        testfunctions[0]*dx
    # Diffusion sol mat 1
    expected_form += 5 * fenics.exp(-4/8.6e-5/temp) * \
        fenics.dot(
            fenics.grad(solutions[0]), fenics.grad(testfunctions[0]))*dx(1)
    # Diffusion sol mat 2
    expected_form += 6 * fenics.exp(-5/8.6e-5/temp) * \
        fenics.dot(
            fenics.grad(solutions[0]), fenics.grad(testfunctions[0]))*dx(2)
    # Source sol
    expected_form += -flux_*testfunctions[0]*dx
    # Transient trap 1
    expected_form += ((solutions[1] - previous_solutions[1]) / dt) * \
        testfunctions[1]*dx
    # Trapping trap 1 mat 1
    expected_form += - 5 * fenics.exp(-4/8.6e-5/temp)/1/1/2 * \
        solutions[0] * (2 - solutions[1]) * \
        testfunctions[1]*dx(1)
    # Trapping trap 1 mat 2
    expected_form += - 6 * fenics.exp(-5/8.6e-5/temp)/2/2/3 * \
        solutions[0] * (2 - solutions[1]) * \
        testfunctions[1]*dx(2)
    # Detrapping trap 1 mat 1
    expected_form += 1e13*fenics.exp(-1/8.6e-5/temp)*solutions[1] * \
        testfunctions[1]*dx(1)
    # Detrapping trap 1 mat 2
    expected_form += 1e13*fenics.exp(-1/8.6e-5/temp)*solutions[1] * \
        testfunctions[1]*dx(2)
    # Source detrapping sol
    expected_form += ((solutions[1] - previous_solutions[1]) / dt) * \
        testfunctions[0]*dx

    assert expected_form.equals(F) is True
Example #32
0
    def solve(self):
        # TODO: when FEniCS ported to Python3, this should be exist_ok
        try:
            os.makedirs('results')
        except OSError:
            pass

        z, w = (self.z, self.w)
        u0 = d.Constant(0.0)

        # Define the linear and bilinear forms
        L = u0 * w * dx

        # Define useful functions
        cond = d.Function(self.DV)
        U = d.Function(self.V)

        # Initialize the max_e vector, that will store the cumulative max e values
        max_e = d.Function(self.V)
        max_e.vector()[:] = 0.0
        max_e.rename("max_E", "Maximum energy deposition by location")
        max_e_file = d.File("results/%s-max_e.pvd" % input_mesh)
        max_e_per_step = d.Function(self.V)
        max_e_per_step_file = d.File("results/%s-max_e_per_step.pvd" % input_mesh)

        self.es = {}
        self.max_es = {}
        fi = d.File("results/%s-cond.pvd" % input_mesh)

        potential_file = d.File("results/%s-potential.pvd" % input_mesh)

        # Loop through the voltages and electrode combinations
        for i, (anode, cathode, voltage) in enumerate(v.electrode_triples):
            print("Electrodes %d (%lf) -> %d (0)" % (anode, voltage, cathode))

            cond = d.project(self.sigma_start, V=self.DV)

            # Define the Dirichlet boundary conditions on the active needles
            uV = d.Constant(voltage)
            term1_bc = d.DirichletBC(self.V, uV, self.patches, v.needles[anode])
            term2_bc = d.DirichletBC(self.V, u0, self.patches, v.needles[cathode])

            e = d.Function(self.V)
            e.vector()[:] = max_e.vector()

            # Re-evaluate conductivity
            self.increase_conductivity(cond, e)

            for j in range(v.max_restarts):
                # Update the bilinear form
                a = d.inner(d.nabla_grad(z), cond * d.nabla_grad(w)) * dx

                # Solve again
                print(" [solving...")
                d.solve(a == L, U, bcs=[term1_bc, term2_bc])
                print("  ....solved]")

                # Extract electric field norm
                for k in range(len(U.vector())):
                    if N.isnan(U.vector()[k]):
                        U.vector()[k] = 1e5

                e_new = d.project(d.sqrt(d.dot(d.grad(U), d.grad(U))), self.V)

                # Take the max of the new field and the established electric field
                e.vector()[:] = N.array([max(*X) for X in zip(e.vector(), e_new.vector())])

                # Re-evaluate conductivity
                fi << cond
                self.increase_conductivity(cond, e)

            potential_file << U

            # Save the max e function to a VTU
            max_e_per_step.vector()[:] = e.vector()[:]
            max_e_per_step_file << max_e_per_step

            # Store this electric field norm, for this triple, for later reference
            self.es[i] = e

            # Store the max of this electric field norm and that for all previous triples
            max_e_array = N.array([max(*X) for X in zip(max_e.vector(), e.vector())])
            max_e.vector()[:] = max_e_array

            # Create a new max_e function for storage, or it will be overwritten by the next iteration
            max_e_new = d.Function(self.V)
            max_e_new.vector()[:] = max_e_array

            # Store this max e function for the cumulative coverage curve calculation later
            self.max_es[i] = max_e_new

            # Save the max e function to a VTU
            max_e_file << max_e
            self.max_e_count = i