Пример #1
0
 def _solve_cell_problems(self):
     # Solves the cell problems (one for each space dimension)
     w = fe.TrialFunction(self.function_space)
     v = fe.TestFunction(self.function_space)
     a = self.a_y * fe.dot(fe.grad(w), fe.grad(v)) * fe.dx
     for i in range(self.dim):
         L = fe.div(self.a_y * self.e_is[i]) * v * fe.dx
         bc = fe.DirichletBC(self.function_space, self.bc_function,
                             PoissonSolver.boundary)
         fe.solve(a == L, self.cell_solutions[i], bc)
         fe.plot(self.cell_solutions[i])
Пример #2
0
    def compute_shape_derivative(self):
        """Computes the part of the shape derivative that comes from the regularization

		Returns
		-------
		ufl.form.Form
			The weak form of the shape derivative coming from the regularization

		"""

        V = self.form_handler.test_vector_field
        if self.has_regularization:

            n = fenics.FacetNormal(self.form_handler.mesh)
            I = fenics.Identity(self.form_handler.mesh.geometric_dimension())

            self.shape_form = Constant(self.mu_surface) * (
                self.current_surface - Constant(self.target_surface)) * t_div(
                    V, n) * self.ds

            if not self.measure_hole:
                self.shape_form += Constant(self.mu_volume) * (
                    self.current_volume -
                    Constant(self.target_volume)) * div(V) * self.dx
                self.shape_form += Constant(self.mu_barycenter)*(self.current_barycenter_x - Constant(self.target_barycenter_list[0]))\
                         *(self.current_barycenter_x/self.current_volume*div(V) + 1/self.current_volume*(V[0] + self.spatial_coordinate[0]*div(V)))*self.dx \
                       + Constant(self.mu_barycenter)*(self.current_barycenter_y - Constant(self.target_barycenter_list[1]))\
                         *(self.current_barycenter_y/self.current_volume*div(V) + 1/self.current_volume*(V[1] + self.spatial_coordinate[1]*div(V)))*self.dx

                if self.form_handler.mesh.geometric_dimension() == 3:
                    self.shape_form += Constant(self.mu_barycenter)*(self.current_barycenter_z - Constant(self.target_barycenter_list[2]))\
                           *(self.current_barycenter_z/self.current_volume*div(V) + 1/self.current_volume*(V[2] + self.spatial_coordinate[2]*div(V)))*self.dx

            else:
                self.shape_form -= Constant(self.mu_volume) * (
                    self.current_volume -
                    Constant(self.target_volume)) * div(V) * self.dx
                self.shape_form += Constant(self.mu_barycenter)*(self.current_barycenter_x - Constant(self.target_barycenter_list[0]))\
                         *(self.current_barycenter_x/self.current_volume*div(V) - 1/self.current_volume*(V[0] + self.spatial_coordinate[0]*div(V)))*self.dx \
                       + Constant(self.mu_barycenter)*(self.current_barycenter_y - Constant(self.target_barycenter_list[1]))\
                         *(self.current_barycenter_y/self.current_volume*div(V) - 1/self.current_volume*(V[1] + self.spatial_coordinate[1]*div(V)))*self.dx

                if self.form_handler.mesh.geometric_dimension() == 3:
                    self.shape_form += Constant(self.mu_barycenter)*(self.current_barycenter_z - Constant(self.target_barycenter_list[2]))\
                             *(self.current_barycenter_z/self.current_volume*div(V) - 1/self.current_volume*(V[2] + self.spatial_coordinate[2]*div(V)))*self.dx

            return self.shape_form

        else:
            dim = self.form_handler.mesh.geometric_dimension()
            return inner(fenics.Constant([0] * dim), V) * self.dx
Пример #3
0
def t_div(u, n):
    """Computes the tangential divergence

	Parameters
	----------
	u : dolfin.function.function.Function
		the argument
	n : ufl.geometry.FacetNormal
		the outer unit normal vector

	Returns
	-------
	ufl.core.expr.Expr
		the tangential divergence of u
	"""

    return fenics.div(u) - fenics.inner(fenics.grad(u) * n, n)
