Beispiel #1
0
def static(K, fext, silent=False):
    """Static Analyses

    Parameters
    ----------

    K : sparse_matrix
        Stiffness matrix. Should include initial stress stiffness matrix,
        aerodynamic matrix and so forth when applicable.
    fext : array-like
        Vector of external loads.
    silent : bool, optional
        A boolean to tell whether the log messages should be printed.

    """
    increments = []
    cs = []

    NLgeom=False
    if NLgeom:
        raise NotImplementedError('Independent static function not ready for NLgeom')
    else:
        msg('Started Linear Static Analysis', silent=silent)
        c = solve(K, fext, silent=silent)
        increments.append(1.)
        cs.append(c)
        msg('Finished Linear Static Analysis', silent=silent)

    return increments, cs
Beispiel #2
0
def static(K, fext, silent=False):
    """Static Analyses

    Parameters
    ----------

    K : sparse_matrix
        Stiffness matrix. Should include initial stress stiffness matrix,
        aerodynamic matrix and so forth when applicable.
    fext : array-like
        Vector of external loads.
    silent : bool, optional
        A boolean to tell whether the log messages should be printed.

    """
    increments = []
    cs = []

    NLgeom = False
    if NLgeom:
        raise NotImplementedError(
            'Independent static function not ready for NLgeom')
    else:
        msg('Started Linear Static Analysis', silent=silent)
        c = solve(K, fext, silent=silent)
        increments.append(1.)
        cs.append(c)
        msg('Finished Linear Static Analysis', silent=silent)

    return increments, cs
Beispiel #3
0
    def static(self, NLgeom=False, silent=False):
        """General solver for static analyses

        Selects the specific solver based on the ``NL_method`` parameter.

        """
        self.increments = []
        self.cs = []

        if NLgeom:
            self.maxInc = max(self.initialInc, self.maxInc)
            msg('Started Non-Linear Static Analysis', silent=silent)
            if self.NL_method is 'NR':
                _solver_NR(self)
            elif self.NL_method is 'arc_length':
                _solver_arc_length(self)
            else:
                raise ValueError('{0} is an invalid NL_method')

        else:
            msg('Started Linear Static Analysis', silent=silent)
            fext = self.calc_fext()
            k0 = self.calc_k0()

            if self.calc_k0_bc is not None:
                k0_bc = self.calc_k0_bc()
                k0max = k0.max()
                k0 /= k0max

                fextmax = fext.max()
                fext /= fextmax

                k0 = k0 + k0_bc

            c = solve(k0, fext)

            if self.calc_k0_bc is not None:
                k0 *= k0max
                fext *= fextmax

                c /= k0max
                c *= fextmax

            self.cs.append(c)
            self.increments.append(1.)
            msg('Finished Linear Static Analysis', silent=silent)

        self.last_analysis = 'static'

        return self.increments, self.cs
Beispiel #4
0
    def static(self, NLgeom=False, silent=False):
        """General solver for static analyses

        Selects the specific solver based on the ``NL_method`` parameter.

        Parameters
        ----------

        NLgeom : bool
            Flag to indicate whether a linear or a non-linear analysis is to
            be performed.
        silent : bool, optional
            A boolean to tell whether the log messages should be printed.

        """
        self.increments = []
        self.cs = []

        if NLgeom:
            self.maxInc = max(self.initialInc, self.maxInc)
            msg('Started Non-Linear Static Analysis', silent=silent)
            if self.NL_method is 'NR':
                _solver_NR(self, silent=silent)
            elif self.NL_method is 'arc_length':
                _solver_arc_length(self)
            else:
                raise ValueError('{0} is an invalid NL_method')

        else:
            msg('Started Linear Static Analysis', silent=silent)
            fext = self.calc_fext(silent=silent)
            k0 = self.calc_k0(silent=silent)

            c = solve(k0, fext, silent=silent)

            self.cs.append(c)
            self.increments.append(1.)
            msg('Finished Linear Static Analysis', silent=silent)

        self.last_analysis = 'static'

        return self.increments, self.cs
