def S(self, u_, p_, ivar=None, tang=False):

        C_ = variable(self.kin.C(u_))

        stress = constantvalue.zero((3, 3))

        # volumetric (kinematic) growth
        if self.mat_growth:

            theta_ = ivar["theta"]

            # material has to be evaluated with C_e only, however total S has
            # to be computed by differentiating w.r.t. C (S = 2*dPsi/dC)
            self.mat = materiallaw(self.C_e(C_, theta_), self.I)

        else:

            self.mat = materiallaw(C_, self.I)

        m = 0
        for matlaw in self.matmodels:

            stress += self.add_stress_mat(matlaw, self.matparams[m], ivar, C_)

            m += 1

        # add remodeled material
        if self.mat_growth and self.mat_remodel:

            self.stress_base = stress

            self.stress_remod = constantvalue.zero((3, 3))

            m = 0
            for matlaw in self.matmodels_remod:

                self.stress_remod += self.add_stress_mat(
                    matlaw, self.matparams_remod[m], ivar, C_)

                m += 1

            # update the stress expression: S = (1-phi(theta)) * S_base + phi(theta) * S_remod
            stress = (
                1. - self.phi_remod(theta_)
            ) * self.stress_base + self.phi_remod(theta_) * self.stress_remod

        # if we have p (hydr. pressure) as variable in a 2-field functional
        if self.incompr_2field:
            if self.mat_growth:
                # TeX: S_{\mathrm{vol}} = -2 \frac{\partial[p(J^{\mathrm{e}}-1)]}{\partial \boldsymbol{C}}
                stress += -2. * diff(
                    p_ * (sqrt(det(self.C_e(C_, theta_))) - 1.), C_)
            else:
                # TeX: S_{\mathrm{vol}} = -2 \frac{\partial[p(J-1)]}{\partial \boldsymbol{C}} = -Jp\boldsymbol{C}^{-1}
                stress += -2. * diff(p_ * (sqrt(det(C_)) - 1.), C_)

        if tang:
            return 2. * diff(stress, C_)
        else:
            return stress
예제 #2
0
    def add_stress_mat(self, matlaw, mparams, ivar, C_):

        # sanity check
        if self.incompr_2field and '_vol' in matlaw:
            raise AttributeError("Do not use a volumetric material law when using a 2-field variational principle with pressure dofs!")

        if matlaw == 'neohooke_dev':
            
            return self.mat.neohooke_dev(mparams,C_)
            
        elif matlaw == 'mooneyrivlin_dev':
            
            return self.mat.mooneyrivlin_dev(mparams,C_)
            
        elif matlaw == 'holzapfelogden_dev':

            return self.mat.holzapfelogden_dev(mparams,self.kin.fib_funcs[0],self.kin.fib_funcs[1],C_)
        
        elif matlaw == 'guccione_dev':

            return self.mat.guccione_dev(mparams,self.kin.fib_funcs[0],self.kin.fib_funcs[1],C_)
            
        elif matlaw == 'stvenantkirchhoff':
            
            return self.mat.stvenantkirchhoff(mparams,C_)
            
        elif matlaw == 'ogden_vol':
            
            return self.mat.ogden_vol(mparams,C_)
            
        elif matlaw == 'sussmanbathe_vol':
            
            return self.mat.sussmanbathe_vol(mparams,C_)
            
        elif matlaw == 'active_fiber':
            
            tau_a_ = ivar["tau_a"]
            return self.mat.active_fiber(tau_a_, self.kin.fib_funcs[0])
            
        elif matlaw == 'active_iso':
            
            tau_a_ = ivar["tau_a"]
            return self.mat.active_iso(tau_a_)
            
        elif matlaw == 'inertia':
            # density is added to kinetic virtual work
            return constantvalue.zero((3,3))
        
        elif matlaw == 'rayleigh_damping':
            # Rayleigh damping is added to virtual work
            return constantvalue.zero((3,3))
        
        elif matlaw == 'growth':
            # growth (and remodeling) treated separately
            return constantvalue.zero((3,3))
            
        else:

            raise NameError('Unknown solid material law!')
