def __init__(self, MBD_system, parent=None): """ Constructor """ super(KinematicAnalysis, self).__init__(MBD_system, parent) # parent self._parent = parent # DAE fun object self.DAE_fun = DAEfun(self._MBD_system, parent=self)
def solve(self): """ Euler method for time integration :param t_0: :param t_n: :param q0: :param h: """ # solution containers self._solution_containers() # copy MBD object self._MBD_system = copy.copy(self.MBD_system) # ode fun object self.DAE_fun = DAEfun(self._MBD_system, parent=self) self.start_solve() self.start_time_simulation_info_in_sec_UTC = time.time() self.start_time_simulation_info = datetime.datetime.fromtimestamp(self.start_time_simulation_info_in_sec_UTC).strftime("%H:%M:%S %d.%m.%Y") print "Simulation started: ", self.start_time_simulation_info # create array of initial conditions for differential equations # get initial conditions q0 = self._MBD_system.evaluate_q0() self.FLAG = 1 self.simulation_id = 0 # 0 - no contact # +1 - contact detected # -1 - contact already happened - reduce integration step self.step = 0 self.h_contact = self._MBD_system.Hmin self._append_to_file_step = 0 # constant time step vector self.t_constant_time_step = np.arange(0, self._MBD_system.t_n + self._MBD_system.Hmax, self._MBD_system.Hmax) self.t_level = 0 self.t_0 = self._dt = self._MBD_system.t_0 self.t_n = self._MBD_system.t_n t = self.t_0 w = q0 self.Hmax = h = self._MBD_system.Hmax self.R = 0 while self.FLAG == 1: if self.stopped: self.refresh(t=t, q=w) self.stop_solve() self.FLAG = 0 if t >= self.t_n: self.FLAG = 0 self.finished = True self.refresh(t=t, q=w) self.t = t = t + h self.h = h # print "-------------------------------------" # print self.t, t, h # error control self.absError = self.evaluate_error(self.t, self.h) if self.absError <= self.absTol: w = w + h * self.DAE_fun.evaluate_dq(t, w) # solve contacts self.FLAG_contact = self._evaluate_contacts(t, w) # evaluate mechanical energy of system self._energy_t = self._mechanical_energy(w) self._energy_delta = self._energy_t - self._solution_data._energy_solution_container[-1] else: self.t = t = t - h self.h = h / 2. # track data h, t, w = self._track_data(h, t, w) # simulation informations self._info(t, w) # check time step h, self._error = self.check_time_step(t, h, w) if self.finished or self.failed or self.stopped: self.finished_solve() # save data to file # if self.MBD_system._solution_save_options.lower() != "discard": self.write_simulation_solution_to_file()
def create_DAE(self): """ :return: """ self.DAE_fun = DAEfun(self.MBD_system, parent=self)
def __init__(self, MBD_system, parent=None): """ Constructor """ # super(DynamicAnalysis, self).__init__(parent) # parent self._parent = parent # states of simulation self.running = False self.stopped = False self.finished = False self.failed = False self._error = False self.errorControl = True # signals self.step_signal = StepSignal() self.finished_signal = FinishedSignal() self.refresh_signal = RefreshSignal() self.energy_signal = EnergySignal() self.error_time_integration_signal = ErrorTimeIntegrationSignal() self.filename_signal = SolutionFilenameSignal() self.save_screenshot_signal = SaveScreenshot() self.solution_signal = SolutionSignal() self.signal_simulation_status = SignalSimulationStatus() # display active self._active_scene = True # MBD system object self.MBD_system = MBD_system # copy MBD object self._MBD_system = copy.copy(self.MBD_system) # DAE fun object self.DAE_fun = DAEfun(self._MBD_system, parent=self) # define simulation attributes self.simulation_id = None self.h_contact = None self.t_0 = 0. self.t_n = None self.stepsNumber = None self.absTol = None self.relTol = None self.absError = None self.relError = None self.progress = 0 self._energy_t = 0. self._energy_delta = 0. self.h_min_level = None self.h_max_level = None self.h_contact_level = None # simulation settings - properties # self.integrationMethod = "RKF" # self.MBD_system.integrationMethod # update opengl widget every N-th step self._dt = self.MBD_system._dt self.step = 0 self.t = 0. self.update_opengl_widget_step_count = 0 self.update_opengl_widget_every_Nth_step = self.MBD_system.updateEveryIthStep self.t_constant_time_step = None self.save_screenshot_step_count = 0 self.save_screenshot_every_Nth_step = 2 * self.update_opengl_widget_every_Nth_step # info properties self.start_time_simulation_info_in_sec_UTC = [] self.start_time_simulation_info = [] self.end_time_simulation_info_in_sec_UTC = [] self.end_time_simulation_info = [] self.simulation_time_info_in_sec_UTC = [] self.simulation_time_info = [] self.stop_time_simulation_info_in_sec_UTC = [] self.stop_time_simulation_info = [] self.FLAG = 1 self.FLAG_contact = 0 self.FLAG_contact_finish = 0 # level of integration step size - time self.h_level = 0 self.dh = 0 self._steps_after_contact = 0 self._dh_constant_steps = 0 # solution data settings # write to file during simulation self._append_to_file_every_Nth_step = 20 self._append_to_file_step = 0 self._append_to_file_during_simulation = True self._append_to_file_keep_last_Nth_steps_in_memory = 10
def solve(self, q0=[], t_n=None, absTol=1E-9, maxIter=10): """ :return: """ # redefine solution containers self._solution_containers() # copy MBD object self.MBD_system.setSolver(self) # self._MBD_system = copy.copy(self.MBD_system) self._MBD_system = self.MBD_system # set solver self._MBD_system.setSolver(self) # ode fun object self.DAE_fun = DAEfun(self._MBD_system, parent=self) self.start_solve() self.beta = self.evaluate_beta(self.alpha) self.gamma = self.evaluate_gamma(self.alpha) self.t_n = t_n if self.t_n is not None and self.stepsNumber is not None: self.Hmax = self.t_n / self.stepsNumber if q0: self.q0 = q0 if t_n is not None: self.t_n = t_n self.h = h = self.Hmax t = self.t_0 w = self.q0 q = self.get_q(w) while self.FLAG == 1 and not self._error and not self.DAE_fun.error: self.h = h K1 = w + 0.5 * h * self.DAE_fun.evaluate_dq(t, w) w0 = K1 i_iter = 0 self.FLAG_iter = 0 while self.FLAG_iter == 0: w = w0 - ( (w0 - (0.5 * h * self.DAE_fun.evaluate_dq(t + h, w0)) - K1) / (1. - 0.5 * h * self.DAE_fun.evaluate_Jacobian(t + h, w0))) self.absError = self.evaluate_error(w0, w) #optimize.newton(f, x0, fprime=None, args=(y,), tol=1.48e-08, maxiter=50) if self.absError < self.absTol: self.FLAG_iter = 1 else: i_iter += 1 w0 = w if i_iter > maxIter: raise ValueError, "The maximum number of iterations exceeded" break if (t >= self.t_n) or (self.step == self.stepsNumber): self.FLAG = 0 self.finished = True self.refresh(t=t, q=w) else: t = t + h # track - store simulation state data of different MBD system objects h, t, w = self._track_data(h, t, w)
def solve(self, q0=[], t_n=None, absTol=1E-9): """ Solves system of ode with order 5 method with runge-kutta algorithm """ # redefine solution containers self._solution_containers() # copy MBD object if hasattr(self.MBD_system, "setSolver"): self.MBD_system.setSolver(self) self._MBD_system = self.MBD_system # set solver self._MBD_system.setSolver(self) # dae fun object if self.DAE_fun is None: self.DAE_fun = DAEfun(self._MBD_system, parent=self) if q0: self.q0 = q0 self.start_solve() # create array of initial conditions for differential equations # get initial conditions if hasattr(self._MBD_system, "q0"): self._MBD_system.q0 = self.q0 if t_n is not None: self.t_n = t_n # evaluate stiffness matrix if hasattr(self.DAE_fun, "evaluate_K"): self.DAE_fun.evaluate_K(self.q0) self.simulation_id = 0 # 0 - no contact # +1 - contact detected # -1 - contact already happened - reduce integration step self.step = 0 if hasattr(self._MBD_system, "Hmin"): self.h_contact = self._MBD_system.Hmin self._append_to_file_step = 0 self.t_0 = self._dt = 0 self.FLAG = 1 if hasattr(self._MBD_system, "t_n"): if self._MBD_system.t_n is not None: self.t_n = self._MBD_system.t_n if hasattr(self._MBD_system, "stepsNumber"): self.stepsNumber = self._MBD_system.stepsNumber t = self.t_0 w = self.q0 if self.t_n is None and self.stepsNumber is not None: self.t_n = np.inf # logging.getLogger("DyS_logger").info("Size of MBD system in bytes %s" % sys.getsizeof(self.MBD_system)) logging.getLogger("DyS_logger").info( "Simulation started with initial conditions q0:\n%s" % self.q0) h = self.Hmax self._t_FLAG1 = self.Hmax # print "absTol =", absTol # self.update_opengl_widget_every_Nth_step = 1*((t_n - t_0)/Hmax) # print "self.update_opengl_widget_every_Nth_step =", self.update_opengl_widget_every_Nth_step self.save_updated_screenshot_to_file(self.t_0) # np.set_printoptions(precision=20, threshold=1000, edgeitems=True, linewidth=1000, suppress=False, formatter={'float': '{: 10.9e}'.format}) while self.FLAG == 1 and not self._error and not self.DAE_fun.error: # time.sleep(.001) # if self.step > 1415: # print "----------------------" # print "step =", self.step, "t =", t, "h =", h#"self.FLAG_contact =", self.FLAG_contact # print "step =", self.step, "h =", h, "t =", t # print "step =", self.step self.h = h self.t = t # print "self.h =", self.h K1 = h * self.DAE_fun.evaluate_dq(t, w) K2 = h * self.DAE_fun.evaluate_dq(t + (1. / 4.) * h, w + (1. / 4.) * K1) K3 = h * self.DAE_fun.evaluate_dq( t + (3. / 8.) * h, w + (3. / 32.) * K1 + (9. / 32.) * K2) K4 = h * self.DAE_fun.evaluate_dq( t + (12. / 13.) * h, w + (1932. / 2197.) * K1 - (7200. / 2197.) * K2 + (7296. / 2197.) * K3) K5 = h * self.DAE_fun.evaluate_dq( t + h, w + (439. / 216.) * K1 - 8. * K2 + (3680. / 513.) * K3 - (845. / 4104.) * K4) K6 = h * self.DAE_fun.evaluate_dq( t + (1. / 2.) * h, w - (8. / 27.) * K1 + 2. * K2 - (3544. / 2565.) * K3 + (1859. / 4104.) * K4 - (11. / 40.) * K5) w_new = self._evaluate_w_new(w, K1, K2, K3, K4, K5, K6) # self.absError = (1. / h) * np.linalg.norm((1. / 360.) * K1 - (128. / 4275.) * K3 - (2197. / 75240.) * K4 + (1. / 50.) * K5 + (2. / 55.) * K6) # self.absError = self.evaluate_error_HHT_I3(w, w_new, K1, K2, K3, K4, K5, K6) self.absError = self.evaluate_absError(w, w_new) #self.absError = (1. / h) * np.linalg.norm((1. / 360.) * K1 - (128. / 4275.) * K3 - (2197. / 75240.) * K4 + (1. / 50.) * K5 + (2. / 55.) * K6) #self.absError = 0.1*self.absTol # self.R = absTol # print "E_RKF45 =", self.evaluate_error_RKF45(K1, K2, K3, K4, K5, K6), "E_HHT_I3 =", self.absError # if calculated difference is less the absolute tolerance limit and accept the calculated solution # if not self.errorControl: # self.absError = self.absTol # if (self.absError <= self.absTol) and (self.FLAG_contact in [0, 1]): # print "self.check_error() =", self.check_error() # solve contacts self.FLAG_contact = self._evaluate_contacts(t, w_new) if not self.check_error(): #and (self.FLAG_contact in [0, 1]) # next time point self.t = t = t + h # value of vector of variables at next time step w = w_new if self.FLAG_contact in [0, 1]: # evaluate mechanical energy of system self._mechanical_energy, self._kinetic_energy, self._potential_energy, self._elastic_strain_energy = self._evaluate_mechanical_energy( w) self._energy_delta = self.evaluate_energy_delta( self._mechanical_energy) else: self.t, self.step, self._mechanical_energy, self._energy_delta = self._use_last_accapted_solution( t, self.step) else: self.t, self.step, self._mechanical_energy, self._energy_delta = self._use_last_accapted_solution( t, self.step) t = self.t # w = w # self.step = self.step # self._mechanical_energy = 0. # self._energy_delta = 0. # track - store simulation state data of different MBD system objects # print "h1 =", h h, t, w = self._track_data(h, t, w) # print "h2 =", h # check time step if self.errorControl: h, self._error = self.check_time_step(t, h, w, R=self.absError) else: print UserWarning, "Error control dissabled! Results may be wrong!" self._error = False # print "h3 =", h # process information of integration process if not self.check_error() and (self.FLAG_contact in [ 0, 1 ]) and self.update_visualization_widget: self._info(t, w) # check if finished if (t >= self.t_n) or (self.step == self.stepsNumber): self.FLAG = 0 self.finished = True self.refresh(t=t, q=w) # integration finished - end time reached successfully if self.finished or self.failed: self.refresh(t=t, q=w) self.finished_solve() self.FLAG = 0 if self.stopped: self.refresh(t=t, q=w) self.stop_solve() self.FLAG = 0 if np.isnan(t): self._error = True self.failed = True print "t is NaN! Check Hmax!" if self._error or self.failed or self.simulation_error.error: print "self._error =", self._error print "self.failed =", self.failed print "self.DAE_fun.error =", self.DAE_fun.error self.simulation_failed() print self.simulation_error.info print Warning, "Simulation failed!" # save data to file if self.write_to_file: self.write_simulation_solution_to_file()