Esempio n. 1
0
 def __init__(self, kin, materials, incompr_2field, mat_growth=None, mat_remodel=None):
     
     self.kin = kin
     
     self.matmodels = []
     for i in range(len(materials.keys())):
         self.matmodels.append(list(materials.keys())[i])
     
     self.matparams = []
     for i in range(len(materials.values())):
         self.matparams.append(list(materials.values())[i])
     
     self.mat_growth = mat_growth
     self.mat_remodel = mat_remodel
     self.incompr_2field = incompr_2field
     
     if self.mat_growth:
         # growth & remodeling parameters
         self.gandrparams = materials['growth']
         self.growth_dir = self.gandrparams['growth_dir']
         self.growth_trig = self.gandrparams['growth_trig']
         
         if self.mat_remodel:
             
             self.matmodels_remod = []
             for i in range(len(self.gandrparams['remodeling_mat'].keys())):
                 self.matmodels_remod.append(list(self.gandrparams['remodeling_mat'].keys())[i])
             
             self.matparams_remod = []
             for i in range(len(self.gandrparams['remodeling_mat'].values())):
                 self.matparams_remod.append(list(self.gandrparams['remodeling_mat'].values())[i])
         
     # identity tensor
     self.I = Identity(3)
Esempio n. 2
0
    def compute_force(self, velocity, pressure, t):
        self.tc.start('errorForce')
        I = Identity(3)  # Identity tensor

        def T(p, v):
            return -p * I + 2.0 * self.nu * sym(grad(v))

        error_force = sqrt(
            assemble(
                inner((T(pressure, velocity) - T(self.sol_p, self.solution)) *
                      self.normal,
                      (T(pressure, velocity) - T(self.sol_p, self.solution)) *
                      self.normal) * self.dsWall))
        an_force = sqrt(
            assemble(
                inner(
                    T(self.sol_p, self.solution) * self.normal,
                    T(self.sol_p, self.solution) * self.normal) * self.dsWall))
        an_f_normal = sqrt(
            assemble(
                inner(
                    inner(
                        T(self.sol_p, self.solution) * self.normal,
                        self.normal),
                    inner(
                        T(self.sol_p, self.solution) * self.normal,
                        self.normal)) * self.dsWall))
        error_f_normal = sqrt(
            assemble(
                inner(
                    inner(
                        (T(self.sol_p, self.solution) - T(pressure, velocity))
                        * self.normal, self.normal),
                    inner(
                        (T(self.sol_p, self.solution) - T(pressure, velocity))
                        * self.normal, self.normal)) * self.dsWall))
        an_f_shear = sqrt(
            assemble(
                inner(
                    (I - outer(self.normal, self.normal)) *
                    T(self.sol_p, self.solution) * self.normal,
                    (I - outer(self.normal, self.normal)) *
                    T(self.sol_p, self.solution) * self.normal) * self.dsWall))
        error_f_shear = sqrt(
            assemble(
                inner((I - outer(self.normal, self.normal)) *
                      (T(self.sol_p, self.solution) - T(pressure, velocity)) *
                      self.normal, (I - outer(self.normal, self.normal)) *
                      (T(self.sol_p, self.solution) - T(pressure, velocity)) *
                      self.normal) * self.dsWall))
        self.listDict['a_force_wall']['list'].append(an_force)
        self.listDict['a_force_wall_normal']['list'].append(an_f_normal)
        self.listDict['a_force_wall_shear']['list'].append(an_f_shear)
        self.listDict['force_wall']['list'].append(error_force)
        self.listDict['force_wall_normal']['list'].append(error_f_normal)
        self.listDict['force_wall_shear']['list'].append(error_f_shear)
        print('  Relative force error:', error_force / an_force)
        self.tc.end('errorForce')
Esempio n. 3
0
 def __init__(self, fib_funcs=None, F_hist=None):
     
     # fibers
     self.fib_funcs = fib_funcs
     
     # history deformation gradient (for prestressing)
     self.F_hist = F_hist
     
     # identity tensor
     self.I = Identity(3)
    def __init__(self, kin, materials):

        self.kin = kin

        self.matmodels = []
        for i in range(len(materials.keys())):
            self.matmodels.append(list(materials.keys())[i])

        self.matparams = []
        for i in range(len(materials.values())):
            self.matparams.append(list(materials.values())[i])

        # identity tensor
        self.I = Identity(3)
 def sigma(self, u):
     n = u.geometric_dimension()
     lmbda = self.lmbda3D(0)
     mu = self.mu3D(0)
     return lmbda * tr(self.eps(u)) * Identity(n) + 2 * mu * self.eps(u)
 def sigma0(self):
     n = self.dim
     lmbda = self.lmbda3D(0)
     mu = self.mu3D(0)
     return lmbda * tr(self.eps0()) * Identity(n) + 2 * mu * self.eps0()
Esempio n. 7
0
# Create CG Krylov solver and turn convergence monitoring on
solver = PETSc.KSP().create(MPI.COMM_WORLD)
solver.setFromOptions()

# Set matrix operator
solver.setOperators(A)

# Compute solution
solver.setMonitor(lambda ksp, its, rnorm: print(
    "Iteration: {}, rel. residual: {}".format(its, rnorm)))
solver.solve(b, u.vector)
solver.view()
u.x.scatter_forward()

# Compute von Mises stress via interpolation
sigma_deviatoric = sigma(u) - (1 / 3) * tr(sigma(u)) * Identity(len(u))
sigma_von_mises = sqrt((3 / 2) * inner(sigma_deviatoric, sigma_deviatoric))

W = FunctionSpace(mesh, ("Discontinuous Lagrange", 0))
sigma_von_mises_expression = Expression(sigma_von_mises,
                                        W.element.interpolation_points)
sigma_von_mises_h = Function(W)
sigma_von_mises_h.interpolate(sigma_von_mises_expression)

# Save solution to XDMF format
with XDMFFile(MPI.COMM_WORLD, "displacements.xdmf", "w") as file:
    file.write_mesh(mesh)
    file.write_function(u)

# Save solution to XDMF format
with XDMFFile(MPI.COMM_WORLD, "von_mises_stress.xdmf", "w") as file:
Esempio n. 8
0
uflSpace1 = Space((2, 2), 1)
u1 = TrialFunction(uflSpace1)
v1 = TestFunction(uflSpace1)
uflSpace2 = Space((2, 2), 2)
u2 = TrialFunction(uflSpace2)
v2 = TestFunction(uflSpace2)

if test_21:
    a = div(u2) * v1[0] * dx
    model = create.model("integrands", grid, a)

    space = "lagrange"
    if test_fem:
        test(model, space, 2, 1, "fem")
    if test_istl:
        test(model, space, 2, 1, "istl")
    if test_petsc:
        test(model, space, 2, 1, "petsc")

