y=np.linspace(-1.0, 1.0, 21)) ############################################################################### # We start considering inhomogeneous Dirchlet boundary conditions (BC). # There are different ways of specifying BCs. They can be maps from markers to # values, explicit functions or implicit (lambda) functions. # # The boundary 1 (top) and 2 (left) are directly mapped to the values 1 and 2. # On side 3 (bottom) a lambda function 3+x is used (p is the boundary position # and p[0] its x coordinate. On side 4 (right) a function uDirichlet is used # that simply returns 4 in this example but can compute anything as a function # of the individual boundaries b. ############################################################################### # Short test: setting single node dirichlet BC u = solve(grid, f=1., uB=[grid.node(2), 0.]) ax, _ = pg.show( grid, u, label='Solution $u$', ) show(grid, ax=ax) def uDirichlet(b): """ Return a solution value for coordinate p. """ return 4.0
# and p[0] its x coordinate. On side 4 (bottom) a function uDirichlet is used # that simply returns 4 in this example but can compute anything as a function # of the individual boundaries b. def uDirichlet(boundary): """Return a solution value for a given boundary. Scalar values are applied to all nodes of the boundary.""" return 4.0 dirichletBC = {1: 1, # left 2: 2.0, # right 3: lambda boundary: 3.0 + boundary.center()[0], # top 4: uDirichlet} # bottom ############################################################################### # The boundary conditions are passed using the bc keyword dictionary. u = solve(grid, f=1., bc={'Dirichlet': dirichletBC}) # Note that showMesh returns the created figure ax and the created colorBar. ax, cbar = show(grid, data=u, label='Solution $u$') show(grid, ax=ax) ax.text(0, 1.01, '$u=3+x$', ha='center') ax.text(-1.01, 0, '$u=1$', va='center', ha='right', rotation='vertical') ax.text(0, -1.01, '$u=4$', ha='center', va='top') ax.text(1.02, 0, '$u=2$', va='center', ha='left', rotation='vertical') ax.set_title('$\\nabla\cdot(1\\nabla u)=1$') ax.set_xlim([-1.1, 1.1]) # some boundary for the text ax.set_ylim([-1.1, 1.1])
grid = pg.createGrid(x=np.linspace(-10.0, 10.0, 21), y=np.linspace(-15.0, .0, 16)) #grid = grid.createH2() grid = grid.createP2() sourcePosA = [-5.0, -4.0] sourcePosB = [ 5.0, -4.0] neumannBC = [[1, mixedBC], #left boundary [2, mixedBC], #right boundary [4, mixedBC]] #bottom boundary k = 1e-3 u = solve(grid, a=1, b=k*k, f=pointSource, duB=neumannBC, userData={'sourcePos': sourcePosA, 'k': k}, verbose=True) u -= solve(grid, a=1, b=k*k, f=pointSource, duB=neumannBC, userData={'sourcePos': sourcePosB, 'k': k}, verbose=True) #uAna = pg.RVector(map(lambda p__: uAnalytical(p__, sourcePosA, k), grid.positions())) #uAna -= pg.RVector(map(lambda p__: uAnalytical(p__, sourcePosB, k), grid.positions())) #err = (1.0 -u/uAna)*100.0 #print "error min max", min(err), max(err) ax = show(grid, data=u, filled=True, colorBar=True,
grid = pg.createGrid(x=np.linspace(-10.0, 10.0, 41), y=np.linspace(-15.0, 0.0, 31)) grid = grid.createP2() sourcePosA = [-5.0, -4.0] sourcePosB = [+5.0, -4.0] robBC = [[1, mixedBC], # left boundary [2, mixedBC], # right boundary [4, mixedBC]] # bottom boundary k = 1e-3 sigma = 1 u = solve(grid, a=sigma, b=-sigma * k*k, f=pointSource(grid, sourcePosA), bc={'Robin': [[1,2,4], mixedBC]}, userData={'sourcePos': sourcePosA, 'k': k}, verbose=True) u -= solve(grid, a=sigma, b=-sigma * k*k, f=pointSource(grid, sourcePosB), bc={'Robin': robBC}, userData={'sourcePos': sourcePosB, 'k': k}, verbose=True) # uAna = pg.RVector(map(lambda p__: uAnalytical(p__, sourcePosA, k), # grid.positions())) # uAna -= pg.RVector(map(lambda p__: uAnalytical(p__, sourcePosB, k), # grid.positions())) # err = (1.0 -u/uAna) * 100.0 # print("error min max", min(err), max(err))
grid = pg.createGrid(x=np.linspace(-10.0, 10.0, 21), y=np.linspace(-15.0, .0, 16)) grid = grid.createP2() sourcePosA = [-5.0, -4.0] sourcePosB = [+5.0, -4.0] neumannBC = [[1, mixedBC], # left boundary [2, mixedBC], # right boundary [4, mixedBC]] # bottom boundary k = 1e-3 sigma = 1 u = solve(grid, a=sigma, b=sigma * k*k, f=pointSource, duB=neumannBC, userData={'sourcePos': sourcePosA, 'k': k}, verbose=True) u -= solve(grid, a=sigma, b=sigma * k*k, f=pointSource, duB=neumannBC, userData={'sourcePos': sourcePosB, 'k': k}, verbose=True) # uAna = pg.RVector(map(lambda p__: uAnalytical(p__, sourcePosA, k), # grid.positions())) # uAna -= pg.RVector(map(lambda p__: uAnalytical(p__, sourcePosB, k), # grid.positions())) # err = (1.0 -u/uAna) * 100.0 # print("error min max", min(err), max(err))
dirichletBC = [[3, lambda b, t: 1.0 + np.cos(2.0 * np.pi * t)], # top [4, 1.0]] #bottom pg.showLater(1) ax = show(grid)[0] ax.figure.canvas.draw() #plt.ion() #plt.show() u = solve(grid, a=vals, f=0.5, times=times, u0=pg.RVector(grid.nodeCount(), 0.0), duBoundary=neumannBC, uBoundary=dirichletBC, ##plotTimeStep=updateDrawU, verbose=False, progress=True) uMin = min(u.flat) uMax = max(u.flat) show(grid, u[0], axes=ax) """ .. image:: PLOT2RST.current_figure :scale: 75 """
sourcePosA = [-5.0, -4.0] sourcePosB = [+5.0, -4.0] robBC = [ [1, mixedBC], # left boundary [2, mixedBC], # right boundary [4, mixedBC] ] # bottom boundary k = 1e-3 sigma = 1 u = solve(grid, a=sigma, b=-sigma * k * k, f=pointSource(grid, sourcePosA), bc={'Robin': [[1, 2, 4], mixedBC]}, userData={ 'sourcePos': sourcePosA, 'k': k }, verbose=True) u -= solve(grid, a=sigma, b=-sigma * k * k, f=pointSource(grid, sourcePosB), bc={'Robin': robBC}, userData={ 'sourcePos': sourcePosB, 'k': k }, verbose=True)
""" return 4.0 dirichletBC = [ [1, 1.0], # left [grid.findBoundaryByMarker(2), 2.0], # right [grid.findBoundaryByMarker(3), lambda p: 3.0 + p.center()[0]], # top [grid.findBoundaryByMarker(4), uDirichlet], ] # bottom ############################################################################### # The BC are passed using the uBoundary keyword. Note that showMesh returns the # created figure axes ax while drawMesh plots on it and it can also be used as # a class with plotting or decoration methods. u = solve(grid, f=1.0, uB=dirichletBC) ax = show( grid, data=u, colorBar=True, orientation="vertical", label="Solution $u$", levels=np.linspace(1.0, 4.0, 17), hold=1 )[0] show(grid, axes=ax) ax.text(0, 1.01, "$u=3+x$", ha="center") ax.text(-1.01, 0, "$u=1$", va="center", ha="right", rotation="vertical") ax.text(0, -1.01, "$u=4$", ha="center", va="top") ax.text(1.02, 0, "$u=2$", va="center", ha="left", rotation="vertical") ax.set_title("$\\nabla\cdot(1\\nabla u)=1$") ax.set_xlim([-1.1, 1.1]) # some boundary for the text
solver.assembleDirichletBC(S, boundUdir, rhs=b) solve = pg.LinSolver(S) solve.solve(b, ut) u[n, :] = ut # u = solver.solvePoisson(grid, times=times, theta=1.0, # u0=lambda r: np.sin(np.pi * r[0]), # uBoundary=dirichletBC) plt.plot(times, u[:, probeID], label='Implicit Euler') u = solver.solve(grid, times=times, theta=0.5, u0=lambda r: np.sin(np.pi * r[0]), uB=dirichletBC) plt.plot(times, u[:, probeID], label='Crank-Nicolson') plt.xlabel("t[s] at x = " + str(round(grid.node(probeID).pos()[0], 2))) plt.ylabel("u") plt.ylim(0.0, 1.0) plt.xlim(0.0, 0.5) plt.legend() plt.grid() ############################################################################### # Explicit Euler scheme is unstable at progressing time. plt.show()
b = M * u[n - 1] + rhs * dt S = M + A * dt solver.assembleDirichletBC(S, boundUdir, rhs=b) solve = pg.LinSolver(S) solve.solve(b, ut) u[n, :] = ut plt.plot(times, u[:, probeID], label='Implicit Euler') u = solver.solve(grid, times=times, theta=0.5, u0=lambda r: np.sin(np.pi * r[0]), uB=dirichletBC) plt.plot(times, u[:, probeID], label='Crank-Nicolson') plt.xlabel("t[s] at x = " + str(round(grid.node(probeID).pos()[0], 2))) plt.ylabel("u") plt.ylim(0.0, 1.0) plt.xlim(0.0, 0.5) plt.legend() plt.grid() ############################################################################### # Explicit Euler scheme is unstable at progressing time.
############################################################################### # We start considering inhomogeneous Dirichlet boundary conditions (BC). # # There are different ways of specifying BCs. They can be maps from markers to # values, explicit functions or implicit (lambda) functions. # # The boundary 1 (top) and 2 (left) are directly mapped to the values 1 and 2. # On side 3 (bottom) a lambda function 3+x is used (p is the boundary position # and p[0] its x coordinate. On side 4 (right) a function uDirichlet is used # that simply returns 4 in this example but can compute anything as a function # of the individual boundaries b. ############################################################################### # Short test: setting single node dirichlet BC u = solve(grid, f=1., bc={'Dirichlet': [grid.node(2), 0.]}) ax, _ = pg.show( grid, u, label='Solution $u$', ) show(grid, ax=ax) def uDirichlet(boundary): """Return a solution value for coordinate p.""" return 4.0 dirichletBC = [
b = M * u[n - 1] + rhs * dt S = M + A * dt solver.assembleDirichletBC(S, boundUdir, rhs=b) solve = pg.LinSolver(S) solve.solve(b, ut) u[n, :] = ut plt.plot(times, u[:, probeID], label='Implicit Euler') u = solver.solve(grid, times=times, theta=0.5, u0=lambda node: np.sin(np.pi * node[0]), bc={'Dirichlet': dirichletBC}) plt.plot(times, u[:, probeID], label='Crank-Nicolson') plt.xlabel("t[s] at x = " + str(round(grid.node(probeID).pos()[0], 2))) plt.ylabel("u") plt.ylim(0.0, 1.0) plt.xlim(0.0, 0.5) plt.legend() plt.grid() ############################################################################### # Explicit Euler scheme is unstable at progressing time.