Пример #4
0
def postprocess(fname, field, cond):
    """Postprocessing of the simulation."""
    func_space = field.function_space()
    mesh = func_space.mesh()
    degree = func_space.ufl_element().degree()
    vec_func_space = fe.VectorFunctionSpace(mesh, INPUTS['element_type'],
                                            degree)
    flux = fe.project(-cond * fe.grad(field), vec_func_space)
    divergence = fe.project(-fe.div(cond * 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))
    keff = av_flux * (ZMAX - ZMIN) / (INPUTS['boundary_conditions']['top'] -
                                      INPUTS['boundary_conditions']['bottom'])
    print('Effective conductivity: {0}'.format(keff))
    with open(fname + "_keff.csv", 'w') as textfile:
        textfile.write('keff\n')
        textfile.write('{0}\n'.format(keff))
    fe.File(fname + "_solution.pvd") << field
    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
    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()
Пример #5
0
    W.sub(0), fe.Expression(('%s * pow((x[1]) / 2.5, 2)' % RE, '0'),
                            degree=DEG), dbc_inflow)
#bc_inflow = fe.DirichletBC(W.sub(0), fe.Constant((RE, '0')), dbc_inflow)
bc_p = fe.DirichletBC(W.sub(1), bc_p, dbc_top)


def Max(a, b):
    return (a + b + abs(a - b)) / 2.


def Min(a, b):
    return (a + b - abs(a - b)) / 2.


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
sij = 0.5 * (fe.grad(u) + fe.grad(u).T)
nu_tv = lmx**(2 * fe.inner(sij, sij))**(0.5)
ns_tv = fe.inner((nu_tv) * fe.grad(v), fe.grad(u)) * fe.dx
ns_visc = nu * fe.inner(fe.grad(v), fe.grad(u)) * fe.dx
ns_conti = q * fe.div(u) * fe.dx
ns_forcing = fe.dot(v, b) * fe.dx

NS = ns_conv + ns_press + ns_tv + ns_visc + ns_conti + ns_forcing

N = 5
fe.parameters["form_compiler"]["quadrature_degree"] = N

weakForm = (1.0 / dt) * fe.inner(u - u0, v) * fe.dx + NS
Пример #6
0
FooT = fn.CompiledSubDomain(
    "(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[1], 0.0) ) && 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 forms ********** #

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
fn.solve(PLeft == PRight, Sol, bcs)

u, phi, p = Sol.split()
Пример #7
0
    #r =fe.Constant(1)
    #r = nu_trial / (Stilde * kappa * kappa * d * d)
    r = Max(Min(nu_trial / (Stilde * kappa * kappa * d * d), fe.Constant(10)),
            -10)
    #r = fe.Constant(0.1)
    #g = fe.Constant(0.01)
    g = r + Cw2 * (r * r * r * r * r * r - r)
    #fw =  g * ((1 + Cw3 * Cw3 * Cw3 * Cw3 * Cw3 * Cw3) / (g * g * g * g * g * g + Cw3 * Cw3 * Cw3 * Cw3 * Cw3 * Cw3))
    fw = fe.elem_pow(
        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.))
    #fw = fe.Constant(1)

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: ns_tv = fe.inner((fv1 * nu_trial) * fe.grad(v), fe.grad(u)) * fe.dx
else:
    sij = 0.5 * (fe.grad(u) + fe.grad(u).T)
    nu_tv = lmx**(2 * fe.inner(sij, sij))**(0.5)
    ns_tv = fe.inner((nu_tv) * fe.grad(v), fe.grad(u)) * fe.dx
ns_visc = nu * fe.inner(fe.grad(v), fe.grad(u)) * fe.dx
ns_conti = q * fe.div(u) * fe.dx
ns_forcing = fe.dot(v, b) * fe.dx