if test_12:
    a = -inner(u1[0] * Identity(2), grad(v2)) * dx
    model = create.model("integrands", grid, a)

    space = "lagrange"
    if test_fem:
        test(model, space, 1, 2, "fem")
    if test_istl:
        test(model, space, 1, 2, "istl")
    if test_petsc:
        test(model, space, 1, 2, "petsc")
Esempio n. 9
0
def compute_total_jacobian(displacement):
    return det(Identity(len(displacement)) + grad(displacement))
Esempio n. 10
0
def compute_growth_induced_strain(conc_field, coupling_constant, dim):
    return conc_field * coupling_constant * Identity(dim)
Esempio n. 11
0
File: run.py Progetto: miklos1/urumi
def holzapfel_ogden(mesh, q, p, nf=0):
    # Based on https://gist.github.com/meg-simula/3ab3fd63264c8cf1912b
    #
    # Original credit note:
    # "Original implementation by Gabriel Balaban,
    # modified by Marie E. Rognes"

    from ufl import (Constant, VectorConstant, Identity, Coefficient,
                     TestFunction, conditional, det, diff, dot, exp,
                     grad, inner, tr, variable)

    # Define some random parameters
    a = Constant(mesh)
    b = Constant(mesh)
    a_s = Constant(mesh)
    b_s = Constant(mesh)
    a_f = Constant(mesh)
    b_f = Constant(mesh)
    a_fs = Constant(mesh)
    b_fs = Constant(mesh)

    # For more fun, make these general vector fields rather than
    # constants:
    e_s = VectorConstant(mesh)
    e_f = VectorConstant(mesh)

    # Define the isochoric energy contribution
    def isochoric(C):
        I_1 = tr(C)
        I4_f = dot(e_f, C*e_f)
        I4_s = dot(e_s, C*e_s)
        I8_fs = dot(e_s, C*e_f)

        def heaviside(x):
            return conditional(x < 1, 0, 1)

        def scaled_exp(a, b, x):
            return a/(2*b)*(exp(b*x) - 1)

        E_1 = scaled_exp(a, b, I_1 - 3)

        E_f = heaviside(I4_f)*scaled_exp(a_f, b_f, (I4_f - 1)**2)
        E_s = heaviside(I4_s)*scaled_exp(a_s, b_s, (I4_s - 1)**2)
        E_3 = scaled_exp(a_fs, b_fs, I8_fs**2)

        E = E_1 + E_f + E_s + E_3
        return E

    # Define mesh and function space
    V = ufl.FunctionSpace(mesh, ufl.VectorElement("CG", mesh.ufl_cell(), q))
    u = Coefficient(V)
    v = TestFunction(V)

    # Misc elasticity related tensors and other quantities
    I = Identity(mesh.ufl_cell().topological_dimension())
    F = grad(u) + I
    F = variable(F)
    J = det(F)
    Cbar = J**(-2/3)*F.T*F

    # Define energy
    Psi = isochoric(Cbar)

    # Find first Piola-Kirchhoff tensor
    P = diff(Psi, F)

    # Define the variational formulation
    it = inner(P, grad(v))

    P = ufl.FunctionSpace(mesh, ufl.VectorElement('P', mesh.ufl_cell(), p))
    f = [ufl.Coefficient(P) for _ in range(nf)]
    return ufl.derivative(reduce(ufl.inner,
                                 list(map(ufl.div, f)) + [it])*ufl.dx, u)
