Beispiel #1
0
class TModel(BMCSTreeNode):
    '''
    Base class of a time-stepping model capturing the state
    of a modeled object at the particular instance of time 
    supplying the predictor and corrector interface.

    The model includes the geometry, boundary conditions, 
    material characteristics, type of material behavior

    A model communicates with the time loop through their 
    common interface which depends on the particular type 
    of time-stepping scheme. In case of a time integration 
    scheme the control variable is represented by displacements,
    in case of an optimization problem, the function supplying 
    the values and gradients of response variables is required.
    In case of fragmentation problem, the model supplies 
    the array of load factors need to induce a crack in 
    a material point. 
    '''

    tloop_type = tr.Type(TLoop)
    '''Type of time loop to be used with the model
    '''

    tstep_type = tr.Type(TStep)
    '''Type of the time step to be used with the model
    '''
    def init_state(self):
        pass

    def record_state(self):
        pass
Beispiel #2
0
class Model(BMCSTreeNode):
    '''Contains the primary unknowns variables U_k
    '''
    tstep_type = tr.Type(TStep)
    tloop_type = tr.Type(TLoop)
    hist_type = tr.Type(Hist)
    sim_type = tr.Type(SimControler)

    tstep = tr.Property(depends_on='tstep_type')

    @tr.cached_property
    def _get_tstep(self):
        return self.tstep_type(model=self)

    tloop = tr.Property(depends_on='tloop_type')

    @tr.cached_property
    def _get_tloop(self):
        return self.tloop_type(tstep=self.tstep)

    hist = tr.Property(depends_on='hist_type')

    @tr.cached_property
    def _get_hist(self):
        return self.hist_type(model=self)

    sim = tr.Property(depends_on='sim_type')

    @tr.cached_property
    def _get_sim(self):
        return self.sim_type(model=self)

    bc = tr.List(tr.Callable)

    U_shape = tr.Tuple(1,)

    def init_state(self):
        self.U_k = np.zeros(self.U_shape, dtype=np.float)
        self.U_n = np.copy(self.U_n)
        self.hist.init_state()

    def get_plot_sheet(self):
        return

    U_k = tr.Array(np.float_, TRIAL_STATE=True)
    U_n = tr.Array(np.float_, FUND_STATE=True)

    S = tr.Dict(tr.Str, tr.Array(np.float), STATE=True)

    F = tr.Property(depends_on='+TRIAL_STATE,+INPUT')

    @tr.cached_property
    def _get_F(self):
        raise NotImplemented

    d_F_U = tr.Property(depends_on='+TRIAL_STATE,+INPUT')

    @tr.cached_property
    def _get_d_F_U(self):
        raise NotImplemented