NS = ns_conv + ns_press + ns_tv + ns_visc + ns_conti + ns_forcing

N = 5
fe.parameters["form_compiler"]["quadrature_degree"] = N
if MODEL:
Пример #8
0
def sigma(u, p):
    return 2*mu*epsilon(u) - p*fs.Identity(len(u))

# Define variational problem for step 1 (Tentative velocity step)
F1 = rho*fs.dot((u - u_n) / k, v)*fs.dx + \
    rho*fs.dot(fs.dot(u_n, fs.nabla_grad(u_n)), v)*fs.dx \
  + fs.inner(sigma(U, p_n), epsilon(v))*fs.dx \
  + fs.dot(p_n*n, v)*fs.ds - fs.dot(mu*fs.nabla_grad(U)*n, v)*fs.ds \
  - fs.dot(f, v)*fs.dx
a1 = fs.lhs(F1)
L1 = fs.rhs(F1)

# Define variational problem for step 2 (Pressure correction step)
a2 = fs.dot(fs.nabla_grad(p),   fs.nabla_grad(q))*fs.dx
L2 = fs.dot(fs.nabla_grad(p_n), fs.nabla_grad(q))*fs.dx \
        - (1/k)*fs.div(u_)*q*fs.dx

# Define variational problem for step 3 (Velocity correction step)
a3 = fs.dot(u,  v)*fs.dx
L3 = fs.dot(u_, v)*fs.dx - k*fs.dot(fs.nabla_grad(p_ - p_n), v)*fs.dx

# Assemble matrices
A1 = fs.assemble(a1)
A2 = fs.assemble(a2)
A3 = fs.assemble(a3)

# Apply boundary conditions to matrices
[bc.apply(A1) for bc in bcu]
[bc.apply(A2) for bc in bcp]

