def solve(self, dt=0.01, tol=0.001, maxiter=50, t_max=2., t_load=1., node_to_plot=None, verbose=False, savefile='', savetextfile='', show=True, timelog=None, output_freq=1): headers = ['u_x', 'u_y', 'v_x', 'v_y', 'a_x', 'a_y', '||a||', 'time', 'loadfunc'] table = {key:[] for key in headers} if timelog: tlog = open(timelog, 'w') else: tlog = None dt = t_max / float(maxiter) t1 = time.clock() if timelog: tlog.write('Commencing initializing calculation\n') # Initialize local values els = self.elements nds = self.nodes for el in els: el.set_matrices() el.calc_normal_vectors() for nd in nds: nd.init_vals(maxiter) t2 = time.clock() if timelog: tlog.write('Initializing calculation total time = %g\n' % (t2 - t1)) # Iterate until convergence is reached for all elements itercount = 0 crits = [] node_data = [] while True: itercount += 1 crit = 0. if timelog: tlog.write('Starting iteration no. %d\n' % itercount) t1 = time.clock() for i, el in enumerate(els): if timelog: tlog.write('Calculating element no. %d\n' % (i + 1)) crit = max(crit, el.iterate(dt, itercount * dt / t_load, tlog, verbose=verbose)) for i, el in enumerate(els): if timelog: tlog.write('Writing nodal values element no. %d\n' % (i + 1)) el.write_next_vals() t2 = time.clock() if timelog: tlog.write('Iteration no. %d complete, total time taken = %g\n' % (itercount, t2 - t1)) crits.append(crit) if node_to_plot and ((itercount % output_freq) == 0): node_data.append((np.array(self.nodes[node_to_plot - 1].v_disp), np.array(self.nodes[node_to_plot - 1].v_velo), np.array(self.nodes[node_to_plot - 1].v_acce), )) table['||a||'].append(np.linalg.norm(np.hstack([nd.v_acce for nd in nds]))) table['loadfunc'].append(load_function(itercount * dt / t_load)) table['time'].append(itercount * dt) if crit < tol: if verbose: print 'Convergence reached in step no.%d: maximum criterium = %.10f' % (itercount, crit) # break else: if verbose: print 'Step no.%d: maximum criterium = %.10f' % (itercount, crit) if itercount == maxiter: print 'Maximum step count reached: maximum criterium = %.10f' % crit break acce_norm = np.linalg.norm(np.hstack([nd.v_acce for nd in nds])) print 'Acceleration norm upon calculation end = %.6f' % acce_norm if timelog: tlog.close() t_vals = np.array(table['time']) # plt.plot(t_vals, crits, label='Convergence criterium', linewidth=2.) if node_to_plot: fig = plt.figure() ax = fig.add_subplot(111) ax.plot(t_vals, [n[0][0] for n in node_data], label='u_x', linewidth=2.) ax.plot(t_vals, [n[0][1] for n in node_data], label='u_y', linewidth=2.) ax.plot(t_vals, [n[1][0] for n in node_data], label='v_x', linewidth=2.) ax.plot(t_vals, [n[1][1] for n in node_data], label='v_y', linewidth=2.) ax.plot(t_vals, [n[2][0] for n in node_data], label='a_x', linewidth=2.) ax.plot(t_vals, [n[2][1] for n in node_data], label='a_y', linewidth=2.) table['u_x'] = [n[0][0] for n in node_data] table['u_y'] = [n[0][1] for n in node_data] table['v_x'] = [n[1][0] for n in node_data] table['v_y'] = [n[1][1] for n in node_data] table['a_x'] = [n[2][0] for n in node_data] table['a_y'] = [n[2][1] for n in node_data] table['time'] = t_vals ax.legend(loc='lower left') if savetextfile: f = open(savetextfile, 'w') texttable = tbl.tabulate(zip(*[table[col] for col in headers]), headers=headers, tablefmt="orgtbl") f.write(texttable) f.close() if savefile: fig.savefig(savefile) if show: plt.show()
def init_vals(self, maxiter): # Init for dynamic relaxation tau = 1 / float(maxiter) self.F_g = load_function(tau) * np.array([0., -self.mass * GRAVITY]) self.v_acce[self.free_dofs] = load_function(tau) / self.mass * (self.F_ext + self.F_g)