Esempio n. 12
0
    ldot * timeVals[:len(timeVals) // 2],
    ldot * (-timeVals[len(timeVals) // 2:] + 2 * timeVals[len(timeVals) // 2]),
))

svals = np.zeros_like(stretchVals)

plt.plot(timeVals, stretchVals)
plt.savefig("stretchesVisco.png")
plt.close()

# stabilization parameters
h = FacetArea(mesh)
h_avg = avg(h)

# new variable name to take derivatives
FF = Identity(3) + grad(u)
CC = FF.T * FF
Fv = variable(FF)
S = diff(freeEnergy(Fv.T * Fv, CCv), Fv)  # first PK stress
dl_interp(CC, C)
dl_interp(CC, Cn)

my_identity = grad(SpatialCoordinate(mesh))

dl_interp(my_identity, CCv)
dl_interp(my_identity, Cvn)
dl_interp(my_identity, C_quart)
dl_interp(my_identity, C_thr_quart)
dl_interp(my_identity, C_half)

a_uv = (derivative(freeEnergy(CC, CCv), u, v) * dx +
Esempio n. 13
0
    def solve(self, problem):
        self.problem = problem
        doSave = problem.doSave
        save_this_step = False
        onlyVel = problem.saveOnlyVel
        dt = self.metadata['dt']

        nu = Constant(self.problem.nu)
        self.tc.init_watch('init',
                           'Initialization',
                           True,
                           count_to_percent=False)
        self.tc.init_watch('rhs',
                           'Assembled right hand side',
                           True,
                           count_to_percent=True)
        self.tc.init_watch('applybc1',
                           'Applied velocity BC 1st step',
                           True,
                           count_to_percent=True)
        self.tc.init_watch('applybc3',
                           'Applied velocity BC 3rd step',
                           True,
                           count_to_percent=True)
        self.tc.init_watch('applybcP',
                           'Applied pressure BC or othogonalized rhs',
                           True,
                           count_to_percent=True)
        self.tc.init_watch('assembleMatrices',
                           'Initial matrix assembly',
                           False,
                           count_to_percent=True)
        self.tc.init_watch('solve 1',
                           'Running solver on 1st step',
                           True,
                           count_to_percent=True)
        self.tc.init_watch('solve 2',
                           'Running solver on 2nd step',
                           True,
                           count_to_percent=True)
        self.tc.init_watch('solve 3',
                           'Running solver on 3rd step',
                           True,
                           count_to_percent=True)
        self.tc.init_watch('solve 4',
                           'Running solver on 4th step',
                           True,
                           count_to_percent=True)
        self.tc.init_watch('assembleA1',
                           'Assembled A1 matrix (without stabiliz.)',
                           True,
                           count_to_percent=True)
        self.tc.init_watch('assembleA1stab',
                           'Assembled A1 stabilization',
                           True,
                           count_to_percent=True)
        self.tc.init_watch('next',
                           'Next step assignments',
                           True,
                           count_to_percent=True)
        self.tc.init_watch('saveVel', 'Saved velocity', True)

        self.tc.start('init')

        # Define function spaces (P2-P1)
        mesh = self.problem.mesh
        self.V = VectorFunctionSpace(mesh, "Lagrange", 2)  # velocity
        self.Q = FunctionSpace(mesh, "Lagrange", 1)  # pressure
        self.PS = FunctionSpace(
            mesh, "Lagrange", 2)  # partial solution (must be same order as V)
        self.D = FunctionSpace(mesh, "Lagrange",
                               1)  # velocity divergence space

        problem.initialize(self.V, self.Q, self.PS, self.D)

        # Define trial and test functions
        u = TrialFunction(self.V)
        v = TestFunction(self.V)
        p = TrialFunction(self.Q)
        q = TestFunction(self.Q)

        n = FacetNormal(mesh)
        I = Identity(find_geometric_dimension(u))

        # Initial conditions: u0 velocity at previous time step u1 velocity two time steps back p0 previous pressure
        [u1, u0, p0] = self.problem.get_initial_conditions([{
            'type': 'v',
            'time': -dt
        }, {
            'type': 'v',
            'time': 0.0
        }, {
            'type': 'p',
            'time': 0.0
        }])

        u_ = Function(self.V)  # current tentative velocity
        u_cor = Function(self.V)  # current corrected velocity
        p_ = Function(
            self.Q
        )  # current pressure or pressure help function from rotation scheme
        p_mod = Function(
            self.Q)  # current modified pressure from rotation scheme

        # Define coefficients
        k = Constant(self.metadata['dt'])
        f = Constant((0, 0, 0))

        # Define forms
        # step 1: Tentative velocity, solve to u_
        u_ext = 1.5 * u0 - 0.5 * u1  # extrapolation for convection term

        # Stabilisation
        h = CellSize(mesh)
        if self.args.cbc_tau:
            # used in Simula cbcflow project
            tau = Constant(self.stabCoef) * h / (sqrt(inner(u_ext, u_ext)) + h)
        else:
            # proposed in R. Codina: On stabilized finite element methods for linear systems of
            # convection-diffusion-reaction equations.
            tau = Constant(self.stabCoef) * k * h**2 / (
                2 * nu * k + k * h * sqrt(DOLFIN_EPS + inner(u_ext, u_ext)) +
                h**2)
            # DOLFIN_EPS is added because of FEniCS bug that inner(u_ext, u_ext) can be negative when u_ext = 0

        if self.use_full_SUPG:
            v1 = v + tau * 0.5 * dot(grad(v), u_ext)
            parameters['form_compiler']['quadrature_degree'] = 6
        else:
            v1 = v

        def nonlinearity(function):
            if self.args.ema:
                return 2 * inner(dot(sym(grad(function)), u_ext), v1
                                 ) * dx + inner(div(function) * u_ext, v1) * dx
            else:
                return inner(dot(grad(function), u_ext), v1) * dx

        def diffusion(fce):
            if self.useLaplace:
                return nu * inner(grad(fce), grad(v1)) * dx
            else:
                form = inner(nu * 2 * sym(grad(fce)), sym(grad(v1))) * dx
                if self.bcv == 'CDN':
                    return form
                if self.bcv == 'LAP':
                    return form - inner(nu * dot(grad(fce).T, n), v1
                                        ) * problem.get_outflow_measure_form()
                if self.bcv == 'DDN':
                    return form  # additional term must be added to non-constant part

        def pressure_rhs():
            if self.args.bc == 'outflow':
                return inner(p0, div(v1)) * dx
            else:
                return inner(p0, div(v1)) * dx - inner(
                    p0 * n, v1) * problem.get_outflow_measure_form()

        a1_const = (1. / k) * inner(u, v1) * dx + diffusion(0.5 * u)
        a1_change = nonlinearity(0.5 * u)
        if self.bcv == 'DDN':
            # does not penalize influx for current step, only for the next one
            # this can lead to oscilation:
            # DDN correct next step, but then u_ext is OK so in next step DDN is not used, leading to new influx...
            # u and u_ext cannot be switched, min_value is nonlinear function
            a1_change += -0.5 * min_value(Constant(0.), inner(
                u_ext, n)) * inner(u, v1) * problem.get_outflow_measure_form()
            # NT works only with uflacs compiler

        L1 = (1. / k) * inner(u0, v1) * dx - nonlinearity(
            0.5 * u0) - diffusion(0.5 * u0) + pressure_rhs()
        if self.bcv == 'DDN':
            L1 += 0.5 * min_value(0., inner(u_ext, n)) * inner(
                u0, v1) * problem.get_outflow_measure_form()

        # Non-consistent SUPG stabilisation
        if self.stabilize and not self.use_full_SUPG:
            # a1_stab = tau*inner(dot(grad(u), u_ext), dot(grad(v), u_ext))*dx
            a1_stab = 0.5 * tau * inner(dot(grad(u), u_ext), dot(
                grad(v), u_ext)) * dx(None, {'quadrature_degree': 6})
            # optional: to use Crank Nicolson in stabilisation term following change of RHS is needed:
            # L1 += -0.5*tau*inner(dot(grad(u0), u_ext), dot(grad(v), u_ext))*dx(None, {'quadrature_degree': 6})

        outflow_area = Constant(problem.outflow_area)
        need_outflow = Constant(0.0)
        if self.useRotationScheme:
            # Rotation scheme
            F2 = inner(grad(p), grad(q)) * dx + (1. / k) * q * div(u_) * dx
        else:
            # Projection, solve to p_
            if self.forceOutflow and problem.can_force_outflow:
                info('Forcing outflow.')
                F2 = inner(grad(p - p0),
                           grad(q)) * dx + (1. / k) * q * div(u_) * dx
                for m in problem.get_outflow_measures():
                    F2 += (1. / k) * (1. / outflow_area) * need_outflow * q * m
            else:
                F2 = inner(grad(p - p0),
                           grad(q)) * dx + (1. / k) * q * div(u_) * dx
        a2, L2 = system(F2)

        # step 3: Finalize, solve to u_
        if self.useRotationScheme:
            # Rotation scheme
            F3 = (1. / k) * inner(u - u_, v) * dx + inner(grad(p_), v) * dx
        else:
            F3 = (1. / k) * inner(u - u_, v) * dx + inner(grad(p_ - p0),
                                                          v) * dx
        a3, L3 = system(F3)

        if self.useRotationScheme:
            # Rotation scheme: modify pressure
            F4 = (p - p0 - p_ + nu * div(u_)) * q * dx
            a4, L4 = system(F4)

        # Assemble matrices
        self.tc.start('assembleMatrices')
        A1_const = assemble(
            a1_const
        )  # must be here, so A1 stays one Python object during repeated assembly
        A1_change = A1_const.copy(
        )  # copy to get matrix with same sparse structure (data will be overwritten)
        if self.stabilize and not self.use_full_SUPG:
            A1_stab = A1_const.copy(
            )  # copy to get matrix with same sparse structure (data will be overwritten)
        A2 = assemble(a2)
        A3 = assemble(a3)
        if self.useRotationScheme:
            A4 = assemble(a4)
        self.tc.end('assembleMatrices')

        if self.solvers == 'direct':
            self.solver_vel_tent = LUSolver('mumps')
            self.solver_vel_cor = LUSolver('mumps')
            self.solver_p = LUSolver('mumps')
            if self.useRotationScheme:
                self.solver_rot = LUSolver('mumps')
        else:
            # NT 2016-1  KrylovSolver >> PETScKrylovSolver

            # not needed, chosen not to use hypre_parasails:
            # if self.prec_v == 'hypre_parasails':  # in FEniCS 1.6.0 inaccessible using KrylovSolver class
            #     self.solver_vel_tent = PETScKrylovSolver('gmres')   # PETSc4py object
            #     self.solver_vel_tent.ksp().getPC().setType('hypre')
            #     PETScOptions.set('pc_hypre_type', 'parasails')
            #     # this is global setting, but preconditioners for pressure solvers are set by their constructors
            # else:
            self.solver_vel_tent = PETScKrylovSolver(
                'gmres', self.args.precV)  # nonsymetric > gmres
            # cannot use 'ilu' in parallel
            self.solver_vel_cor = PETScKrylovSolver('cg', self.args.precVC)
            self.solver_p = PETScKrylovSolver(
                self.args.solP,
                self.args.precP)  # almost (up to BC) symmetric > CG
            if self.useRotationScheme:
                self.solver_rot = PETScKrylovSolver('cg', 'hypre_amg')

        # setup Krylov solvers
        if self.solvers == 'krylov':
            # Get the nullspace if there are no pressure boundary conditions
            foo = Function(
                self.Q)  # auxiliary vector for setting pressure nullspace
            if self.args.bc == 'nullspace':
                null_vec = Vector(foo.vector())
                self.Q.dofmap().set(null_vec, 1.0)
                null_vec *= 1.0 / null_vec.norm('l2')
                self.null_space = VectorSpaceBasis([null_vec])
                as_backend_type(A2).set_nullspace(self.null_space)

            # apply global options for Krylov solvers
            solver_options = {
                'monitor_convergence': True,
                'maximum_iterations': 10000,
                'nonzero_initial_guess': True
            }
            # 'nonzero_initial_guess': True   with  solver.solve(A, u, b) means that
            # Solver will use anything stored in u as an initial guess
            for solver in [self.solver_vel_tent, self.solver_vel_cor, self.solver_rot, self.solver_p] if \
                    self.useRotationScheme else [self.solver_vel_tent, self.solver_vel_cor, self.solver_p]:
                for key, value in solver_options.items():
                    try:
                        solver.parameters[key] = value
                    except KeyError:
                        info('Invalid option %s for KrylovSolver' % key)
                        return 1

            if self.args.solP == 'richardson':
                self.solver_p.parameters['monitor_convergence'] = False

            self.solver_vel_tent.parameters['relative_tolerance'] = 10**(
                -self.args.prv1)
            self.solver_vel_tent.parameters['absolute_tolerance'] = 10**(
                -self.args.pav1)
            self.solver_vel_cor.parameters['relative_tolerance'] = 10E-12
            self.solver_vel_cor.parameters['absolute_tolerance'] = 10E-4
            self.solver_p.parameters['relative_tolerance'] = 10**(
                -self.args.prp)
            self.solver_p.parameters['absolute_tolerance'] = 10**(
                -self.args.pap)
            if self.useRotationScheme:
                self.solver_rot.parameters['relative_tolerance'] = 10E-10
                self.solver_rot.parameters['absolute_tolerance'] = 10E-10

            if self.args.Vrestart > 0:
                self.solver_vel_tent.parameters['gmres'][
                    'restart'] = self.args.Vrestart

            if self.args.solP == 'gmres' and self.args.Prestart > 0:
                self.solver_p.parameters['gmres'][
                    'restart'] = self.args.Prestart

        # boundary conditions
        bcu, bcp = problem.get_boundary_conditions(self.args.bc == 'outflow',
                                                   self.V, self.Q)
        self.tc.end('init')
        # Time-stepping
        info("Running of Incremental pressure correction scheme n. 1")
        ttime = self.metadata['time']
        t = dt
        step = 1

        # debug function
        if problem.args.debug_rot:
            plot_cor_v = Function(self.V)

        while t < (ttime + dt / 2.0):
            self.problem.update_time(t, step)
            if self.MPI_rank == 0:
                problem.write_status_file(t)

            if doSave:
                save_this_step = problem.save_this_step

            # assemble matrix (it depends on solution)
            self.tc.start('assembleA1')
            assemble(
                a1_change, tensor=A1_change
            )  # assembling into existing matrix is faster than assembling new one
            A1 = A1_const.copy()  # we dont want to change A1_const
            A1.axpy(1, A1_change, True)
            self.tc.end('assembleA1')
            self.tc.start('assembleA1stab')
            if self.stabilize and not self.use_full_SUPG:
                assemble(
                    a1_stab, tensor=A1_stab
                )  # assembling into existing matrix is faster than assembling new one
                A1.axpy(1, A1_stab, True)
            self.tc.end('assembleA1stab')

            # Compute tentative velocity step
            begin("Computing tentative velocity")
            self.tc.start('rhs')
            b = assemble(L1)
            self.tc.end('rhs')
            self.tc.start('applybc1')
            [bc.apply(A1, b) for bc in bcu]
            self.tc.end('applybc1')
            try:
                self.tc.start('solve 1')
                self.solver_vel_tent.solve(A1, u_.vector(), b)
                self.tc.end('solve 1')
                if save_this_step:
                    self.tc.start('saveVel')
                    problem.save_vel(True, u_)
                    self.tc.end('saveVel')
                if save_this_step and not onlyVel:
                    problem.save_div(True, u_)
                problem.compute_err(True, u_, t)
                problem.compute_div(True, u_)
            except RuntimeError as inst:
                problem.report_fail(t)
                return 1
            end()

            if self.useRotationScheme:
                begin("Computing tentative pressure")
            else:
                begin("Computing pressure")
            if self.forceOutflow and problem.can_force_outflow:
                out = problem.compute_outflow(u_)
                info('Tentative outflow: %f' % out)
                n_o = -problem.last_inflow - out
                info('Needed outflow: %f' % n_o)
                need_outflow.assign(n_o)
            self.tc.start('rhs')
            b = assemble(L2)
            self.tc.end('rhs')
            self.tc.start('applybcP')
            [bc.apply(A2, b) for bc in bcp]
            if self.args.bc == 'nullspace':
                self.null_space.orthogonalize(b)
            self.tc.end('applybcP')
            try:
                self.tc.start('solve 2')
                self.solver_p.solve(A2, p_.vector(), b)
                self.tc.end('solve 2')
            except RuntimeError as inst:
                problem.report_fail(t)
                return 1
            if self.useRotationScheme:
                foo = Function(self.Q)
                foo.assign(p_ + p0)
                if save_this_step and not onlyVel:
                    problem.averaging_pressure(foo)
                    problem.save_pressure(True, foo)
            else:
                foo = Function(self.Q)
                foo.assign(p_)  # we do not want to change p_ by averaging
                if save_this_step and not onlyVel:
                    problem.averaging_pressure(foo)
                    problem.save_pressure(False, foo)
            end()

            begin("Computing corrected velocity")
            self.tc.start('rhs')
            b = assemble(L3)
            self.tc.end('rhs')
            if not self.args.B:
                self.tc.start('applybc3')
                [bc.apply(A3, b) for bc in bcu]
                self.tc.end('applybc3')
            try:
                self.tc.start('solve 3')
                self.solver_vel_cor.solve(A3, u_cor.vector(), b)
                self.tc.end('solve 3')
                problem.compute_err(False, u_cor, t)
                problem.compute_div(False, u_cor)
            except RuntimeError as inst:
                problem.report_fail(t)
                return 1
            if save_this_step:
                self.tc.start('saveVel')
                problem.save_vel(False, u_cor)
                self.tc.end('saveVel')
            if save_this_step and not onlyVel:
                problem.save_div(False, u_cor)
            end()

            if self.useRotationScheme:
                begin("Rotation scheme pressure correction")
                self.tc.start('rhs')
                b = assemble(L4)
                self.tc.end('rhs')
                try:
                    self.tc.start('solve 4')
                    self.solver_rot.solve(A4, p_mod.vector(), b)
                    self.tc.end('solve 4')
                except RuntimeError as inst:
                    problem.report_fail(t)
                    return 1
                if save_this_step and not onlyVel:
                    problem.averaging_pressure(p_mod)
                    problem.save_pressure(False, p_mod)
                end()

                if problem.args.debug_rot:
                    # save applied pressure correction (expressed as a term added to RHS of next tentative vel. step)
                    # see comment next to argument definition
                    plot_cor_v.assign(project(k * grad(nu * div(u_)), self.V))
                    problem.fileDict['grad_cor']['file'].write(plot_cor_v, t)

            # compute functionals (e. g. forces)
            problem.compute_functionals(
                u_cor, p_mod if self.useRotationScheme else p_, t, step)

            # Move to next time step
            self.tc.start('next')
            u1.assign(u0)
            u0.assign(u_cor)
            u_.assign(
                u_cor)  # use corrected velocity as initial guess in first step

            if self.useRotationScheme:
                p0.assign(p_mod)
            else:
                p0.assign(p_)

            t = round(t + dt, 6)  # round time step to 0.000001
            step += 1
            self.tc.end('next')

        info("Finished: Incremental pressure correction scheme n. 1")
        problem.report()
        return 0
 def sigma(v):
     return (2.0 * mu * epsilon(v) + lmbda * tr(epsilon(v)) * Identity(len(v)))
Esempio n. 15
0
def T(u: Expr, p: Expr, mu: Expr):
    return 2 * mu * sym_grad(u) - p * Identity(u.ufl_shape[0])
Esempio n. 16
0
def tangential_proj(u: Expr, n: Expr):
    """
    See for instance:
    https://link.springer.com/content/pdf/10.1023/A:1022235512626.pdf
    """
    return (Identity(u.ufl_shape[0]) - outer(n, n)) * u
Esempio n. 17
0
    def solve(self, problem):
        self.problem = problem
        doSave = problem.doSave
        save_this_step = False
        onlyVel = problem.saveOnlyVel
        dt = self.metadata['dt']

        nu = Constant(self.problem.nu)
        self.tc.init_watch('init',
                           'Initialization',
                           True,
                           count_to_percent=False)
        self.tc.init_watch('solve',
                           'Running nonlinear solver',
                           True,
                           count_to_percent=True)
        self.tc.init_watch('next',
                           'Next step assignments',
                           True,
                           count_to_percent=True)
        self.tc.init_watch('saveVel', 'Saved velocity', True)

        self.tc.start('init')

        mesh = self.problem.mesh

        # Define function spaces (P2-P1)
        self.V = VectorFunctionSpace(mesh, "Lagrange", 2)  # velocity
        self.Q = FunctionSpace(mesh, "Lagrange", 1)  # pressure
        self.W = MixedFunctionSpace([self.V, self.Q])
        self.PS = FunctionSpace(
            mesh, "Lagrange", 2)  # partial solution (must be same order as V)
        self.D = FunctionSpace(mesh, "Lagrange",
                               1)  # velocity divergence space

        # to assign solution in space W.sub(0) to Function(V) we need FunctionAssigner (cannot be assigned directly)
        fa = FunctionAssigner(self.V, self.W.sub(0))
        velSp = Function(self.V)

        problem.initialize(self.V, self.Q, self.PS, self.D)

        # Define unknown and test function(s) NS
        v, q = TestFunctions(self.W)
        w = Function(self.W)
        dw = TrialFunction(self.W)
        u, p = split(w)

        # Define fields
        n = FacetNormal(mesh)
        I = Identity(u.geometric_dimension())
        theta = 0.5  # Crank-Nicholson
        k = Constant(self.metadata['dt'])

        # Initial conditions: u0 velocity at previous time step u1 velocity two time steps back p0 previous pressure
        [u0, p0] = self.problem.get_initial_conditions([{
            'type': 'v',
            'time': 0.0
        }, {
            'type': 'p',
            'time': 0.0
        }])

        if doSave:
            problem.save_vel(False, u0)

        # boundary conditions
        bcu, bcp = problem.get_boundary_conditions(False, self.W.sub(0),
                                                   self.W.sub(1))

        # Define steady part of the equation
        def T(u):
            return -p * I + 2.0 * nu * sym(grad(u))

        def F(u, v, q):
            return (inner(T(u), grad(v)) - q * div(u)) * dx + inner(
                grad(u) * u, v) * dx

        # Define variational forms
        F_ns = (inner(
            (u - u0), v) / k) * dx + (1.0 - theta) * F(u0, v, q) + theta * F(
                u, v, q)
        J_ns = derivative(F_ns, w, dw)
        # J_ns = derivative(F_ns, w)  # did not work

        # NS_problem = NonlinearVariationalProblem(F_ns, w, bcu, J_ns, form_compiler_parameters=ffc_options)
        NS_problem = NonlinearVariationalProblem(F_ns, w, bcu, J_ns)
        # (var. formulation, unknown, Dir. BC, jacobian, optional)
        NS_solver = NonlinearVariationalSolver(NS_problem)

        prm = NS_solver.parameters
        prm['newton_solver']['absolute_tolerance'] = 1E-08
        prm['newton_solver']['relative_tolerance'] = 1E-08
        # prm['newton_solver']['maximum_iterations'] = 45
        # prm['newton_solver']['relaxation_parameter'] = 1.0
        prm['newton_solver']['linear_solver'] = 'mumps'
        # prm['newton_solver']['lu_solver']['same_nonzero_pattern'] = True

        info(NS_solver.parameters, True)

        self.tc.end('init')

        # Time-stepping
        info("Running of direct method")
        ttime = self.metadata['time']
        t = dt
        step = 1
        while t < (ttime + dt / 2.0):
            self.problem.update_time(t, step)
            if self.MPI_rank == 0:
                problem.write_status_file(t)

            if doSave:
                save_this_step = problem.save_this_step

            # Compute
            begin("Solving NS ....")
            try:
                self.tc.start('solve')
                NS_solver.solve()
                self.tc.end('solve')
            except RuntimeError as inst:
                problem.report_fail(t)
                return 1
            end()

            # Extract solutions:
            (u, p) = w.split()
            fa.assign(velSp, u)
            # we are assigning twice (now and inside save_vel), but it works with one method save_vel for direct and
            #   projection (we could split save_vel to save one assign)

            if save_this_step:
                self.tc.start('saveVel')
                problem.save_vel(False, velSp)
                self.tc.end('saveVel')
            if save_this_step and not onlyVel:
                problem.save_div(False, u)
            problem.compute_err(False, u, t)
            problem.compute_div(False, u)

            # foo = Function(self.Q)
            # foo.assign(p)
            # problem.averaging_pressure(foo)
            # if save_this_step and not onlyVel:
            #     problem.save_pressure(False, foo)

            if save_this_step and not onlyVel:
                problem.save_pressure(False, p)

            # compute functionals (e. g. forces)
            problem.compute_functionals(u, p, t, step)

            # Move to next time step
            self.tc.start('next')
            u0.assign(velSp)
            t = round(t + dt, 6)  # round time step to 0.000001
            step += 1
            self.tc.end('next')

        info("Finished: direct method")
        problem.report()
        return 0
def compliance(sigma, u, mu, lmbda):
    return sigma / (2 * mu) - lmbda / (4 * mu *
                                       (lmbda + mu)) * tr(sigma) * Identity(
                                           u.geometric_dimension())
def compliance(sigma):
  ' Returns the strain tensor as a function of sigma '
  return sigma/(2*mu) - lmbda/(4*mu*(lmbda + mu))*tr(sigma)*Identity(u.geometric_dimension())
Esempio n. 20
0
def compute_stress(displacement, mu, lmbda):
    return 2.0 * mu * compute_strain(displacement) + \
           lmbda * tr(compute_strain(displacement)) * Identity(len(displacement))
# is assumed to be the same as the spatial dimension (in this case 3),
# unless otherwise specified.
#
# Next, we will be needing functions for the boundary source ``B``, the
# traction ``T`` and the displacement solution itself ``u``::

# Functions
u = Coefficient(element)        # Displacement from previous iteration
# B = Coefficient(element)        # Body force per unit volume
# T = Coefficient(element)        # Traction force on the boundary

# Now, we can define the kinematic quantities involved in the model::

# Kinematics
d = len(u)
I = Identity(d)         # Identity tensor
F = variable(I + grad(u))         # Deformation gradient
C = F.T*F               # Right Cauchy-Green tensor

# Invariants of deformation tensors
Ic = tr(C)
J = det(F)

# Before defining the energy density and thus the total potential
# energy, it only remains to specify constants for the elasticity
# parameters::

# Elasticity parameters
E = 10.0
nu = 0.3
mu = E/(2*(1 + nu))
Esempio n. 22
0
def compute_growth_induced_jacobian(growth_induced_strain, dim):
    return det(Identity(dim) + growth_induced_strain)
Esempio n. 23
0
    def __init__(self, io_params, time_params, fem_params, constitutive_models, bc_dict, time_curves, io, comm=None):
        problem_base.__init__(self, io_params, time_params, comm)

        self.problem_physics = 'solid'

        self.simname = io_params['simname']

        self.io = io
        
        # number of distinct domains (each one has to be assigned a own material model)
        self.num_domains = len(constitutive_models)

        self.order_disp = fem_params['order_disp']
        try: self.order_pres = fem_params['order_pres']
        except: self.order_pres = 1
        self.quad_degree = fem_params['quad_degree']
        self.incompressible_2field = fem_params['incompressible_2field']
        
        self.fem_params = fem_params
        self.constitutive_models = constitutive_models

        # collect domain data
        self.dx_, self.rho0, self.rayleigh, self.eta_m, self.eta_k = [], [], [False]*self.num_domains, [], []
        for n in range(self.num_domains):
            # integration domains
            self.dx_.append(dx(subdomain_data=self.io.mt_d, subdomain_id=n+1, metadata={'quadrature_degree': self.quad_degree}))
            # data for inertial and viscous forces: density and damping
            if self.timint != 'static':
                self.rho0.append(constitutive_models['MAT'+str(n+1)+'']['inertia']['rho0'])
                if 'rayleigh_damping' in constitutive_models['MAT'+str(n+1)+''].keys():
                    self.rayleigh[n] = True
                    self.eta_m.append(constitutive_models['MAT'+str(n+1)+'']['rayleigh_damping']['eta_m'])
                    self.eta_k.append(constitutive_models['MAT'+str(n+1)+'']['rayleigh_damping']['eta_k'])

        try: self.prestress_initial = fem_params['prestress_initial']
        except: self.prestress_initial = False

        # type of discontinuous function spaces
        if str(self.io.mesh.ufl_cell()) == 'tetrahedron' or str(self.io.mesh.ufl_cell()) == 'triangle3D':
            dg_type = "DG"
            if (self.order_disp > 1 or self.order_pres > 1) and self.quad_degree < 3:
                raise ValueError("Use at least a quadrature degree of 3 or more for higher-order meshes!")
        elif str(self.io.mesh.ufl_cell()) == 'hexahedron' or str(self.io.mesh.ufl_cell()) == 'quadrilateral3D':
            dg_type = "DQ"
            if (self.order_disp > 1 or self.order_pres > 1) and self.quad_degree < 5:
                raise ValueError("Use at least a quadrature degree of 5 or more for higher-order meshes!")
        else:
            raise NameError("Unknown cell/element type!")
        
        # create finite element objects for u and p
        P_u = VectorElement("CG", self.io.mesh.ufl_cell(), self.order_disp)
        P_p = FiniteElement("CG", self.io.mesh.ufl_cell(), self.order_pres)
        # function spaces for u and p
        self.V_u = FunctionSpace(self.io.mesh, P_u)
        self.V_p = FunctionSpace(self.io.mesh, P_p)

        # Quadrature tensor, vector, and scalar elements
        Q_tensor = TensorElement("Quadrature", self.io.mesh.ufl_cell(), degree=1, quad_scheme="default")
        Q_vector = VectorElement("Quadrature", self.io.mesh.ufl_cell(), degree=1, quad_scheme="default")
        Q_scalar = FiniteElement("Quadrature", self.io.mesh.ufl_cell(), degree=1, quad_scheme="default")

        # not yet working - we cannot interpolate into Quadrature elements with the current dolfinx version currently!
        #self.Vd_tensor = FunctionSpace(self.io.mesh, Q_tensor)
        #self.Vd_vector = FunctionSpace(self.io.mesh, Q_vector)
        #self.Vd_scalar = FunctionSpace(self.io.mesh, Q_scalar)

        # Quadrature function spaces (currently not properly functioning for higher-order meshes!!!)
        self.Vd_tensor = TensorFunctionSpace(self.io.mesh, (dg_type, self.order_disp-1))
        self.Vd_vector = VectorFunctionSpace(self.io.mesh, (dg_type, self.order_disp-1))
        self.Vd_scalar = FunctionSpace(self.io.mesh, (dg_type, self.order_disp-1))

        # functions
        self.du    = TrialFunction(self.V_u)            # Incremental displacement
        self.var_u = TestFunction(self.V_u)             # Test function
        self.dp    = TrialFunction(self.V_p)            # Incremental pressure
        self.var_p = TestFunction(self.V_p)             # Test function
        self.u     = Function(self.V_u, name="Displacement")
        self.p     = Function(self.V_p, name="Pressure")
        # values of previous time step
        self.u_old = Function(self.V_u)
        self.v_old = Function(self.V_u)
        self.a_old = Function(self.V_u)
        self.p_old = Function(self.V_p)
        # a setpoint displacement for multiscale analysis
        self.u_set = Function(self.V_u)
        self.p_set = Function(self.V_p)
        self.tau_a_set = Function(self.Vd_scalar)
        # initial (zero) functions for initial stiffness evaluation (e.g. for Rayleigh damping)
        self.u_ini, self.p_ini, self.theta_ini, self.tau_a_ini = Function(self.V_u), Function(self.V_p), Function(self.Vd_scalar), Function(self.Vd_scalar)
        self.theta_ini.vector.set(1.0)
        self.theta_ini.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD)
        # growth stretch
        self.theta = Function(self.Vd_scalar, name="theta")
        self.theta_old = Function(self.Vd_scalar)
        self.growth_thres = Function(self.Vd_scalar)
        # initialize to one (theta = 1 means no growth)
        self.theta.vector.set(1.0), self.theta_old.vector.set(1.0)
        self.theta.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD), self.theta_old.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD)
        # active stress
        self.tau_a = Function(self.Vd_scalar, name="tau_a")
        self.tau_a_old = Function(self.Vd_scalar)
        self.amp_old, self.amp_old_set = Function(self.Vd_scalar), Function(self.Vd_scalar)
        self.amp_old.vector.set(1.0), self.amp_old_set.vector.set(1.0)
        self.amp_old.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD), self.amp_old_set.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD)
        # prestressing history defgrad and spring prestress
        if self.prestress_initial:
            self.F_hist = Function(self.Vd_tensor, name="Defgrad_hist")
            self.u_pre = Function(self.V_u)
        else:
            self.F_hist = None
            self.u_pre = None
        
        self.internalvars     = {"theta" : self.theta, "tau_a" : self.tau_a}
        self.internalvars_old = {"theta" : self.theta_old, "tau_a" : self.tau_a_old}
        
        
        # reference coordinates
        self.x_ref = Function(self.V_u)
        self.x_ref.interpolate(self.x_ref_expr)
        
        if self.incompressible_2field:
            self.ndof = self.u.vector.getSize() + self.p.vector.getSize()
        else:
            self.ndof = self.u.vector.getSize()

        # initialize solid time-integration class
        self.ti = timeintegration.timeintegration_solid(time_params, fem_params, time_curves, self.t_init, self.comm)

        # check for materials that need extra treatment (anisotropic, active stress, growth, ...)
        have_fiber1, have_fiber2 = False, False
        self.have_active_stress, self.active_stress_trig, self.have_frank_starling, self.have_growth = False, 'ode', False, False
        self.mat_active_stress, self.mat_growth, self.mat_remodel, self.mat_growth_dir, self.mat_growth_trig, self.mat_growth_thres = [False]*self.num_domains, [False]*self.num_domains, [False]*self.num_domains, [None]*self.num_domains, [None]*self.num_domains, []*self.num_domains

        self.localsolve, growth_dir = False, None
        self.actstress = []
        for n in range(self.num_domains):
            
            if 'holzapfelogden_dev' in self.constitutive_models['MAT'+str(n+1)+''].keys() or 'guccione_dev' in self.constitutive_models['MAT'+str(n+1)+''].keys():
                have_fiber1, have_fiber2 = True, True
            
            if 'active_fiber' in self.constitutive_models['MAT'+str(n+1)+''].keys():
                have_fiber1 = True
                self.mat_active_stress[n], self.have_active_stress = True, True
                # if one mat has a prescribed active stress, all have to be!
                if 'prescribed_curve' in self.constitutive_models['MAT'+str(n+1)+'']['active_fiber']:
                    self.active_stress_trig = 'prescribed'
                if 'prescribed_multiscale' in self.constitutive_models['MAT'+str(n+1)+'']['active_fiber']:
                    self.active_stress_trig = 'prescribed_multiscale'
                if self.active_stress_trig == 'ode':
                    act_curve = self.ti.timecurves(self.constitutive_models['MAT'+str(n+1)+'']['active_fiber']['activation_curve'])
                    self.actstress.append(activestress_activation(self.constitutive_models['MAT'+str(n+1)+'']['active_fiber'], act_curve))
                    if self.actstress[-1].frankstarling: self.have_frank_starling = True
                if self.active_stress_trig == 'prescribed':
                    self.ti.funcs_to_update.append({self.tau_a : self.ti.timecurves(self.constitutive_models['MAT'+str(n+1)+'']['active_fiber']['prescribed_curve'])})

            if 'active_iso' in self.constitutive_models['MAT'+str(n+1)+''].keys():
                self.mat_active_stress[n], self.have_active_stress = True, True
                # if one mat has a prescribed active stress, all have to be!
                if 'prescribed_curve' in self.constitutive_models['MAT'+str(n+1)+'']['active_iso']:
                    self.active_stress_trig = 'prescribed'
                if 'prescribed_multiscale' in self.constitutive_models['MAT'+str(n+1)+'']['active_iso']:
                    self.active_stress_trig = 'prescribed_multiscale'
                if self.active_stress_trig == 'ode':
                    act_curve = self.ti.timecurves(self.constitutive_models['MAT'+str(n+1)+'']['active_iso']['activation_curve'])
                    self.actstress.append(activestress_activation(self.constitutive_models['MAT'+str(n+1)+'']['active_iso'], act_curve))
                if self.active_stress_trig == 'prescribed':
                    self.ti.funcs_to_update.append({self.tau_a : self.ti.timecurves(self.constitutive_models['MAT'+str(n+1)+'']['active_iso']['prescribed_curve'])})

            if 'growth' in self.constitutive_models['MAT'+str(n+1)+''].keys():
                self.mat_growth[n], self.have_growth = True, True
                self.mat_growth_dir[n] = self.constitutive_models['MAT'+str(n+1)+'']['growth']['growth_dir']
                self.mat_growth_trig[n] = self.constitutive_models['MAT'+str(n+1)+'']['growth']['growth_trig']
                # need to have fiber fields for the following growth options
                if self.mat_growth_dir[n] == 'fiber' or self.mat_growth_trig[n] == 'fibstretch':
                    have_fiber1 = True
                if self.mat_growth_dir[n] == 'radial':
                    have_fiber1, have_fiber2 = True, True
                # in this case, we have a theta that is (nonlinearly) dependent on the deformation, theta = theta(C(u)),
                # therefore we need a local Newton iteration to solve for equilibrium theta (return mapping) prior to entering
                # the global Newton scheme - so flag localsolve to true
                if self.mat_growth_trig[n] != 'prescribed' and self.mat_growth_trig[n] != 'prescribed_multiscale':
                    self.localsolve = True
                    self.mat_growth_thres.append(self.constitutive_models['MAT'+str(n+1)+'']['growth']['growth_thres'])
                else:
                    self.mat_growth_thres.append(as_ufl(0))
                # for the case that we have a prescribed growth stretch over time, append curve to functions that need time updates
                # if one mat has a prescribed growth model, all have to be!
                if self.mat_growth_trig[n] == 'prescribed':
                    self.ti.funcs_to_update.append({self.theta : self.ti.timecurves(self.constitutive_models['MAT'+str(n+1)+'']['growth']['prescribed_curve'])})
                if 'remodeling_mat' in self.constitutive_models['MAT'+str(n+1)+'']['growth'].keys():
                    self.mat_remodel[n] = True
            else:
                self.mat_growth_thres.append(as_ufl(0))
                
        # full linearization of our remodeling law can lead to excessive compiler times for ffcx... :-/
        # let's try if we might can go without one of the critial terms (derivative of remodeling fraction w.r.t. C)
        try: self.lin_remod_full = fem_params['lin_remodeling_full']
        except: self.lin_remod_full = True

        # growth threshold (as function, since in multiscale approach, it can vary element-wise)
        if self.have_growth and self.localsolve:
            growth_thres_proj = project(self.mat_growth_thres, self.Vd_scalar, self.dx_)
            self.growth_thres.vector.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
            self.growth_thres.interpolate(growth_thres_proj)
        
        # read in fiber data
        if have_fiber1:

            fibarray = ['fiber']
            if have_fiber2: fibarray.append('sheet')

            # fiber function space - vector defined on quadrature points
            V_fib = self.Vd_vector
            self.fib_func = self.io.readin_fibers(fibarray, V_fib, self.dx_)

        else:
            self.fib_func = None

        
        # for multiscale G&R analysis
        self.tol_stop_large = 0

        # initialize kinematics class
        self.ki = solid_kinematics_constitutive.kinematics(fib_funcs=self.fib_func, F_hist=self.F_hist)

        # initialize material/constitutive class
        self.ma = []
        for n in range(self.num_domains):
            self.ma.append(solid_kinematics_constitutive.constitutive(self.ki, self.constitutive_models['MAT'+str(n+1)+''], self.incompressible_2field, mat_growth=self.mat_growth[n], mat_remodel=self.mat_remodel[n]))

        # initialize solid variational form class
        self.vf = solid_variationalform.variationalform(self.var_u, self.du, self.var_p, self.dp, self.io.n0, self.x_ref)
        
        # initialize boundary condition class
        self.bc = boundaryconditions.boundary_cond_solid(bc_dict, self.fem_params, self.io, self.ki, self.vf, self.ti)

        if self.prestress_initial:
            # initialize prestressing history deformation gradient
            Id_proj = project(Identity(len(self.u)), self.Vd_tensor, self.dx_)
            self.F_hist.interpolate(Id_proj)
  
        self.bc_dict = bc_dict
        
        # Dirichlet boundary conditions
        if 'dirichlet' in self.bc_dict.keys():
            self.bc.dirichlet_bcs(self.V_u)

        self.set_variational_forms_and_jacobians()
