예제 #1
0
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)
예제 #2
0
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)
예제 #3
0
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')
예제 #4
0
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')
예제 #5
0
    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()
예제 #6
0
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)
예제 #7
0
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])
예제 #8
0
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)
예제 #9
0
 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()
예제 #10
0
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)
예제 #11
0
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))
예제 #12
0
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)
예제 #13
0
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)
예제 #14
0
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))
예제 #15
0
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)
예제 #16
0
    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()