def _damped_response(self,non_linear_damping=0.0):        
        SA0,SD0=self.undamped_response # retrieve undamped response
        assert len(SA0.shape)==3
        initial_damping=self.initial_damping # get initial damping
        damping_factor=non_linear_damping+initial_damping
        # get the reduction factors:
        Ra,Rv,Rd=calculate_reduction_factors(damping_factor)
        
        # maybe treat displacement sensitive as velocity sensitive:
        if self.csm_damping_regimes == CSM_DAMPING_REGIMES_USE_ALL:
            pass
        elif self.csm_damping_regimes == CSM_DAMPING_REGIMES_USE_RA_RV:
             Rd=Rv
        elif self.csm_damping_regimes == CSM_DAMPING_REGIMES_USE_RV:
             Ra=Rv
             Rd=Rv
        else:
            raise ValueError

        TAV,TVD = self.corner_periods # get corner periods
        assert len(TAV.shape) == 2
        assert len(TVD.shape) == 2     
        # damp the corner periods is flag is set:
        # (note this does not affect the original corner periods)
        assert Ra.shape[-1] == 1
        assert Rv.shape[-1] == 1
        assert len(Ra.shape) == 3
        assert len(Rv.shape) == 3
        if self.csm_damping_modify_Tav == CSM_DAMPING_MODIFY_TAV:
            #print 'damping',damping_factor
            #print 'TAV',TAV[:,0:5]
            #print 'Ra,Rv',Ra[:,0:5],Rv[:,0:5]
            TAV=TAV*(Ra[...,0]/Rv[...,0])
            #print 'TAV',TAV[:,0:5]

        periods=self.periods
        
        # update SA:  
        SA,SD = calculate_updated_demand(
            periods,SA0,SD0,Ra,Rv,Rd,TAV,TVD,
            csm_damping_use_smoothing=self.csm_damping_use_smoothing)
        # update capacity:
        SAcap=calculate_capacity(SD,self.capacity_parameters)
        return SA,SD,SAcap
 def _non_linear_damping(self,displacement):
     
     # Calculate the acceleration of the intersect point.
     displacement=displacement[:,:,newaxis]
     acceleration=calculate_capacity(displacement,
                                     self.capacity_parameters)
     assert acceleration.shape[-1]==1 # should not have periods
     # Get the right damping function.
     if self.csm_hysteretic_damping is 'trapeziodal':
         damping_function=trapazoid_damp   
     else:
         damping_function=nonlin_damp
         
     SA,SD=acceleration,displacement
     # calculate damping
     damping=damping_function(self.capacity_parameters,
                              self.kappa,SA,SD,self.csm_hysteretic_damping)
     damping[where(SA<0.00000000001)]=0
     return damping
    def building_response(self,SA):
        """Use the equivilant linear solver to solve 
        """
        rtol,maxits = self.rtol,self.csm_damping_max_iterations
        periods = self.periods
        magnitudes = self.magnitudes
        # building_parameters should already be compressed, or expanded.
        if True:
            # TODO: Allow hazus and aus standard response curves.
            # TODO: Allow cutoff after max.
            SA,surface_displacement = undamped_response(
                SA,periods,
                self.atten_override_RSA_shape,
                self.atten_cutoff_max_spectral_displacement,
                self.loss_min_pga,
                magnitude=magnitudes)
            self.undamped_response = SA,surface_displacement
        else: raise ValueError
        self.corner_periods = calculate_corner_periods(periods,SA,magnitudes)
        
        # set up initial conditions:
        update_function=self.updated_response
        SA,SD,SAcap=self._damped_response(non_linear_damping=0)
        assert len(SA.shape)==3

        #print "self.capacity_parameters", self.capacity_parameters
        #print "SAcap.tolist()[0][0]", SAcap.tolist()[0][0]
        #print "SA.tolist()[0][0]", SA.tolist()[0][0]
        #print "SD.tolist()[0][0]", SD.tolist()[0][0]
        # now solve
        SD_building,non_convergant = solve(SA,SD,SAcap,update_function,
                                           rtol=rtol,maxits=maxits)
        SA_building=calculate_capacity(SD_building[:,:,newaxis],
                                       self.capacity_parameters)
        assert SA_building.shape[-1]==1 # should not have periods
        assert len(SA_building.shape)==3 # should not have periods
        assert len(SD_building.shape)==2 # should not have periods
        SA_building=SA_building[...,0] # collapse out periods
        #print "cap_spec_mod SA_building,SD_building", SA_building,SD_building
        return SA_building,SD_building