예제 #3
0
    def __new__(cls, a, b):
        # Conversion
        a = as_ufl(a)
        b = as_ufl(b)

        # Type checking
        if not is_true_ufl_scalar(a):
            error("Cannot take the power of a non-scalar expression %s." %
                  ufl_err_str(a))
        if not is_true_ufl_scalar(b):
            error("Cannot raise an expression to a non-scalar power %s." %
                  ufl_err_str(b))

        # Simplification
        if isinstance(a, ScalarValue) and isinstance(b, ScalarValue):
            return as_ufl(a._value**b._value)
        if isinstance(b, Zero):
            return IntValue(1)
        if isinstance(a, Zero) and isinstance(b, ScalarValue):
            if isinstance(b, ComplexValue):
                error("Cannot raise zero to a complex power.")
            bf = float(b)
            if bf < 0:
                error("Division by zero, cannot raise 0 to a negative power.")
            else:
                return zero()
        if isinstance(b, ScalarValue) and b._value == 1:
            return a

        # Construction
        self = Operator.__new__(cls)
        self._init(a, b)
        return self
예제 #4
0
    def set_acc_vel(self, u, u_old, v_old, a_old):

        # set forms for acc and vel
        if self.timint == 'genalpha':
            acc = self.update_a_newmark(u, u_old, v_old, a_old, ufl=True)
            vel = self.update_v_newmark(acc, u, u_old, v_old, a_old, ufl=True)
        elif self.timint == 'ost':
            acc = self.update_a_ost(u, u_old, v_old, a_old, ufl=True)
            vel = self.update_v_ost(acc, u, u_old, v_old, a_old, ufl=True)
        elif self.timint == 'static':
            acc = constantvalue.zero(3)
            vel = constantvalue.zero(3)
        else:
            raise NameError(
                "Unknown time-integration algorithm for solid mechanics!")

        return acc, vel
예제 #5
0
    def set_acc(self, v, v_old, a_old):

        # set forms for acc and vel
        if self.timint == 'ost':
            acc = self.update_a_ost(v, v_old, a_old, ufl=True)
        elif self.timint == 'static':
            acc = constantvalue.zero(3)
        else:
            raise NameError(
                "Unknown time-integration algorithm for fluid mechanics!")

        return acc
예제 #6
0
def determinant_expr(A):
    "Compute the (pseudo-)determinant of A."
    sh = A.ufl_shape
    if isinstance(A, Zero):
        return zero()
    elif sh == ():
        return A
    elif sh[0] == sh[1]:
        if sh[0] == 1:
            return A[0, 0]
        elif sh[0] == 2:
            return determinant_expr_2x2(A)
        elif sh[0] == 3:
            return determinant_expr_3x3(A)
    else:
        return pseudo_determinant_expr(A)

    # TODO: Implement generally for all dimensions?
    error("determinant_expr not implemented for shape %s." % (sh, ))
예제 #7
0
    def __new__(cls, a, b):
        a = as_ufl(a)
        b = as_ufl(b)
        if not is_true_ufl_scalar(a): error("Cannot take the power of a non-scalar expression.")
        if not is_true_ufl_scalar(b): error("Cannot raise an expression to a non-scalar power.")

        if isinstance(a, ScalarValue) and isinstance(b, ScalarValue):
            return as_ufl(a._value ** b._value)
        if a == 0 and isinstance(b, ScalarValue):
            bf = float(b)
            if bf < 0:
                error("Division by zero, annot raise 0 to a negative power.")
            else:
                return zero()
        if b == 1:
            return a
        if b == 0:
            return IntValue(1)

        # construct and initialize a new Power object
        self = AlgebraOperator.__new__(cls)
        self._init(a, b)
        return self