# Time-stepping
Пример #9
0
    def __compute_shape_gradient_forms(self):
        """Calculates the necessary left-hand-sides for the shape gradient problem.

		Returns
		-------
		None
		"""

        self.shape_bdry_def = json.loads(
            self.config.get('ShapeGradient', 'shape_bdry_def', fallback='[]'))
        if not type(self.shape_bdry_def) == list:
            raise ConfigError('ShapeGradient', 'shape_bdry_def',
                              'The input has to be a list.')
        # if not len(self.shape_bdry_def) > 0:
        # 	raise ConfigError('ShapeGradient', 'shape_bdry_def','The input must not be empty.')

        self.shape_bdry_fix = json.loads(
            self.config.get('ShapeGradient', 'shape_bdry_fix', fallback='[]'))
        if not type(self.shape_bdry_def) == list:
            raise ConfigError('ShapeGradient', 'shape_bdry_fix',
                              'The input has to be a list.')

        self.shape_bdry_fix_x = json.loads(
            self.config.get('ShapeGradient', 'shape_bdry_fix_x',
                            fallback='[]'))
        if not type(self.shape_bdry_fix_x) == list:
            raise ConfigError('ShapeGradient', 'shape_bdry_fix_x',
                              'The input has to be a list.')

        self.shape_bdry_fix_y = json.loads(
            self.config.get('ShapeGradient', 'shape_bdry_fix_y',
                            fallback='[]'))
        if not type(self.shape_bdry_fix_y) == list:
            raise ConfigError('ShapeGradient', 'shape_bdry_fix_y',
                              'The input has to be a list.')

        self.shape_bdry_fix_z = json.loads(
            self.config.get('ShapeGradient', 'shape_bdry_fix_z',
                            fallback='[]'))
        if not type(self.shape_bdry_fix_z) == list:
            raise ConfigError('ShapeGradient', 'shape_bdry_fix_z',
                              'The input has to be a list.')

        self.bcs_shape = create_bcs_list(
            self.deformation_space,
            fenics.Constant([0] *
                            self.deformation_space.ufl_element().value_size()),
            self.boundaries, self.shape_bdry_fix)
        self.bcs_shape += create_bcs_list(self.deformation_space.sub(0),
                                          fenics.Constant(0.0),
                                          self.boundaries,
                                          self.shape_bdry_fix_x)
        self.bcs_shape += create_bcs_list(self.deformation_space.sub(1),
                                          fenics.Constant(0.0),
                                          self.boundaries,
                                          self.shape_bdry_fix_y)
        if self.deformation_space.num_sub_spaces() == 3:
            self.bcs_shape += create_bcs_list(self.deformation_space.sub(2),
                                              fenics.Constant(0.0),
                                              self.boundaries,
                                              self.shape_bdry_fix_z)

        self.CG1 = fenics.FunctionSpace(self.mesh, 'CG', 1)
        self.DG0 = fenics.FunctionSpace(self.mesh, 'DG', 0)

        if self.shape_scalar_product is None:
            # Use the default linear elasticity approach

            self.mu_lame = fenics.Function(self.CG1)
            self.lambda_lame = self.config.getfloat('ShapeGradient',
                                                    'lambda_lame',
                                                    fallback=0.0)
            self.damping_factor = self.config.getfloat('ShapeGradient',
                                                       'damping_factor',
                                                       fallback=0.0)

            if self.config.getboolean('ShapeGradient',
                                      'inhomogeneous',
                                      fallback=False):
                self.volumes = fenics.project(fenics.CellVolume(self.mesh),
                                              self.DG0)
                vol_max = np.max(np.abs(self.volumes.vector()[:]))
                self.volumes.vector()[:] /= vol_max

            else:
                self.volumes = fenics.Constant(1.0)

            def eps(u):
                return fenics.Constant(0.5) * (fenics.grad(u) +
                                               fenics.grad(u).T)

            trial = fenics.TrialFunction(self.deformation_space)
            test = fenics.TestFunction(self.deformation_space)

            self.riesz_scalar_product = fenics.Constant(2)*self.mu_lame/self.volumes*fenics.inner(eps(trial), eps(test))*self.dx \
                   + fenics.Constant(self.lambda_lame)/self.volumes*fenics.div(trial)*fenics.div(test)*self.dx \
                   + fenics.Constant(self.damping_factor)/self.volumes*fenics.inner(trial, test)*self.dx

        else:
            # Use the scalar product supplied by the user

            self.riesz_scalar_product = self.shape_scalar_product
