def heat_diffusion(): D = 0.54 # heat diffusion coefficient f = dirac(1., 1.) # discretize domain Vh1 = DiscreteDomain.from_file('resources/piece-1border.msh', labels={ 'Omega': 10, 'Gamma': 1 }) Vh2 = DiscreteDomain.from_file('resources/piece-2borders.msh', labels={ 'Omega': 10, 'Gamma_N': 1, 'Gamma_D': 2 }) # prepare variational formulations Problem1 = VariationalFormulation.from_str( 'u,v:int2d(Vh1)(D*grad{u}*grad{v}) - int2d(Vh1)(f*v)' \ '+ on(1, 10)', locals()) Problem2 = VariationalFormulation.from_str( 'u,v:int2d(Vh2)(D*grad{u}*grad{v}) - int2d(Vh2)(f*v)' \ '+ on(2, 10)', locals()) # solve equations u1 = Problem1.solve() u2 = Problem2.solve() plot(Vh1, u1, show_labels=True, to_file='heat-diffusion1.jpg', value=False) plot(Vh2, u2, show_labels=True, to_file='heat-diffusion2.jpg', value=False)
def _time_dependent(scheme): u0 = lambda x, y: np.sin(np.pi * x) * np.sin(np.pi * y) f = lambda x, y, t: (2 * np.pi * np.pi - 1) * np.exp(-t) * np.sin( np.pi * x) * np.sin(np.pi * y) Vh = DiscreteDomain.rectangle(1, 1, n_points=8) Tmax = 1 dt = 5e-4 n_iter = int(Tmax / dt) + 1 init_u = u0(*Vh.points).reshape((Vh.Nv, 1)) if scheme == 'euler-exp': Scheme = EulerExplicit(init_u, Vh, dt=dt, f=f, dirichlet=(1, 0.)) all_u = Scheme.solve(n_iter, all_solutions=True) iter_u = all_u[::20] make_animation('heat-euler-exp.mp4', [Vh] * len(iter_u), iter_u, dim=3) elif scheme == 'euler-imp': Scheme = EulerImplicit(init_u, Vh, dt=dt, f=f, dirichlet=(1, 0.)) all_u = Scheme.solve(n_iter, all_solutions=True) iter_u = all_u[::20] make_animation('heat-euler-imp.mp4', [Vh] * len(iter_u), iter_u, dim=3) elif scheme == 'cn': Scheme = CrankNicholson(init_u, Vh, dt=dt, f=f, dirichlet=(1, 0.)) all_u = Scheme.solve(n_iter, all_solutions=True) iter_u = all_u[::20] make_animation('heat-cn.mp4', [Vh] * len(iter_u), iter_u, dim=3)
def wifi_diffusion(): f = dirac(0.1, 0.1, bounds=[0.05, 2.95, 0.05, 1.95]) frequency = 2.4e9 k = 2 * np.pi * frequency / 3e8 n = 2.4 + 0.01j # discretize domain Vh = DiscreteDomain.from_file('resources/room.msh', labels={ 'OmegaAir': 10, 'OmegaWall': 11, 'Gamma': 1 }) # prepare variational formulation Problem = VariationalFormulation(Vh, [('RIGIDITY', Vh, -1.), ('MASS', Vh('OmegaAir'), k * k), ('MASS', Vh('OmegaWall'), n * n * k * k), ('MASS', Vh('Gamma'), 1j * k * n)], [(Vh, f)]) # solve equation u = Problem.solve() # plot result save_to_vtk('wifi-solution.vtu', Vh, u) plot(Vh, u, cmap='gnuplot', value=False, figscale=(2, 1), to_file='wifi.jpg')
def chemicals_propagation(): f = lambda x, y: 0. w = np.array([-0.01, 0.]) # discretize domain Vh = DiscreteDomain.rectangle(200, 5, n_points=60, n_borders=4, labels={ 'Omega': 10, 'Gamma_U': 2, 'Gamma_C': 4 }) # prepare variational formulation Problem = VariationalFormulation.from_str( 'u,v : int2d(Vh)(grad{u}*grad{v}) + int2d(Vh)(w*u*grad{v})' \ '- int2d(Vh)(f*v) + on(2, 10)', locals() ) # solve equation u = Problem.solve() # plot result plot(Vh(10, 2, 4), u, cmap='viridis', figscale=(2, 1), show_labels=True, title='Chemicals propagation in a river')
def load_primitive(self): """Creates a DiscreteDomain instance with a primitive reference.""" selected = self.domain_cur_primitive if selected is None: return b = int(self.domain_primitives_borders.get()) if selected == 'Line': length = float(self.domain_param1.get()) step = int(self.domain_param2.get()) self.discrete_domain = DiscreteDomain.line(length, step=step, nb_borders=b) elif selected == 'Rectangle': xsize = float(self.domain_param1.get()) ysize = float(self.domain_param2.get()) step = int(self.domain_param3.get()) self.discrete_domain = DiscreteDomain.rectangle(xsize, ysize, step=step, nb_borders=b) elif selected == 'Circle': radius = float(self.domain_param1.get()) astep = int(self.domain_param2.get()) rstep = int(self.domain_param3.get()) self.discrete_domain = DiscreteDomain.circle(radius, astep=astep, rstep=rstep, nb_borders=b) elif selected == 'Ring': iradius = float(self.domain_param1.get()) oradius = float(self.domain_param2.get()) if iradius > oradius: Logger.slog('ERROR: cannot initialize "Ring" primitive with ' 'Inner Radius > Outer Radius.') return astep = int(self.domain_param3.get()) rstep = int(self.domain_param4.get()) self.discrete_domain = DiscreteDomain.ring(iradius, oradius, astep=astep, rstep=rstep, nb_borders=b) self.reset_problem() self.domain_reference = '_Primitive_' self.set_figure()
def basefunc(): for fe_type in ['P1', 'P2', 'P3']: Vh = DiscreteDomain.from_file('resources/square-simple.msh', fe_type=fe_type) bf = Vh.base_functions t = ['Phi_' + str(i) for i in range(Vh.Nv)] # plot titles make_animation('base_functions-{}.mp4'.format(fe_type), [Vh] * len(bf), bf, t, fps=10, use_subtriangulation=True, show_triangulation=True)
def error_analysis(): f = lambda x, y: (2 * np.pi * np.pi + 1) * np.sin(np.pi * x) * np.sin(np.pi * y) u_ex = lambda x, y: np.sin(np.pi * x) * np.sin(np.pi * y) norm = 'L2' errors = InterpolationError(norm) # create the object to store the errors size = 1 # study the error for several finite elements and several discretization # n_pointss for n_points in range(5, 35, 5): # discretize domain with 2 types of finite elements Vh1 = DiscreteDomain.rectangle(size, size, n_points=n_points, fe_type='P1') Vh2 = DiscreteDomain.rectangle(size, size, n_points=n_points, fe_type='P2') # prepare 1st variational formulation Problem1 = VariationalFormulation(Vh1, [('RIGIDITY', Vh1), ('MASS', Vh1)], [(Vh1, f)], dirichlet=(1, 0.)) # prepare 2nd variational formulation Problem2 = VariationalFormulation(Vh2, [('RIGIDITY', Vh2), ('MASS', Vh2)], [(Vh2, f)], dirichlet=(1, 0.)) # solve equation u1 = Problem1.solve() u2 = Problem2.solve() # get exact solution reference u_exact1 = u_ex(*Vh1.points) u_exact2 = u_ex(*Vh2.points) # compute L2 error h = size / n_points errors[h] = Vh1.error(u1, u_exact1, h, norm=norm) errors[h] = Vh2.error(u2, u_exact2, h, norm=norm) # output to table and graph errors.output(compare_order=[1, 2]) errors.plot(compare_order=[1, 2])
def acoustic_diffraction_simple(): # create discrete domain Vh = DiscreteDomain.ring(0.5, 1.0, an_points=40, rn_points=20, n_borders=2, labels={ 'Omega': 10, 'GammaInt': 1, 'GammaExt': 2 }) _acoustic_diffraction(Vh)
def load_mesh(self): """Creates a DiscreteDomain instance with a file reference.""" self.reset_problem() file_reader = filedialog.askopenfilename(title='Choose a mesh file:') if len(file_reader) > 0: # if necessary, reset primitive-linked variables for child in self.domain_params.winfo_children(): child.destroy() self.domain_cur_primitive = None # read file into a new instance self.domain_reference = file_reader self.discrete_domain = DiscreteDomain.from_file(file_reader) self.set_figure()
def poisson_robin(): f = lambda x, y: (2 * np.pi * np.pi + 1) * np.sin(np.pi * x) * np.sin(np.pi * y) # discretize domain Vh = DiscreteDomain.rectangle(1, 1, n_points=20, n_borders=4) # prepare variational formulation Problem = VariationalFormulation(Vh, [('RIGIDITY', Vh), ('MASS', Vh(1), -10.)], [(Vh, f), (Vh(1), lambda x, y: np.cos(y))], dirichlet=(2, 3, 4, 0.)) # solve equation u = Problem.solve() # plot result plot(Vh, u, cmap='CMRmap', dim=3)
def wave_interference(): k = 1.5 * np.pi f = FunctionalFunction(dirac(1., 2., tol=0.1)) + FunctionalFunction( dirac(5., 2., tol=0.1)) # discretize domain Vh = DiscreteDomain.rectangle(6, 4, n_points=50) # prepare variational formulation Problem = VariationalFormulation.from_str( 'u,v:-int2d(Vh)(grad{u}*grad{v}) + int2d(Vh)(k*k*u*v)' \ '+ int1d(Vh{1})(1j*k*u*v) + int2d(Vh)(f*v)', locals()) # solve equation u = Problem.solve() # plot result plot(Vh, u, cmap='jet', value=False, figscale=(3, 1))
def deformation_1d_csv(): # prepare variables common to all executions vars_1d['domain'] = DiscreteDomain.line(1, n_points=30) vars_1d['p'] = 1 vars_1d['q'] = 1 # prepare list of force application points f_pt_list = np.concatenate( (np.linspace(0.05, 0.95, 30), np.linspace(0.9, 0.05, 28, endpoint=False))) # run a multievaluation multi_solutions = multievaluate(_cable_1d)(f_pt=f_pt_list) # make an animation with all results Vh, u = zip(*multi_solutions) save_to_csv('1d-cable', Vh, u, multiexport=True)
def acoustic_diffraction_file(): # get input from user: name of the mesh file if PY_V == 2: filename = raw_input('Enter a .msh file name: ') elif PY_V == 3: filename = input('Enter a .msh file name: ') while not filename.endswith('.msh'): print('Incorrect file name. The mesh file must be a .msh file (GMSH' 'v. 2.2 format)!') if PY_V == 2: filename = raw_input('Enter a .msh file name: ') elif PY_V == 3: filename = input('Enter a .msh file name: ') # create discrete domain Vh = DiscreteDomain.from_file(filename, labels={ 'Omega': 10, 'GammaInt': 1, 'GammaExt': 2 }) _acoustic_diffraction(Vh)
def poisson(): f = lambda x, y: x * y for fe_type in ['P1', 'P2', 'P3']: # discretize domain Vh = DiscreteDomain.circle(1, an_points=40, rn_points=20, fe_type=fe_type) # prepare variational formulation Problem = VariationalFormulation(Vh, [('RIGIDITY', Vh)], [(Vh, f)], dirichlet=(1, 0.)) # solve equation u = Problem.solve() # saves directly (no plot display) plot(Vh, u, title='Poisson equation ({} polynomials)'.format(fe_type), value=False, no_plot=True, to_file='poisson-{}.jpg'.format(fe_type))
def deformation_1d_anim(): # prepare variables common to all executions vars_1d['domain'] = DiscreteDomain.line(1, n_points=30) vars_1d['p'] = 1 vars_1d['q'] = 1 # prepare list of force application points f_pt_list = np.concatenate( (np.linspace(0.05, 0.95, 30), np.linspace(0.9, 0.05, 28, endpoint=False))) # run a multievaluation multi_solutions = multievaluate(_cable_1d)(f_pt=f_pt_list) # make an animation with all results Vh, u = zip(*multi_solutions) make_animation('1d-cable.gif', Vh, u, cmap='copper', value=False, fps=200, dim=3)
def load_session(self): """Loads a SimpleFEMPy session (domain, variables, weak formulation and output settings).""" file_reader = filedialog.askopenfilename( title='Choose a SimpleFEMPy session file:') if len(file_reader) > 0: self.reset_session() regex = r'(?P<name>.*)\s*\$\s*(?P<value>.*)\n?' with open(file_reader, 'r') as f: content = f.read() matches = re.finditer(regex, content) for m in matches: n = m.group('name') v = m.group('value') if n == 'DOMAIN_NAME': self.discrete_domain_name.set(v) elif n == 'DOMAIN': t = v.split('|') if t[0] == '_Primitive_': b = int(t[2]) self.domain_primitives_list.activate( SFEMPyApp.PRIMITIVES.index(t[1])) self.set_primitive_params(t[1]) if t[1] == 'Line': self.domain_param1.delete(0, tk.END) self.domain_param1.insert(0, t[3]) self.domain_param2.delete(0, tk.END) self.domain_param2.insert(0, t[4]) self.discrete_domain = DiscreteDomain.line( float(t[3]), step=int(t[4]), nb_borders=b) elif t[1] == 'Rectangle': self.domain_param1.delete(0, tk.END) self.domain_param1.insert(0, t[3]) self.domain_param2.delete(0, tk.END) self.domain_param2.insert(0, t[4]) self.domain_param3.delete(0, tk.END) self.domain_param3.insert(0, t[5]) self.discrete_domain = DiscreteDomain.rectangle( float(t[3]), float(t[4]), step=int(t[5]), nb_borders=b) elif t[1] == 'Circle': self.domain_param1.delete(0, tk.END) self.domain_param1.insert(0, t[3]) self.domain_param2.delete(0, tk.END) self.domain_param2.insert(0, t[4]) self.domain_param3.delete(0, tk.END) self.domain_param3.insert(0, t[5]) self.discrete_domain = DiscreteDomain.circle( float(t[3]), astep=int(t[4]), rstep=int(t[5]), nb_borders=b) elif t[1] == 'Ring': self.domain_param1.delete(0, tk.END) self.domain_param1.insert(0, t[3]) self.domain_param2.delete(0, tk.END) self.domain_param2.insert(0, t[4]) self.domain_param3.delete(0, tk.END) self.domain_param3.insert(0, t[5]) self.domain_param4.delete(0, tk.END) self.domain_param4.insert(0, t[6]) self.discrete_domain = DiscreteDomain.ring( float(t[3]), float(t[4]), astep=int(t[5]), rstep=int(t[6]), nb_borders=b) r = SFEMPyApp.PRIMITIVES.index(t[1]) self.domain_primitives_list.activate(r) self.domain_primitives_list.selection_set(r) self.domain_primitives_borders.delete(0, tk.END) self.domain_primitives_borders.insert(0, t[2]) self.domain_reference = t[0] else: self.discrete_domain = DiscreteDomain.from_file(t[1]) self.domain_reference = t[1] elif n == 'VAR_FORMULATION': self.varf_str.set(v) elif n == 'VARIABLES': vars = v.split('; ') for v in vars: self.add_variable() self.vars[-1].set(v) elif n == 'OUTPUT_TYPE': r = int(v) self.output_type.set(r) if r == 2: self.output_custom.config(state='normal') elif n == 'OUTPUT_CUSTOM': if v == '_None_': pass else: self.output_custom_str.set(v) elif n == 'OUTPUT_PARAMS': params = v.split('|') for p in params: if 'cmap' in p: cmap = p.split(':')[1] self.output_opt_cmap.set(cmap) elif p == 'value': self.output_opt_value.set(1) elif p == '3D': self.output_opt_3d.set(1) elif p == 'labels': self.output_opt_labels.set(1) elif p == 'triangulate': self.output_opt_triangulate.set(1) self.set_figure()