Beispiel #3
0
class TStepBC(TStep):

    tloop_type = tr.Type(TLoopImplicit)

    primary_var_changed = tr.Event

    def __init__(self, *args, **kw):
        super().__init__(*args, **kw)
        self.fe_domain

    #=========================================================================
    # Time and state
    #=========================================================================

    t_n = tr.Float(0.0)
    '''Fundamental state time used for time dependent essential BC'
    '''
    U_n = tr.Property(tr.Array(np.float_),
                      depends_on='model_structure_changed')
    '''Fundamental value of the primary (control variable)
    '''
    @tr.cached_property
    def _get_U_n(self):
        return np.zeros_like(self.U_k)

    '''Current fundamental value of the primary variable.
    '''
    U_k = tr.Property(tr.Array(np.float_),
                      depends_on='model_structure_changed')
    '''Fundamental value of the primary (control variable)
    '''
    @tr.cached_property
    def _get_U_k(self):

        U_var_shape = self.fe_domain.U_var_shape
        return np.zeros(U_var_shape, dtype=np.float_).flatten()

    model_structure_changed = tr.Event

    bc = tr.List
    r'''Boundary conditions
    '''
    record = tr.Dict
    r'''Recorded variables
    '''

    # Boundary condition manager
    #
    bcond_mngr = tr.Property(tr.Instance(BCondMngr),
                             depends_on='bc,bc_items,model_structure_changed')

    @tr.cached_property
    def _get_bcond_mngr(self):
        return BCondMngr(bcond_list=self.bc)

    def init_state(self):
        '''Initialize state.
        '''
        self.t_n = 0.0
        self.t_n1 = 0.0
        self.model_structure_changed = True

    step_flag = tr.Enum('predictor', 'corrector')
    '''Step flag to control the inclusion of essential BC'
    '''
    @tr.on_trait_change('model_structure_changed')
    def _reset(self):
        self.step_flag = 'predictor'

    K = tr.Property(
        tr.Instance(SysMtxAssembly),
        depends_on='model_structure_changed'
    )
    '''System matrix with registered essencial boundary conditions.
    '''
    @tr.cached_property
    def _get_K(self):
        K = SysMtxAssembly()
        self.bcond_mngr.setup(None)
        self.bcond_mngr.register(K)
        return K

    #=========================================================================
    # Spatial domain
    #=========================================================================
    domains = tr.List([])
    r'''Spatial domain represented by a finite element discretization.
    providing the kinematic mapping between the linear algebra (vector and
    matrix) and field representation of the primary variables.
    '''

    fe_domain = tr.Property(depends_on='model_structure_changed')

    @tr.cached_property
    def _get_fe_domain(self):
        domains = [
            DomainState(tstep=self, xdomain=xdomain, tmodel=tmodel)
            for xdomain, tmodel in self.domains
        ]
        return XDomain(domains)

    corr_pred = tr.Property(depends_on='primary_var_changed,t_n1')

    @tr.cached_property
    def _get_corr_pred(self):
        self.K.reset_mtx()
        f_Eis, K_ks, dof_Es = np.array(
            [s.get_corr_pred(self.U_k, self.t_n, self.t_n1)
             for s in self.fe_domain]
        ).T
        self.K.sys_mtx_arrays = list(K_ks)  # improve
        F_ext = np.zeros_like(self.U_k)
        self.bcond_mngr.apply(
            self.step_flag, None, self.K, F_ext, self.t_n, self.t_n1
        )
        F_int = np.bincount(
            np.hstack(np.hstack(dof_Es)),
            weights=np.hstack(np.hstack(f_Eis))
        )
        R = F_ext - F_int
        self.K.apply_constraints(R)
        if self.debug:
            print('t_n1', self.t_n1)
            print('U_k\n', self.U_k)
            print('F_int\n', F_int)
            print('F_ext\n', F_ext)
        return R, self.K, F_int

    def make_iter(self):
        '''Perform a single iteration
        '''
        d_U_k, pos_def = self.K.solve(check_pos_def=True)
        if self.debug:
            print('positive definite', pos_def)
        self.U_k[:] += d_U_k
        self.primary_var_changed = True
        self.step_flag = 'corrector'

    def make_incr(self):
        '''Update the control, primary and state variables..
        '''
        self.U_n[:] = self.U_k[:]
        states = [d.record_state() for d in self.fe_domain]
        self.hist.record_timestep(self.t_n1, self.U_k, self.F_k, states)
        self.t_n = self.t_n1
        self.step_flag = 'predictor'

    def __str__(self):
        s = '\nt_n: %g, t_n1: %g' % (self.t_n, self.t_n1)
        s += '\nU_n' + str(self.U_n)
        s += '\nU_k' + str(self.U_k)
        return s

    R_norm = tr.Property

    def _get_R_norm(self):
        R = self.R
        return np.sqrt(np.einsum('...i,...i', R, R))

    R = tr.Property

    def _get_R(self):
        R, _, _ = self.corr_pred
        return R.flatten()

    dR = tr.Property

    def _get_dR(self):
        _, dR, _ = self.corr_pred
        return dR

    F_k = tr.Property

    def _get_F_k(self):
        _, _, F_k = self.corr_pred
        return F_k
Beispiel #4
0
class TStep(tr.HasStrictTraits):
    '''Manage the data and metadata of a time step within an interation loop.
    '''
    title = tr.Str('<unnamed>')

    tloop_type = tr.Type(ITLoop)
    '''Type of time loop to be used with the model
    '''

    #=========================================================================
    # HISTORY
    #=========================================================================
    hist_type = tr.Type(Hist)

    hist = tr.Property(tr.Instance(IHist))
    r'''History representation of the model response.
    '''
    @tr.cached_property
    def _get_hist(self):
        return self.hist_type(tstep_source=self)

    debug = tr.Bool(False)

    t_n1 = tr.Float(0.0, auto_set=False, enter_set=True)
    '''Target value of the control variable.
    '''
    U_n = tr.Float(0.0, auto_set=False, enter_set=True)
    '''Current fundamental value of the primary variable.
    '''
    U_k = tr.Float(0.0, auto_set=False, enter_set=True)
    '''Current trial value of the primary variable.
    '''

    def init_state(self):
        '''Initialize state.
        '''
        self.U_n = 0.0
        self.t_n1 = 0.0
        self.U_k = 0.0

    def record_state(self):
        '''Provide the current state for history recording.
        '''
        pass

    _corr_pred = tr.Property(depends_on='U_k,t_n1')

    @tr.cached_property
    def _get__corr_pred(self):
        return self.get_corr_pred(self.U_k, self.t_n1)

    R = tr.Property

    def _get_R(self):
        R, _ = self._corr_pred
        return R

    dR = tr.Property

    def _get_dR(self):
        _, dR = self._corr_pred
        return dR

    R_norm = tr.Property

    def _get_R_norm(self):
        R = self.R
        return np.sqrt(R * R)

    def make_iter(self):
        d_U = self.R / self.dR
        self.U_k += d_U

    def make_incr(self):
        '''Update the control, primary and state variables..
        '''
        self.U_n = self.U_k
        # self.hist.record_timestep()

    sim = tr.Property()
    '''Launch a simulator - currently only one simulator is allowed
    for a model. Mutiple might also make sense when different solvers
    are to be compared. The simulator pulls the time loop type
    from the model.
    '''

    @tr.cached_property
    def _get_sim(self):
        return Simulator(tstep=self)