def open_circuit_manganese(concentration): """Return open-circuit potential for Li_yMn2O4 param: concentration - Lithium concentration normalized concentration range: [0, 1.0] """ concentr = concentration / normalization_concentration a = 4.19829 b = 0.0565661 * tanh(-14.5546*concentr + 8.60942) z = 0.99839 c = ngs.IfPos(z - concentr, 0.0275479 * (1/Pow(0.998432-concentr, 0.492465) - 1.90111), 0.0275479 * (1/Pow(0.998432-z, 0.492465) - 1.90111)) d = 0.157123 * exp(-0.04738 * concentr**8) e = 0.810239 * exp(-40*(concentr-0.133875)) lower_cutoff = 0.05 e2 = 0.810239 * exp(-40*(lower_cutoff-0.133875)) f = 0.5-0.5*tanh(1000*(concentr - z)) g = 0.0275479 * (1/pow(0.998432-z, 0.492465) - 1.90111) r = 0.5+0.5*tanh(1000*(concentr - lower_cutoff)) # return a + b - c * f - (1-f) * g - d + e k = (a + b - c * f - (1-f) * g - d + e) return r * k + (1-r) * (a+e2)
def open_circuit_carbon(concentration): """Return open-circuit potential for Li_xC6 param: concentration - Lithium concentration normalized concentration range: [0, 0.7] """ concentr = concentration / normalization_concentration # return -0.16 + 1.32 * exp(-3 * concentr) lower_capoff = -1 r = 0.5+0.5*tanh(100*(concentr - lower_capoff)) return (-0.16 + 1.32 * exp(-3 * concentr)) * r + (1-r) * (-0.16 + 1.32*exp(-3*lower_capoff))
def __init__(self, show_gui, max_ndof=50000): super().__init__(show_gui) # init protected self._pde_string = """laplacian(u(x)) = (18x^2-6)e^{-1.5(x^2 + y^2)} +(18y^2-6)e^{-1.5(x^2 + y^2)} +6(6x^2+12x+5)e^{-3((x+1)^2+(y+1)^2)} +6(6y^2+12y+5)e^{-3((x+1)^2+(y+1)^2)} +6(6x^2-12x+5)e^{-3((x-1)^2+(y+1)^2)} +6(6y^2+12y+5)e^{-3((x-1)^2+(y+1)^2)} +6(6x^2+12x+5)e^{-3((x+1)^2+(y-1)^2)} +6(6y^2-12y+5)e^{-3((x+1)^2+(y-1)^2)} +6(6x^2-12x+5)e^{-3((x-1)^2+(y-1)^2)} +6(6y^2-12y+5)e^{-3((x-1)^2+(y-1)^2)}""" self._ngs_ex = 2*ngs.exp(-1.5*(ngs.x*ngs.x + ngs.y*ngs.y)) + \ ngs.exp(-3*((ngs.x + 1)**2 + (ngs.y + 1)**2)) + \ ngs.exp(-3*((ngs.x - 1)**2 + (ngs.y + 1)**2)) + \ ngs.exp(-3*((ngs.x + 1)**2 + (ngs.y - 1)**2)) + \ ngs.exp(-3*((ngs.x - 1)**2 + (ngs.y - 1)**2)) # init public self.max_ndof = max_ndof
def __init__(self, show_gui, max_ndof=50000): super().__init__(show_gui) # init protected self._pde_string = """laplacian(u(x)) = 2*np.exp(-2 (x^2 + y^2))*(2 * np.sin(-2 (x^2 + y^2)) + 2 (1-8 * x^2) np.cos(-2 * (x^2 + y^2))) + \ 2*np.exp(-2 (x^2 + y^2))*(2 * np.sin(-2 (x^2 + y^2)) + 2 (1-8 * y^2) np.cos(-2 * (x^2 + y^2))) + \ 2*np.exp(-1 (x^2 + y^2))*(1 * np.sin(-1 (x^2 + y^2)) + 1 (1-4 * x^2) np.cos(-1 * (x^2 + y^2))) + \ 2*np.exp(-1 (x^2 + y^2))*(1 * np.sin(-1 (x^2 + y^2)) + 1 (1-4 * y^2) np.cos(-1 * (x^2 + y^2))) + \ 2*np.exp(-0.1(x^2 + y^2))*(0.1*np.sin(-0.1(x^2 + y^2)) + 0.1(1-0.4*x^2) np.cos(-0.1*(x^2 + y^2))) + \ 2*np.exp(-0.1(x^2 + y^2))*(0.1*np.sin(-0.1(x^2 + y^2)) + 0.1(1-0.4*y^2) np.cos(-0.1*(x^2 + y^2))) """ self._ngs_ex = ngs.exp(-2 * ((ngs.x)**2 + (ngs.y)**2))*ngs.sin(2 * ((ngs.x)**2 + (ngs.y)**2)) + \ ngs.exp(-1 * ((ngs.x)**2 + (ngs.y)**2))*ngs.sin(1 * ((ngs.x)**2 + (ngs.y)**2)) + \ ngs.exp(-0.1* ((ngs.x)**2 + (ngs.y)**2))*ngs.sin(0.1* ((ngs.x)**2 + (ngs.y)**2)) # init public self.max_ndof = max_ndof
def __init__(self, show_gui, max_ndof=50000): super().__init__(show_gui) # init protected self._pde_string = """-laplacian(u(x)) = -(4*(10^6)*x^2 -4*(10^6)x + 998*(10^3))e^(-1000*((x-0.5)^2 + (y-0.5)^2)) -(4*(10^6)*y^2 -4*(10^6)y + 998*(10^3))e^(-1000*((x-0.5)^2 + (y-0.5)^2))""" self._ngs_ex = ngs.exp(-1000 * ((ngs.x - 0.5)**2 + (ngs.y - 0.5)**2)) # init public self.max_ndof = max_ndof
def sig( x: Union[int, float, Parameter, CoefficientFunction] ) -> Union[float, CoefficientFunction]: """ Function that implements the sigmoid function in a way that's compatible with NGSolve Parameter and Coefficient objects. Args: x: The value to evaluate the sigmoid at Return: ~: sig(x) """ return 1 / (1 + exp(-x))
def tanh( x: Union[int, float, Parameter, CoefficientFunction] ) -> Union[float, CoefficientFunction]: """ Function that implements the hyperbolic tangent in a way that's compatible with NGSolve Parameter and Coefficient objects. Args: x: The value to evaluate tanh at. Return: ~: tanh(x) """ # Deal with some math overflow problems if type(x) is Parameter or type(x) is CoefficientFunction: # Added to ensure that the tanh calculation does not return nan x_adj = IfPos(x - 350, 350, x) else: # float or int if x > 350: x_adj = 350 else: x_adj = x return (exp(2 * x_adj) - 1.0) / (exp(2 * x_adj) + 1.0)
def poisson_solve(): fes = H1(mesh, order=3, dirichlet="left|right|bottom|top") u = fes.TrialFunction() v = fes.TestFunction() f = LinearForm(fes) f += -((4 * x**2 - 2) * ng.exp(-x**2) + (4 * y**2 - 2) * ng.exp(-y**2)) * v * dx a = BilinearForm(fes) a += grad(u) * grad(v) * dx a.Assemble() f.Assemble() uₕ = ng.GridFunction(fes) uₕ.Set(uexact, ng.BND) α = f.vec.CreateVector() α.data = f.vec - a.mat * uₕ.vec uₕ.vec.data += a.mat.Inverse(freedofs=fes.FreeDofs()) * α return uₕ
from netgen.geom2d import unit_square from wave import vec, waveA, makeforms # PARAMETERS: p = 3 # polynomial degree h0 = 1 # coarse mesh size for unit square domain markprm = 0.5 # percentage of max total error for marking # SET UP: mesh = Mesh(unit_square.GenerateMesh(maxh=h0)) q_zero = 'bottom' # Mesh boundary parts where q and mu_zero = 'bottom|right|left' # mu has essential b.c u00 = exp(-1000 * ((x - 0.5) * (x - 0.5))) # Nonzero initial condition cwave = 1. # wave speed F = ngs.CoefficientFunction((0, 0)) # Zero source a, f, X, sep = makeforms(mesh, p, F, q_zero, mu_zero, cwave, epsil=1.e-10) euz = GridFunction(X) # Contains solution at each adaptive step q = euz.components[sep[0]] # Volume (L2) components mu = euz.components[sep[0]+1] zq = euz.components[sep[1]] # Interface components zmu = euz.components[sep[1]+1] zq.Set(u00, definedon='bottom') zmu.Set(-u00, definedon='bottom') ngs.Draw(mu, autoscale=False, # draw only one of the solution components
def σ(x): return 1 / (1 + ng.exp(-x))
return uₕ # read in NNet weights and biases Wx = np.genfromtxt('NN_params/Wx.csv', delimiter=',') Wy = np.genfromtxt('NN_params/Wy.csv', delimiter=',') Wz = np.genfromtxt('NN_params/Wz.csv', delimiter=',') b1 = np.genfromtxt('NN_params/b1.csv', delimiter=',') W2 = np.genfromtxt('NN_params/W2.csv', delimiter=',') b2 = np.genfromtxt('NN_params/b2.csv', delimiter=',') W3 = np.genfromtxt('NN_params/W3.csv', delimiter=',') b3 = np.genfromtxt('NN_params/b3.csv', delimiter=',') # manufactured solution uexact = ng.exp(-ng.x**2) + ng.exp(-ng.y**2) # logistic activation function def σ(x): return 1 / (1 + ng.exp(-x)) # vectorize the logistic function for component-wise application vσ = np.vectorize(σ) # NNet coefficient function u_net = W3.dot(vσ(W2.dot(vσ(Wx.dot(ng.x) + Wy.dot(ng.y) + b1)) + b2)) + b3 # unit square domain #mesh = Mesh(unit_square.GenerateMesh(maxh=0.2))
def solve(self): # disable garbage collector # --------------------------------------------------------------------# gc.disable() while (gc.isenabled()): time.sleep(0.1) # --------------------------------------------------------------------# # measure how much memory is used until here process = psutil.Process() memstart = process.memory_info().vms # starts timer tstart = time.time() if self.show_gui: import netgen.gui # create mesh with initial size 0.1 geo = geom2d.SplineGeometry() p1 = geo.AppendPoint(-2, -2) p2 = geo.AppendPoint(2, -2) p3 = geo.AppendPoint(2, 2) p4 = geo.AppendPoint(-2, 2) geo.Append(["line", p1, p2]) geo.Append(["line", p2, p3]) geo.Append(["line", p3, p4]) geo.Append(["line", p4, p1]) self._mesh = ngs.Mesh(geo.GenerateMesh(maxh=0.1)) #create finite element space self._fes = ngs.H1(self._mesh, order=2, dirichlet=".*", autoupdate=True) # test and trail function u = self._fes.TrialFunction() v = self._fes.TestFunction() # create bilinear form and enable static condensation self._a = ngs.BilinearForm(self._fes, condense=True) self._a += ngs.grad(u) * ngs.grad(v) * ngs.dx # creat linear functional and apply RHS self._f = ngs.LinearForm(self._fes) self._f += ( -(18 * ngs.x * ngs.x - 6) * ngs.exp(-1.5 * (ngs.x * ngs.x + ngs.y * ngs.y)) - (18 * ngs.y * ngs.y - 6) * ngs.exp(-1.5 * (ngs.x * ngs.x + ngs.y * ngs.y)) - 6 * (6 * ngs.x**2 + 12 * ngs.x + 5) * ngs.exp(-3 * ((ngs.x + 1)**2 + (ngs.y + 1)**2)) - 6 * (6 * ngs.y**2 + 12 * ngs.y + 5) * ngs.exp(-3 * ((ngs.x + 1)**2 + (ngs.y + 1)**2)) - 6 * (6 * ngs.x**2 - 12 * ngs.x + 5) * ngs.exp(-3 * ((ngs.x - 1)**2 + (ngs.y + 1)**2)) - 6 * (6 * ngs.y**2 + 12 * ngs.y + 5) * ngs.exp(-3 * ((ngs.x - 1)**2 + (ngs.y + 1)**2)) - 6 * (6 * ngs.x**2 + 12 * ngs.x + 5) * ngs.exp(-3 * ((ngs.x + 1)**2 + (ngs.y - 1)**2)) - 6 * (6 * ngs.y**2 - 12 * ngs.y + 5) * ngs.exp(-3 * ((ngs.x + 1)**2 + (ngs.y - 1)**2)) - 6 * (6 * ngs.x**2 - 12 * ngs.x + 5) * ngs.exp(-3 * ((ngs.x - 1)**2 + (ngs.y - 1)**2)) - 6 * (6 * ngs.y**2 - 12 * ngs.y + 5) * ngs.exp(-3 * ( (ngs.x - 1)**2 + (ngs.y - 1)**2))) * v * ngs.dx # preconditioner: multigrid - what prerequisits must the problem have? self._c = ngs.Preconditioner(self._a, "multigrid") # create grid function that holds the solution and set the boundary to 0 self._gfu = ngs.GridFunction(self._fes, autoupdate=True) # solution self._g = self._ngs_ex self._gfu.Set(self._g, definedon=self._mesh.Boundaries(".*")) # draw grid function in gui if self.show_gui: ngs.Draw(self._gfu) # create Hcurl space for flux calculation and estimate error self._space_flux = ngs.HDiv(self._mesh, order=2, autoupdate=True) self._gf_flux = ngs.GridFunction(self._space_flux, "flux", autoupdate=True) # TaskManager starts threads that (standard thread nr is numer of cores) #with ngs.TaskManager(): # this is the adaptive loop while self._fes.ndof < self.max_ndof: self._solveStep() self._estimateError() self._mesh.Refine() # since the adaptive loop stopped with a mesh refinement, the gfu must be # calculated one last time self._solveStep() if self.show_gui: ngs.Draw(self._gfu) # set measured exectution time self._exec_time = time.time() - tstart # set measured used memory memstop = process.memory_info().vms - memstart self._mem_consumption = memstop # enable garbage collector # --------------------------------------------------------------------# gc.enable() gc.collect()
def Pow(a, b): """Power function for CoefficientFunctions""" return exp(log(a)*b)
def tanh(x): """tangens hyperbolicus for CoefficientFunctions""" return (1 - exp(-2*x)) / (1 + exp(-2*x))
a = ngs.BilinearForm(fes) a += ngs.SymbolicBFI(1 / 2 * grad(u) * grad(v) + potential * u * v) a.Assemble() m = ngs.BilinearForm(fes) m += ngs.SymbolicBFI(1j * u * v) m.Assemble() ## Initial condition ### Gaussian wave packet delta_x = 2 x0 = -20 kx = 2 wave_packet = ngs.CoefficientFunction( exp(1j * (kx * x)) * exp(-((x - x0)**2) / 4 / delta_x**2)) ### Heaviside function # wave_packet = ngs.CoefficientFunction(IfPos(x, 1, 0)) gf_psi = ngs.GridFunction(fes) gf_psi.Set(wave_packet) gf_psi.vec.data = 1 / ngs.Norm(gf_psi.vec) * gf_psi.vec freedofs = fes.FreeDofs() for i in range(len(gf_psi.vec)): if not freedofs[i]: gf_psi.vec[i] = 0 ## Crank-Nicolson time step max_time = 100
a = ngs.BilinearForm(fes) a += ngs.SymbolicBFI(1/2 * grad(u) * grad(v)) a.Assemble() m = ngs.BilinearForm(fes) m += ngs.SymbolicBFI(1j * u * v) m.Assemble() ## Initial condition delta_x = 0.05 x0 = 0.2 y0 = 0.5 kx = 0 ky = 0 wave_packet = ngs.CoefficientFunction( exp(1j * (kx * x + ky * y)) * exp(-((x-x0)**2+(y-y0)**2)/4/delta_x**2)) gf_psi = ngs.GridFunction(fes) gf_psi.Set(wave_packet) gf_psi.vec.data = 1/ngs.Norm(gf_psi.vec) * gf_psi.vec freedofs = fes.FreeDofs() for i in range(len(gf_psi.vec)): if not freedofs[i]: gf_psi.vec[i] = 0 ngs.Draw(ngs.Norm(gf_psi), mesh, name='abs(psi)') ## Crank-Nicolson time step max_time = 1 timestep = 0.0001