Пример #10
0
def navierStokes(projectId, mesh, faceSets, boundarySets, config):

    log("Navier Stokes Analysis has started")

    # this is the default directory, when user request for download all files in this directory is being compressed and sent to the user
    resultDir = "./Results/"

    if len(config["steps"]) > 1:
        return "more than 1 step is not supported yet"

    # config is a dictionary containing all the user inputs for solver configurations
    t_init = 0.0
    t_final = float(config['steps'][0]["finalTime"])
    t_num = int(config['steps'][0]["iterationNo"])
    dt = ((t_final - t_init) / t_num)
    t = t_init

    #
    #  Viscosity coefficient.
    #
    nu = float(config['materials'][0]["viscosity"])
    rho = float(config['materials'][0]["density"])

    #
    #  Declare Finite Element Spaces
    # do not use triangle directly
    P2 = fn.VectorElement("P", mesh.ufl_cell(), 2)
    P1 = fn.FiniteElement("P", mesh.ufl_cell(), 1)
    TH = fn.MixedElement([P2, P1])
    V = fn.VectorFunctionSpace(mesh, "P", 2)
    Q = fn.FunctionSpace(mesh, "P", 1)
    W = fn.FunctionSpace(mesh, TH)

    #
    #  Declare Finite Element Functions
    #
    (u, p) = fn.TrialFunctions(W)
    (v, q) = fn.TestFunctions(W)
    w = fn.Function(W)
    u0 = fn.Function(V)
    p0 = fn.Function(Q)

    #
    # Macros needed for weak formulation.
    #
    def contract(u, v):
        return fn.inner(fn.nabla_grad(u), fn.nabla_grad(v))

    def b(u, v, w):
        return 0.5 * (fn.inner(fn.dot(u, fn.nabla_grad(v)), w) -
                      fn.inner(fn.dot(u, fn.nabla_grad(w)), v))

    # Define boundaries
    bcs = []
    for BC in config['BCs']:
        if BC["boundaryType"] == "wall":
            for edge in json.loads(BC["edges"]):
                bcs.append(
                    fn.DirichletBC(W.sub(0),
                                   fn.Constant((0.0, 0.0, 0.0)),
                                   boundarySets,
                                   int(edge),
                                   method='topological'))
        if BC["boundaryType"] == "inlet":
            vel = json.loads(BC['value'])
            for edge in json.loads(BC["edges"]):
                bcs.append(
                    fn.DirichletBC(W.sub(0),
                                   fn.Expression(
                                       (str(vel[0]), str(vel[1]), str(vel[2])),
                                       degree=2),
                                   boundarySets,
                                   int(edge),
                                   method='topological'))
        if BC["boundaryType"] == "outlet":
            for edge in json.loads(BC["edges"]):
                bcs.append(
                    fn.DirichletBC(W.sub(1),
                                   fn.Constant(float(BC['value'])),
                                   boundarySets,
                                   int(edge),
                                   method='topological'))

    f = fn.Constant((0.0, 0.0, 0.0))

    #  weak form NSE
    NSE = (1.0/dt)*fn.inner(u, v)*fn.dx + b(u0, u, v)*fn.dx + nu * \
        contract(u, v)*fn.dx - fn.div(v)*p*fn.dx + q*fn.div(u)*fn.dx
    LNSE = fn.inner(f, v) * fn.dx + (1. / dt) * fn.inner(u0, v) * fn.dx

    velocity_file = fn.XDMFFile(resultDir + "/vel.xdmf")
    pressure_file = fn.XDMFFile(resultDir + "/pressure.xdmf")
    velocity_file.parameters["flush_output"] = True
    velocity_file.parameters["functions_share_mesh"] = True
    pressure_file.parameters["flush_output"] = True
    pressure_file.parameters["functions_share_mesh"] = True
    #
    # code for projecting a boundary condition into a file for visualization
    #
    # for bc in bcs:
    #     bc.apply(w.vector())
    # fn.File("para_plotting/bc.pvd") << w.sub(0)

    for jj in range(0, t_num):
        t = t + dt
        # print('t = ' + str(t))
        A, b = fn.assemble_system(NSE, LNSE, bcs)
        fn.solve(A, w.vector(), b)
        # fn.solve(NSE==LNSE,w,bcs)
        fn.assign(u0, w.sub(0))
        fn.assign(p0, w.sub(1))
        # Save Solutions to Paraview File
        if (jj % 20 == 0):
            velocity_file.write(u0, t)
            pressure_file.write(p0, t)
            sendFile(projectId, resultDir + "vel.xdmf")
            sendFile(projectId, resultDir + "vel.h5")
            sendFile(projectId, resultDir + "pressure.xdmf")
            sendFile(projectId, resultDir + "pressure.h5")
            statusUpdate(projectId, "STARTED", {"progress": jj / t_num * 100})
Пример #11
0
    if (stim_t1 <= t and t <= stim_t1 + stim_dur1):
        return waveS1
    if (stim_t2 <= t and t <= stim_t2 + stim_dur2):
        return waveS2
    else:
        return fn.Constant(0.0)

# weak forms - poroelasticity
# left-hand side
pe_left_hand_side = \
        (c0/alpha + 1.0/lmbda) * (p/dt) * q * fn.dx - \
        (1.0/lmbda) * (phi/dt) * q * fn.dx + \
        (kappa/(eta * alpha)) * fn.dot(fn.grad(p), fn.grad(q)) * fn.dx - \
        (1.0/lmbda) * phi * psi * fn.dx + \
        (1.0/lmbda) * p * psi * fn.dx - \
        fn.div(u) * psi * fn.dx + \
        2.0 * mu * fn.inner(strain(u), strain(v)) * fn.dx - \
        phi * fn.div(v) * fn.dx