Beispiel #5
0
    def static(self, NLgeom=False, silent=False):
        """General solver for static analyses

        Selects the specific solver based on the ``NL_method`` parameter.

        Parameters
        ----------

        NLgeom : bool
            Flag to indicate whether a linear or a non-linear analysis is to
            be performed.
        silent : bool, optional
            A boolean to tell whether the log messages should be printed.

        """
        self.increments = []
        self.cs = []

        if NLgeom:
            self.maxInc = max(self.initialInc, self.maxInc)
            msg('Started Non-Linear Static Analysis', silent=silent)
            if self.NL_method is 'NR':
                _solver_NR(self, silent=silent)
            elif self.NL_method is 'arc_length':
                _solver_arc_length(self)
            else:
                raise ValueError('{0} is an invalid NL_method')

        else:
            msg('Started Linear Static Analysis', silent=silent)
            fext = self.calc_fext(silent=silent)
            k0 = self.calc_k0(silent=silent)

            c = solve(k0, fext, silent=silent)

            self.cs.append(c)
            self.increments.append(1.)
            msg('Finished Linear Static Analysis', silent=silent)

        self.last_analysis = 'static'

        return self.increments, self.cs
Beispiel #6
0
def _solver_NR(run, silent=False):
    """Newton-Raphson solver

    """
    msg('Initialization...', level=1, silent=silent)

    modified_NR = run.modified_NR
    inc = run.initialInc
    total = inc
    once_at_total = False
    max_total = 0.

    fext = run.calc_fext(inc=inc, silent=silent)
    k0 = run.calc_k0(silent=silent)
    c = solve(k0, fext, silent=silent)
    kT_last = k0

    if modified_NR:
        compute_kT = False
    else:
        compute_kT = True

    step_num = 1
    while True:
        msg('Started Load Step {} - '.format(step_num) +
            'Attempting time = {0}'.format(total),
            level=1,
            silent=silent)

        # TODO maybe for pdC=True, pdT the fext must be calculated with
        # the last kT available...

        absERR = 1.e6
        relERR = 1.e6
        min_Rmax = 1.e6
        prev_Rmax = 1.e6
        last_min_Rmax = 1.e6
        iteration = 0
        converged = False

        kT = kT_last

        fext = run.calc_fext(inc=total, silent=silent)

        iter_NR = 0
        while True:
            iteration += 1
            msg('Iteration: {}'.format(iteration), level=2, silent=silent)
            if iteration > run.maxNumIter:
                warn('Maximum number of iterations achieved!',
                     level=2,
                     silent=silent)
                break

            if compute_kT or (run.kT_initial_state and step_num == 1
                              and iteration
                              == 1) or iter_NR == (run.compute_every_n - 1):
                iter_NR = 0
                kT = run.calc_kT(c=c, inc=total, silent=silent)
            else:
                iter_NR += 1
                if not modified_NR:
                    compute_kT = True

            fint = run.calc_fint(c=c, inc=total, silent=silent)

            R = fext - fint

            # convergence criteria:
            # - maximum residual force Rmax
            Rmax = np.abs(R).max()
            msg('Rmax = {0}'.format(Rmax), level=3, silent=silent)

            if iteration >= 2 and Rmax < run.absTOL:
                converged = True
                break
            if (Rmax > prev_Rmax and Rmax > min_Rmax and iteration > 2):
                warn('Diverged!', level=2, silent=silent)
                break
            else:
                min_Rmax = min(min_Rmax, Rmax)
            change_rate_Rmax = abs(prev_Rmax - Rmax) / abs(prev_Rmax)
            if (iteration > 2 and change_rate_Rmax < run.too_slow_TOL):
                warn('Diverged! (convergence too slow)',
                     level=2,
                     silent=silent)
                break
            prev_Rmax = Rmax

            msg('Solving... ', level=2, silent=silent)
            delta_c = solve(kT, R, silent=silent)
            msg('finished!', level=2, silent=silent)

            eta1 = 0.
            eta2 = 1.
            if run.line_search:
                msg('Performing line-search... ', level=2, silent=silent)
                iter_line_search = 0
                while True:
                    c1 = c + eta1 * delta_c
                    c2 = c + eta2 * delta_c
                    fint1 = run.calc_fint(c=c1, inc=total, silent=silent)
                    fint2 = run.calc_fint(c=c2, inc=total, silent=silent)
                    R1 = fext - fint1
                    R2 = fext - fint2
                    s1 = delta_c.dot(R1)
                    s2 = delta_c.dot(R2)
                    eta_new = (eta2 - eta1) * (-s1 / (s2 - s1)) + eta1
                    eta1 = eta2
                    eta2 = eta_new
                    eta2 = min(max(eta2, 0.2), 10.)
                    if abs(eta2 - eta1) < 0.01:
                        break
                    iter_line_search += 1
                    if iter_line_search == run.max_iter_line_search:
                        eta2 = 1.
                        warn('maxinum number of iterations',
                             level=3,
                             silent=silent)
                        break
                msg('finished!', level=2, silent=silent)
            c = c + eta2 * delta_c

        if converged:
            msg('Finished Load Step {} at'.format(step_num) +
                ' time = {0}'.format(total),
                level=1,
                silent=silent)
            run.increments.append(total)
            run.cs.append(c.copy())  #NOTE copy required
            finished = False
            if abs(total - 1) < 1e-3:
                finished = True
            else:
                factor = 1.1
                if once_at_total:
                    inc_new = min(factor * inc, run.maxInc, (1. - total) / 2)
                else:
                    inc_new = min(factor * inc, run.maxInc, 1. - total)
                msg('Changing time increment from {0:1.9f} to {1:1.9f}'.format(
                    inc, inc_new),
                    level=1,
                    silent=silent)
                inc = inc_new
                total += inc
                total = min(1, total)
                step_num += 1
            if finished:
                break
            if modified_NR:
                msg('Updating kT...', level=1, silent=silent)
                kT = run.calc_kT(c=c, inc=total, silent=silent)
                msg('kT updated!', level=1, silent=silent)
            compute_kT = False
            kT_last = kT
        else:
            max_total = max(max_total, total)
            while True:
                factor = 0.3
                msg('Bisecting time increment from {0} to {1}'.format(
                    inc, inc * factor),
                    level=1,
                    silent=silent)
                if abs(total - 1) < 1e-3:
                    once_at_total = True
                total -= inc
                inc *= factor
                if inc < run.minInc:
                    msg('Minimum step size achieved!', level=1, silent=silent)
                    break
                total += inc
                if total >= max_total:
                    continue
                else:
                    break
            if inc < run.minInc:
                msg('Stopping solver: minimum step size achieved!',
                    level=1,
                    silent=silent)
                break

        if len(run.cs) > 0:
            c = run.cs[-1].copy()  #NOTE copy required
        else:
            # means that run bisection must be done in initialInc
            fext = run.calc_fext(inc=inc, silent=silent)
            c = solve(k0, fext, silent=silent)

    msg('Finished Non-Linear Static Analysis', silent=silent)
    msg('at time {0}'.format(total), level=1, silent=silent)