Esempio n. 24
0
def compute_deviatoric_stress_tensor(stress_tensor, dim):
    return stress_tensor - (1. / 3.) * tr(stress_tensor) * Identity(dim)
Esempio n. 25
0
x = SpatialCoordinate(cell)
mu = Constant(0, "mu")
nu = Constant(0, "nu")
u = TrialFunction(spcU)
v = TestFunction(spcU)
p = TrialFunction(spcP)
q = TestFunction(spcP)
exact_u = as_vector([x[1] * (1. - x[1]), 0])
exact_p = as_vector([(-2 * x[0] + 2) * mu])
f = as_vector([
    0,
] * grid.dimension)
f += nu * exact_u
mainModel = (nu * dot(u, v) + mu * inner(grad(u) + grad(u).T, grad(v)) -
             dot(f, v)) * dx
gradModel = -inner(p[0] * Identity(grid.dimension), grad(v)) * dx
divModel = -div(u) * q[0] * dx
massModel = inner(p, q) * dx
preconModel = inner(grad(p), grad(q)) * dx

# can also use 'operator' everywhere
mainOp = create.scheme("galerkin",
                       (mainModel == 0, DirichletBC(spcU, exact_u, 1)), spcU)
gradOp = create.operator("galerkin", gradModel, spcP, spcU)
divOp = create.operator("galerkin", divModel, spcU, spcP)
massOp = create.scheme("galerkin", massModel == 0, spcP)
preconOp = create.scheme("galerkin", preconModel == 0, spcP)

mainOp.model.mu = 0.1
mainOp.model.nu = 0.01
Esempio n. 26
0
 def sigma(v):
     return 2.0 * mu * sym(grad(v)) + lmbda * tr(sym(
         grad(v))) * Identity(2)
Esempio n. 27
0
# Fiber field
A = Coefficient(A_element)

# External forces
T = Coefficient(u_element)
p0 = Coefficient(p_element)

# Material parameters FIXME
rho = Constant(cell)
K = Constant(cell)
c00 = Constant(cell)
c11 = Constant(cell)
c22 = Constant(cell)

# Deformation gradient
I = Identity(d)
F = I + grad(u)
F = variable(F)
Finv = inv(F)
J = det(F)

# Left Cauchy-Green deformation tensor
B = F * F.T
I1_B = tr(B)
I2_B = (I1_B**2 - tr(B * B)) / 2
I3_B = J**2

# Right Cauchy-Green deformation tensor
C = F.T * F
I1_C = tr(C)
I2_C = (I1_C**2 - tr(C * C)) / 2