# right-hand side
pe_right_hand_side = \
        (c0/alpha + 1.0/lmbda) * (p_old/dt) * q * fn.dx - \
        (1.0/lmbda) * (phi_old/dt) * q * fn.dx + \
        fn.dot(f, v) * fn.dx + \
        fn.dot(v, c_1 * fn.outer(f_0, f_0) * fn.grad(n_old)) * fn.dx
        
# solutions
pe_solution = fn.Function(Hh)
rd_solution = fn.Function(Nh)

z     = fn.Function(Vhf)
Пример #12
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)
Пример #13
0
    fe.Expression(('%s * pow((x[1] - 1) / 2.5, 2)' % RE, '0'), degree=DEG),
    dbc_inflow)
#bc_inflow = fe.DirichletBC(W.sub(0), fe.Constant((RE, '0')), dbc_inflow)
bc_p = fe.DirichletBC(W.sub(1), bc_p, dbc_top)


def Max(a, b):
    return (a + b + abs(a - b)) / 2.


def Min(a, b):
    return (a + b - abs(a - b)) / 2.


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
sij = 0.5 * (fe.grad(u) + fe.grad(u).T)
S = fe.sqrt(EPSILON + 2. * fe.inner(0.5 * (fe.grad(u) + fe.grad(u).T), 0.5 *
                                    (fe.grad(u) + fe.grad(u).T)))
lmx = 0.3
nu_tv = lmx**2. * S

#nu_tv = 0.5 * fe.inner(sij, sij) ** 0.5
#nu_tv = lmx * (2 * fe.inner(sij, sij)) ** (0.5)
#ns_tv = fe.inner((nu_tv) * fe.grad(v), fe.grad(u)) * fe.dx
ns_visc = (nu + nu_tv) * fe.inner(fe.grad(v), fe.grad(u)) * fe.dx
#ns_visc = nu * fe.inner(fe.grad(v), fe.grad(u)) * fe.dx
ns_conti = q * fe.div(u) * fe.dx
ns_forcing = fe.dot(v, b) * fe.dx
Пример #14
0
def explicit_relax_dyn(w0, kappa=1e5, dt=1.e-5, t_end=1.e-4, show_plots=False):

    (u0, p0, v0) = fe.split(w0)

    bcs_u, bcs_p, bcs_v = load_2d_muscle_bc(V_upv.sub(0), V_upv.sub(1),
                                            V_upv.sub(2), boundaries)

    kappa = fe.Constant(kappa)

    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) + incompr_relaxation(
        p0, kappa)
    g = incompr_constr(J)

    # Lagrange function (without constraint)

    L = -W
    P = first_piola_stress(L, F)
    G = incompr_stress(g, F)

    (u1, p1, v1) = fe.TrialFunctions(V_upv)
    (eta, q, xi) = fe.TestFunctions(V_upv)
    a_dyn_u = inner(u1 - u0, eta) * dx - dt * inner(v1, eta) * dx
    a_dyn_p = (p1 - p0) * q * dx - dt * kappa * div(v1) * J * 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(p0 * G, grad(xi)) * dx - inner(B, xi) * dx)

    a = fe.lhs(a_dyn_u + a_dyn_p + a_dyn_v)
    l = fe.rhs(a_dyn_u + a_dyn_p + a_dyn_v)

    w1 = fe.Function(V_upv)
    w2 = fe.Function(V_upv)

    sol = []

    vol = fe.assemble(1. * dx)

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

        A = fe.assemble(a)
        L = fe.assemble(l)

        for bc in bcs_u + bcs_p + bcs_v:
            bc.apply(A, L)

        fe.solve(A, w1.vector(), L)

        if fe.norm(w1.vector()) > 1e7:
            print('ERROR: norm explosion')
            break

        # update initial values for next step
        w0.assign(w1)
        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, kappa
Пример #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
    )