def _solver_NR(a):
    """Newton-Raphson solver

    """
    msg('Initialization...', level=1)

    modified_NR = a.modified_NR
    inc = a.initialInc
    total = inc
    once_at_total = False
    max_total = 0.

    fext = a.calc_fext(inc=inc)
    k0 = a.calc_k0()
    c = solve(k0, fext)
    kT_last = k0

    if modified_NR:
        compute_kT = False
    else:
        compute_kT = True

    step_num = 1
    while True:
        msg('Started Load Step {} - '.format(step_num)
            + 'Attempting time = {0}'.format(total), level=1)

        # TODO maybe for pdC=True, pdT the fext must be calculated with
        # the last kT available...

        absERR = 1.e6
        relERR = 1.e6
        min_Rmax = 1.e6
        prev_Rmax = 1.e6
        last_min_Rmax = 1.e6
        iteration = 0
        converged = False

        kT = kT_last

        fext = a.calc_fext(inc=total)

        iter_NR = 0
        while True:
            iteration += 1
            msg('Iteration: {}'.format(iteration), level=2)
            if iteration > a.maxNumIter:
                warn('Maximum number of iterations achieved!', level=2)
                break

            if compute_kT or (a.kT_initial_state and step_num==1 and
                    iteration==1) or iter_NR==(a.compute_every_n-1):
                iter_NR = 0
                kT = a.calc_kT(c, inc=total)
            else:
                iter_NR += 1
                if not modified_NR:
                    compute_kT = True

            fint = a.calc_fint(c=c, inc=total)

            R = fext - fint

            # convergence criteria:
            # - maximum residual force Rmax
            Rmax = np.abs(R).max()
            msg('Rmax = {0}'.format(Rmax), level=3)

            if iteration >= 2 and Rmax < a.absTOL:
                converged = True
                break
            if (Rmax > prev_Rmax and Rmax > min_Rmax and iteration > 2):
                warn('Diverged!', level=2)
                break
            else:
                min_Rmax = min(min_Rmax, Rmax)
            change_rate_Rmax = abs(prev_Rmax-Rmax)/abs(prev_Rmax)
            if (iteration > 2 and change_rate_Rmax < a.too_slow_TOL):
                warn('Diverged! (convergence too slow)', level=2)
                break
            prev_Rmax = Rmax

            msg('Solving... ', level=2)
            delta_c = solve(kT, R)
            msg('finished!', level=2)

            eta1 = 0.
            eta2 = 1.
            if a.line_search:
                msg('Performing line-search... ', level=2)
                iter_line_search = 0
                while True:
                    c1 = c + eta1*delta_c
                    c2 = c + eta2*delta_c
                    fint1 = a.calc_fint(c1, inc=total)
                    fint2 = a.calc_fint(c2, inc=total)
                    R1 = fext - fint1
                    R2 = fext - fint2
                    s1 = delta_c.dot(R1)
                    s2 = delta_c.dot(R2)
                    eta_new = (eta2-eta1)*(-s1/(s2-s1)) + eta1
                    eta1 = eta2
                    eta2 = eta_new
                    eta2 = min(max(eta2, 0.2), 10.)
                    if abs(eta2-eta1) < 0.01:
                        break
                    iter_line_search += 1
                    if iter_line_search == a.max_iter_line_search:
                        eta2 = 1.
                        warn('maxinum number of iterations', level=3)
                        break
                msg('finished!', level=2)
            c = c + eta2*delta_c

        if converged:
            msg('Finished Load Step {} at'.format(step_num)
                + ' time = {0}'.format(total), level=1)
            a.increments.append(total)
            a.cs.append(c.copy()) #NOTE copy required
            finished = False
            if abs(total - 1) < 1e-3:
                finished = True
            else:
                factor = 1.1
                if once_at_total:
                    inc_new = min(factor*inc, a.maxInc, (1.-total)/2)
                else:
                    inc_new = min(factor*inc, a.maxInc, 1.-total)
                msg('Changing time increment from {0} to {1}'.format(
                    inc, inc_new), level=1)
                inc = inc_new
                total += inc
                total = min(1, total)
                step_num += 1
            if finished:
                break
            if modified_NR:
                msg('Updating kT...', level=1)
                kT = a.calc_kT(c, inc=total)
                msg('kT updated!', level=1)
            compute_kT = False
            kT_last = kT
        else:
            max_total = max(max_total, total)
            while True:
                factor = 0.3
                msg('Bisecting time increment from {0} to {1}'.format(
                    inc, inc*factor), level=1)
                if abs(total -1) < 1e-3:
                    once_at_total = True
                total -= inc
                inc *= factor
                if inc < a.minInc:
                    msg('Minimum step size achieved!', level=1)
                    break
                total += inc
                if total >= max_total:
                    continue
                else:
                    break
            if inc < a.minInc:
                msg('Stopping solver: minimum step size achieved!',
                        level=1)
                break

        if len(a.cs)>0:
            c = a.cs[-1].copy() #NOTE copy required
        else:
            # means that a bisection must be done in initialInc
            fext = a.calc_fext(inc=inc)
            c = solve(k0, fext)

    msg('Finished Non-Linear Static Analysis')
    msg('at time {0}'.format(total), level=1)