def MakeMesh2D(mesh1, mesh2): tpmesh = ngmeshing.Mesh(dim=mesh1.dim + mesh2.dim) ngm1 = mesh1.ngmesh ngm2 = mesh2.ngmesh els1 = ngm1.Elements1D() els2 = ngm2.Elements1D() vert1 = ngm1.Points() vert2 = ngm2.Points() pids = [] for i in range(len(vert1)): for j in range(len(vert2)): pids.append( tpmesh.Add( MeshPoint( Pnt(vert1[ngmeshing.PointId(i + 1)].p[0], vert2[ngmeshing.PointId(j + 1)].p[0], 0)))) tpmesh.Add(FaceDescriptor(surfnr=1, domin=1, bc=1)) for elx in els1: for ely in els2: pnum = [ (elx.vertices[1].nr - 1) * len(vert2) + ely.vertices[1].nr - 1, (elx.vertices[0].nr - 1) * len(vert2) + ely.vertices[1].nr - 1, (elx.vertices[0].nr - 1) * len(vert2) + ely.vertices[0].nr - 1, (elx.vertices[1].nr - 1) * len(vert2) + ely.vertices[0].nr - 1 ] elpids = [pids[p] for p in pnum] tpmesh.Add(Element2D(1, elpids)) return tpmesh
def test_polynomial_ET_Segm(domain, alpha): order = alpha m = ngm.Mesh() m.dim = 1 nel = 1 pnums = [] for i in range(0, nel+1): pnums.append (m.Add (ngm.MeshPoint (ngm.Pnt(i/nel, 0, 0)))) for i in range(0,nel): m.Add (ngm.Element1D ([pnums[i],pnums[i+1]], index=1)) m.Add (ngm.Element0D (pnums[0], index=1)) m.Add (ngm.Element0D (pnums[nel], index=2)) mesh = Mesh(m) x_ast = 0.78522 levelset = x_ast-x referencevals = {POS:pow(x_ast, alpha+1)/(alpha+1), NEG:(1-pow(x_ast, alpha+1))/(alpha+1), IF: pow(x_ast, alpha)} V = H1(mesh, order=1) lset_approx = GridFunction(V) #InterpolateToP1(levelset,lset_approx) lset_approx.Set(levelset) f = x**alpha integral = Integrate(levelset_domain = { "levelset" : lset_approx, "domain_type" : domain}, cf=f, mesh=mesh, order = order) print("Result of Integration Key ",domain," : ", integral) error = abs(integral - referencevals[domain]) print("Error: ", error) assert error < 5e-15*(order+1)*(order+1)
def test_BBNDsave(): mesh = CreateGeo().GenerateMesh( maxh=0.4, perfstepsend=meshing.MeshingStep.MESHSURFACE) for i in range(2): mesh.GenerateVolumeMesh(only3D_domain_nr=i + 1, maxh=0.4) mesh.SetGeometry(None) mesh.Save("test.vol") mesh2 = meshing.Mesh() mesh2.Load("test.vol") mesh2.Save("test2.vol") with open("test.vol", "r") as f: first = f.readlines() with open("test2.vol", "r") as f: second = f.readlines() # exclude the face colours section (because they aren't in the same order) for i, line in enumerate(first): if line[0:12] == "face_colours": first = first[0:i] second = second[0:i] break diff = difflib.context_diff(first, second) print("File diff:") l = list(diff) print(*l) assert len(l) == 0
def ngsolve_vector_array_factory(length, dim, seed): if dim not in NGSOLVE_spaces: mesh = ngmsh.Mesh(dim=1) if dim > 0: pids = [] for i in range(dim + 1): pids.append( mesh.Add(ngmsh.MeshPoint(ngmsh.Pnt(i / dim, 0, 0)))) for i in range(dim): mesh.Add(ngmsh.Element1D([pids[i], pids[i + 1]], index=1)) NGSOLVE_spaces[dim] = NGSolveVectorSpace( ngs.L2(ngs.Mesh(mesh), order=0)) U = NGSOLVE_spaces[dim].zeros(length) np.random.seed(seed) for v, a in zip(U._list, np.random.random((length, dim))): v.to_numpy()[:] = a if np.random.randint(2): UU = NGSOLVE_spaces[dim].zeros(length) for v, a in zip(UU._list, np.random.random((length, dim))): v.real_part.to_numpy()[:] = a for u, uu in zip(U._list, UU._list): u.imag_part = uu.real_part return U
def _create_ngsolve_space(dim): if dim not in _NGSOLVE_spaces: mesh = ngmsh.Mesh(dim=1) if dim > 0: pids = [] for i in range(dim + 1): pids.append(mesh.Add(ngmsh.MeshPoint(ngmsh.Pnt(i / dim, 0, 0)))) for i in range(dim): mesh.Add(ngmsh.Element1D([pids[i], pids[i + 1]], index=1)) _NGSOLVE_spaces[dim] = NGSolveVectorSpace(ngs.L2(ngs.Mesh(mesh), order=0)) return _NGSOLVE_spaces[dim]
def test_convection1d_dg(): m = meshing.Mesh() m.dim = 1 nel = 20 pnums = [] for i in range(0, nel + 1): pnums.append(m.Add(meshing.MeshPoint(Pnt(i / nel, 0, 0)))) for i in range(0, nel): m.Add(meshing.Element1D([pnums[i], pnums[i + 1]], index=1)) m.Add(meshing.Element0D(pnums[0], index=1)) m.Add(meshing.Element0D(pnums[nel], index=2)) m.AddPointIdentification(pnums[0], pnums[nel], identnr=1, type=meshing.IdentificationType.PERIODIC) mesh = Mesh(m) fes = L2(mesh, order=4) u = fes.TrialFunction() v = fes.TestFunction() b = CoefficientFunction(1) bn = b * specialcf.normal(1) a = BilinearForm(fes) a += SymbolicBFI(-u * b * grad(v)) a += SymbolicBFI(bn * IfPos(bn, u, u.Other()) * v, element_boundary=True) u = GridFunction(fes) pos = 0.5 u0 = exp(-100 * (x - pos) * (x - pos)) u.Set(u0) w = u.vec.CreateVector() t = 0 tau = 1e-4 tend = 1 with TaskManager(): while t < tend - tau / 2: a.Apply(u.vec, w) fes.SolveM(rho=CoefficientFunction(1), vec=w) u.vec.data -= tau * w t += tau l2error = sqrt(Integrate((u - u0) * (u - u0), mesh)) print(l2error) assert l2error < 1e-2
def MakeMesh3D(mesh1, mesh2): tpmesh = ngmeshing.Mesh(dim=mesh1.dim + mesh2.dim) ngm1 = mesh1.ngmesh ngm2 = mesh2.ngmesh if mesh1.dim == 2: els1 = ngm1.Elements2D() els2 = ngm2.Elements1D() vert1 = ngm1.Points() vert2 = ngm2.Points() pids = [] for i in range(len(vert1)): for j in range(len(vert2)): pids.append( tpmesh.Add( MeshPoint( Pnt(vert1[ngmeshing.PointId(i + 1)].p[0], vert1[ngmeshing.PointId(i + 1)].p[1], vert2[ngmeshing.PointId(j + 1)].p[0])))) for elx in els1: for ely in els2: pnum = [] for j in reversed(ely.vertices): for i in elx.vertices: pnum.append((i.nr - 1) * len(vert2) + j.nr - 1) elpids = [pids[p] for p in pnum] tpmesh.Add(Element3D(1, elpids)) return tpmesh else: els1 = ngm1.Elements1D() els2 = ngm2.Elements2D() vert1 = ngm1.Points() vert2 = ngm2.Points() pids = [] for i in range(len(vert1)): for j in range(len(vert2)): pids.append( tpmesh.Add( MeshPoint( Pnt(vert1[ngmeshing.PointId(i + 1)].p[0], vert2[ngmeshing.PointId(j + 1)].p[0], vert2[ngmeshing.PointId(j + 1)].p[1])))) for elx in els1: for ely in els2: pnum = [] for i in reversed(elx.vertices): for j in (ely.vertices): pnum.append((i.nr - 1) * len(vert2) + j.nr - 1) elpids = [pids[p] for p in pnum] tpmesh.Add(Element3D(1, elpids)) return tpmesh
def load_mesh(config: ConfigParser) -> Mesh: """ Loads an NGSolve mesh from a .sol file whose file path is specified in the given config file. Args: config: A ConfigParser object containing the information from the config file. Returns: mesh: The NGSolve mesh pointed to in the config file. """ assert type(config) is ConfigParser try: mesh_filename = config['MESH']['filename'] except: raise ValueError( 'No default available for MESH, filename. Please specify a value in the config file.' ) # Check that the file exists. if not os.path.isfile(mesh_filename): raise FileNotFoundError( 'The given mesh file \"{}\" does not exist.'.format(mesh_filename)) # Mesh can be a Netgen mesh or a GMSH mesh. if mesh_filename.endswith('.msh'): ngmesh = ReadGmsh(mesh_filename) mesh = ngs.Mesh(ngmesh) elif mesh_filename.endswith('.vol'): ngmesh = ngmsh.Mesh() ngmesh.Load(mesh_filename) mesh = ngs.Mesh(ngmesh) else: raise TypeError( 'Only .vol (Netgen) and .msh (GMSH) meshes can be used.' 'Your specified filename was \"{}\"'.format(mesh_filename)) # Suppressing the warning about using the default value for curved_elements. curved_elements = config.get_item(['MESH', 'curved_elements'], bool, quiet=True) if curved_elements: interp_ord = config.get_item( ['FINITE ELEMENT SPACE', 'interpolant_order'], int) mesh.Curve(interp_ord) return mesh
def test_hdg1d(): m = meshing.Mesh(dim=1) nel = 10 pnums = [] for i in range(0, nel+1): pnums.append (m.Add (MeshPoint (Pnt(i/nel, 0, 0)))) for i in range(0,nel): m.Add (Element1D ([pnums[i],pnums[i+1]], index=1)) m.Add (Element0D (pnums[0], index=1)) m.Add (Element0D (pnums[nel], index=1)) mesh = Mesh(m) order = 2 V1 = L2(mesh, order=order) V2 = FacetFESpace(mesh, order=0, dirichlet=[1]) V = FESpace([V1,V2]) u, uhat = V.TrialFunction() v, vhat = V.TestFunction() n = specialcf.normal(mesh.dim) h = specialcf.mesh_size a = BilinearForm(V) a += SymbolicBFI(grad(u)*grad(v)) a += SymbolicBFI(-grad(u)*n*(v-vhat),element_boundary=True) a += SymbolicBFI(-grad(v)*n*(u-uhat),element_boundary=True) alpha = 4 a += SymbolicBFI(alpha*order*order/h * (u-uhat)*(v-vhat),element_boundary=True) f = LinearForm(V) f += SymbolicLFI(1*v) f.Assemble() a.Assemble() u = GridFunction(V) u.vec.data = a.mat.Inverse(V.FreeDofs(),inverse="sparsecholesky")*f.vec exsol = 0.5*x*(1-x) l2error = Integrate(InnerProduct(u.components[0]-exsol,u.components[0]-exsol),mesh) assert l2error < 1e-15
def test_1dlaplace(): m = meshing.Mesh() m.dim = 1 nel = 20 pnums = [] for i in range(0, nel + 1): pnums.append(m.Add(meshing.MeshPoint(meshing.Pnt(i / nel, 0, 0)))) for i in range(0, nel): m.Add(meshing.Element1D([pnums[i], pnums[i + 1]], index=1)) m.Add(meshing.Element0D(pnums[0], index=1)) m.Add(meshing.Element0D(pnums[nel], index=2)) mesh = Mesh(m) order = 10 fes = H1(mesh, order=order, dirichlet=[1, 2]) u = fes.TrialFunction() v = fes.TestFunction() n = specialcf.normal(mesh.dim) h = specialcf.mesh_size ugf = GridFunction(fes) uex = GridFunction(fes) uex.Set(sin(pi * x)) a = BilinearForm(fes) a += SymbolicBFI(grad(u) * grad(v)) l = LinearForm(fes) l += SymbolicLFI(pi * pi * uex * v) l.Assemble() a.Assemble() invmat = a.mat.Inverse(fes.FreeDofs()) ugf.vec.data = invmat * l.vec error = sqrt(Integrate((ugf - uex) * (ugf - uex), mesh)) assert error <= 1e-14
def MakeMesh1D(): a = 0 b = 1 nel = 10 m = msh.Mesh() m.dim = 1 pnums = [] for i in range(nel + 1): pnums.append(m.Add(msh.MeshPoint(msh.Pnt(a + (b - a) * i / nel, 0, 0)))) for i in range(2): m.Add(msh.Element1D([pnums[i], pnums[i + 1]], index=1)) for i in range(2, 5): m.Add(msh.Element1D([pnums[i], pnums[i + 1]], index=3)) for i in range(5, 7): m.Add(msh.Element1D([pnums[i], pnums[i + 1]], index=1)) for i in range(7, nel): m.Add(msh.Element1D([pnums[i], pnums[i + 1]], index=2)) m.SetMaterial(1, 'base') m.SetMaterial(2, 'chip') m.SetMaterial(3, 'top') # add points m.Add(msh.Element0D(pnums[0], index=1)) m.Add(msh.Element0D(pnums[2], index=2)) m.Add(msh.Element0D(pnums[5], index=2)) m.Add(msh.Element0D(pnums[7], index=2)) m.Add(msh.Element0D(pnums[nel], index=2)) # set boundary condition names m.SetBCName(0, 'bottom') m.SetBCName(1, 'other') m.Save('temp.vol') return m
def CartSquare(N, t_steps, xscale=1, xshift=0, tscale=1): ngmesh = ngm.Mesh() ngmesh.SetGeometry(unit_square) ngmesh.dim = 2 pnums = [] for j in range(t_steps + 1): for i in range(N + 1): pnums.append( ngmesh.Add( ngm.MeshPoint( ngm.Pnt((i / N) * xscale - xshift, (j / t_steps) * tscale, 0)))) foo = ngm.FaceDescriptor(surfnr=1, domin=1, bc=1) ngmesh.Add(foo) ngmesh.SetMaterial(1, "mat") for j in range(t_steps): for i in range(N): ngmesh.Add( ngm.Element2D(1, [ pnums[i + j * (N + 1)], pnums[i + 1 + j * (N + 1)], pnums[i + 1 + (j + 1) * (N + 1)], pnums[i + (j + 1) * (N + 1)] ])) fde = ngm.FaceDescriptor(surfnr=1, domin=1, bc=1) fde.bcname = "bottom" fdid = ngmesh.Add(fde) for i in range(N): ngmesh.Add(ngm.Element1D([pnums[i], pnums[i + 1]], index=1)) fde = ngm.FaceDescriptor(surfnr=2, domin=1, bc=2) fde.bcname = "top" fdid = ngmesh.Add(fde) for i in range(N): ngmesh.Add( ngm.Element1D([ pnums[i + t_steps * (N + 1)], pnums[i + 1 + t_steps * (N + 1)] ], index=2)) fde = ngm.FaceDescriptor(surfnr=3, domin=1, bc=3) fde.bcname = "dirichlet" fdid = ngmesh.Add(fde) for i in range(t_steps): ngmesh.Add( ngm.Element1D( [pnums[N + i * (N + 1)], pnums[N + (i + 1) * (N + 1)]], index=3)) ngmesh.Add( ngm.Element1D( [pnums[0 + i * (N + 1)], pnums[0 + (i + 1) * (N + 1)]], index=3)) ngmesh.SetBCName(0, "bottom") ngmesh.SetBCName(1, "top") ngmesh.SetBCName(2, "dirichlet") mesh = Mesh(ngmesh) # print("boundaries" + str(mesh.GetBoundaries())) return mesh
def PODSweep(Object, Order, alpha, inorout, mur, sig, Array, PODArray, PODTol, PlotPod, sweepname, SavePOD, PODErrorBars, BigProblem): Object = Object[:-4] + ".vol" #Set up the Solver Parameters Solver, epsi, Maxsteps, Tolerance = SolverParameters() #Loading the object file ngmesh = ngmeshing.Mesh(dim=3) ngmesh.Load("VolFiles/" + Object) #Creating the mesh and defining the element types mesh = Mesh("VolFiles/" + Object) mesh.Curve(5) #This can be used to refine the mesh numelements = mesh.ne #Count the number elements print(" mesh contains " + str(numelements) + " elements") #Set up the coefficients #Scalars Mu0 = 4 * np.pi * 10**(-7) NumberofSnapshots = len(PODArray) NumberofFrequencies = len(Array) #Coefficient functions mu_coef = [mur[mat] for mat in mesh.GetMaterials()] mu = CoefficientFunction(mu_coef) inout_coef = [inorout[mat] for mat in mesh.GetMaterials()] inout = CoefficientFunction(inout_coef) sigma_coef = [sig[mat] for mat in mesh.GetMaterials()] sigma = CoefficientFunction(sigma_coef) #Set up how the tensor and eigenvalues will be stored N0 = np.zeros([3, 3]) PODN0Errors = np.zeros([3, 1]) R = np.zeros([3, 3]) I = np.zeros([3, 3]) TensorArray = np.zeros([NumberofFrequencies, 9], dtype=complex) EigenValues = np.zeros([NumberofFrequencies, 3], dtype=complex) ######################################################################### #Theta0 #This section solves the Theta0 problem to calculate both the inputs for #the Theta1 problem and calculate the N0 tensor #Setup the finite element space fes = HCurl(mesh, order=Order, dirichlet="outer", flags={"nograds": True}) #Count the number of degrees of freedom ndof = fes.ndof #Define the vectors for the right hand side evec = [ CoefficientFunction((1, 0, 0)), CoefficientFunction((0, 1, 0)), CoefficientFunction((0, 0, 1)) ] #Setup the grid functions and array which will be used to save Theta0i = GridFunction(fes) Theta0j = GridFunction(fes) Theta0Sol = np.zeros([ndof, 3]) #Run in three directions and save in an array for later for i in range(3): Theta0Sol[:, i] = Theta0(fes, Order, alpha, mu, inout, evec[i], Tolerance, Maxsteps, epsi, i + 1, Solver) print(' solved theta0 problems ') #Calculate the N0 tensor VolConstant = Integrate(1 - mu**(-1), mesh) for i in range(3): Theta0i.vec.FV().NumPy()[:] = Theta0Sol[:, i] for j in range(i + 1): Theta0j.vec.FV().NumPy()[:] = Theta0Sol[:, j] if i == j: N0[i, j] = (alpha**3) * (VolConstant + (1 / 4) * (Integrate( mu**(-1) * (InnerProduct(curl(Theta0i), curl(Theta0j))), mesh))) else: N0[i, j] = (alpha**3 / 4) * (Integrate( mu**(-1) * (InnerProduct(curl(Theta0i), curl(Theta0j))), mesh)) #Copy the tensor N0 += np.transpose(N0 - np.eye(3) @ N0) ######################################################################### #Theta1 #This section solves the Theta1 problem to calculate the solution vectors #of the snapshots #Setup the finite element space dom_nrs_metal = [0 if mat == "air" else 1 for mat in mesh.GetMaterials()] fes2 = HCurl(mesh, order=Order, dirichlet="outer", complex=True, gradientdomains=dom_nrs_metal) ndof2 = fes2.ndof #Define the vectors for the right hand side xivec = [ CoefficientFunction((0, -z, y)), CoefficientFunction((z, 0, -x)), CoefficientFunction((-y, x, 0)) ] if BigProblem == True: Theta1Sols = np.zeros([ndof2, NumberofSnapshots, 3], dtype=np.complex64) else: Theta1Sols = np.zeros([ndof2, NumberofSnapshots, 3], dtype=complex) if PlotPod == True: PODTensors, PODEigenValues, Theta1Sols[:, :, :] = Theta1_Sweep( PODArray, mesh, fes, fes2, Theta0Sol, xivec, alpha, sigma, mu, inout, Tolerance, Maxsteps, epsi, Solver, N0, NumberofFrequencies, True, True, False, BigProblem) else: Theta1Sols[:, :, :] = Theta1_Sweep(PODArray, mesh, fes, fes2, Theta0Sol, xivec, alpha, sigma, mu, inout, Tolerance, Maxsteps, epsi, Solver, N0, NumberofFrequencies, True, False, False, BigProblem) print(' solved theta1 problems ') ######################################################################### #POD print(' performing SVD ', end='\r') #Perform SVD on the solution vector matrices u1Truncated, s1, vh1 = np.linalg.svd(Theta1Sols[:, :, 0], full_matrices=False) u2Truncated, s2, vh2 = np.linalg.svd(Theta1Sols[:, :, 1], full_matrices=False) u3Truncated, s3, vh3 = np.linalg.svd(Theta1Sols[:, :, 2], full_matrices=False) #Print an update on progress print(' SVD complete ') #scale the value of the modes s1norm = s1 / s1[0] s2norm = s2 / s2[0] s3norm = s3 / s3[0] #Decide where to truncate cutoff = NumberofSnapshots for i in range(NumberofSnapshots): if s1norm[i] < PODTol: if s2norm[i] < PODTol: if s3norm[i] < PODTol: cutoff = i break #Truncate the SVD matrices u1Truncated = u1Truncated[:, :cutoff] u2Truncated = u2Truncated[:, :cutoff] u3Truncated = u3Truncated[:, :cutoff] ######################################################################## #Create the ROM print(' creating reduced order model', end='\r') nu_no_omega = Mu0 * (alpha**2) Theta_0 = GridFunction(fes) u, v = fes2.TnT() if BigProblem == True: a0 = BilinearForm(fes2, symmetric=True) else: a0 = BilinearForm(fes2) a0 += SymbolicBFI((mu**(-1)) * InnerProduct(curl(u), curl(v))) a0 += SymbolicBFI((1j) * (1 - inout) * epsi * InnerProduct(u, v)) if BigProblem == True: a1 = BilinearForm(fes2, symmetric=True) else: a1 = BilinearForm(fes2) a1 += SymbolicBFI((1j) * inout * nu_no_omega * sigma * InnerProduct(u, v)) a0.Assemble() a1.Assemble() Theta_0.vec.FV().NumPy()[:] = Theta0Sol[:, 0] r1 = LinearForm(fes2) r1 += SymbolicLFI(inout * (-1j) * nu_no_omega * sigma * InnerProduct(Theta_0, v)) r1 += SymbolicLFI(inout * (-1j) * nu_no_omega * sigma * InnerProduct(xivec[0], v)) r1.Assemble() read_vec = r1.vec.CreateVector() write_vec = r1.vec.CreateVector() Theta_0.vec.FV().NumPy()[:] = Theta0Sol[:, 1] r2 = LinearForm(fes2) r2 += SymbolicLFI(inout * (-1j) * nu_no_omega * sigma * InnerProduct(Theta_0, v)) r2 += SymbolicLFI(inout * (-1j) * nu_no_omega * sigma * InnerProduct(xivec[1], v)) r2.Assemble() Theta_0.vec.FV().NumPy()[:] = Theta0Sol[:, 2] r3 = LinearForm(fes2) r3 += SymbolicLFI(inout * (-1j) * nu_no_omega * sigma * InnerProduct(Theta_0, v)) r3 += SymbolicLFI(inout * (-1j) * nu_no_omega * sigma * InnerProduct(xivec[2], v)) r3.Assemble() if PODErrorBars == True: fes0 = HCurl(mesh, order=0, dirichlet="outer", complex=True, gradientdomains=dom_nrs_metal) ndof0 = fes0.ndof RerrorReduced1 = np.zeros([ndof0, cutoff * 2 + 1], dtype=complex) RerrorReduced2 = np.zeros([ndof0, cutoff * 2 + 1], dtype=complex) RerrorReduced3 = np.zeros([ndof0, cutoff * 2 + 1], dtype=complex) ProH = GridFunction(fes2) ProL = GridFunction(fes0) ######################################################################## #Create the ROM R1 = r1.vec.FV().NumPy() R2 = r2.vec.FV().NumPy() R3 = r3.vec.FV().NumPy() A0H = np.zeros([ndof2, cutoff], dtype=complex) A1H = np.zeros([ndof2, cutoff], dtype=complex) #E1 for i in range(cutoff): read_vec.FV().NumPy()[:] = u1Truncated[:, i] write_vec.data = a0.mat * read_vec A0H[:, i] = write_vec.FV().NumPy() write_vec.data = a1.mat * read_vec A1H[:, i] = write_vec.FV().NumPy() HA0H1 = (np.conjugate(np.transpose(u1Truncated)) @ A0H) HA1H1 = (np.conjugate(np.transpose(u1Truncated)) @ A1H) HR1 = (np.conjugate(np.transpose(u1Truncated)) @ np.transpose(R1)) if PODErrorBars == True: ProH.vec.FV().NumPy()[:] = R1 ProL.Set(ProH) RerrorReduced1[:, 0] = ProL.vec.FV().NumPy()[:] for i in range(cutoff): ProH.vec.FV().NumPy()[:] = A0H[:, i] ProL.Set(ProH) RerrorReduced1[:, i + 1] = ProL.vec.FV().NumPy()[:] ProH.vec.FV().NumPy()[:] = A1H[:, i] ProL.Set(ProH) RerrorReduced1[:, i + cutoff + 1] = ProL.vec.FV().NumPy()[:] #E2 for i in range(cutoff): read_vec.FV().NumPy()[:] = u2Truncated[:, i] write_vec.data = a0.mat * read_vec A0H[:, i] = write_vec.FV().NumPy() write_vec.data = a1.mat * read_vec A1H[:, i] = write_vec.FV().NumPy() HA0H2 = (np.conjugate(np.transpose(u2Truncated)) @ A0H) HA1H2 = (np.conjugate(np.transpose(u2Truncated)) @ A1H) HR2 = (np.conjugate(np.transpose(u2Truncated)) @ np.transpose(R2)) if PODErrorBars == True: ProH.vec.FV().NumPy()[:] = R2 ProL.Set(ProH) RerrorReduced2[:, 0] = ProL.vec.FV().NumPy()[:] for i in range(cutoff): ProH.vec.FV().NumPy()[:] = A0H[:, i] ProL.Set(ProH) RerrorReduced2[:, i + 1] = ProL.vec.FV().NumPy()[:] ProH.vec.FV().NumPy()[:] = A1H[:, i] ProL.Set(ProH) RerrorReduced2[:, i + cutoff + 1] = ProL.vec.FV().NumPy()[:] #E3 for i in range(cutoff): read_vec.FV().NumPy()[:] = u3Truncated[:, i] write_vec.data = a0.mat * read_vec A0H[:, i] = write_vec.FV().NumPy() write_vec.data = a1.mat * read_vec A1H[:, i] = write_vec.FV().NumPy() HA0H3 = (np.conjugate(np.transpose(u3Truncated)) @ A0H) HA1H3 = (np.conjugate(np.transpose(u3Truncated)) @ A1H) HR3 = (np.conjugate(np.transpose(u3Truncated)) @ np.transpose(R3)) if PODErrorBars == True: ProH.vec.FV().NumPy()[:] = R3 ProL.Set(ProH) RerrorReduced3[:, 0] = ProL.vec.FV().NumPy()[:] for i in range(cutoff): ProH.vec.FV().NumPy()[:] = A0H[:, i] ProL.Set(ProH) RerrorReduced3[:, i + 1] = ProL.vec.FV().NumPy()[:] ProH.vec.FV().NumPy()[:] = A1H[:, i] ProL.Set(ProH) RerrorReduced3[:, i + cutoff + 1] = ProL.vec.FV().NumPy()[:] #Clear the variables A0H, A1H = None, None a0, a1 = None, None ######################################################################## #Sort out the error bounds if PODErrorBars == True: if BigProblem == True: MR1 = np.zeros([ndof0, cutoff * 2 + 1], dtype=np.complex64) MR2 = np.zeros([ndof0, cutoff * 2 + 1], dtype=np.complex64) MR3 = np.zeros([ndof0, cutoff * 2 + 1], dtype=np.complex64) else: MR1 = np.zeros([ndof0, cutoff * 2 + 1], dtype=complex) MR2 = np.zeros([ndof0, cutoff * 2 + 1], dtype=complex) MR3 = np.zeros([ndof0, cutoff * 2 + 1], dtype=complex) u, v = fes0.TnT() m = BilinearForm(fes0) m += SymbolicBFI(InnerProduct(u, v)) f = LinearForm(fes0) m.Assemble() c = Preconditioner(m, "local") c.Update() inverse = CGSolver(m.mat, c.mat, precision=1e-20, maxsteps=500) ErrorGFU = GridFunction(fes0) for i in range(2 * cutoff + 1): #E1 ProL.vec.data.FV().NumPy()[:] = RerrorReduced1[:, i] ProL.vec.data -= m.mat * ErrorGFU.vec ErrorGFU.vec.data += inverse * ProL.vec MR1[:, i] = ErrorGFU.vec.FV().NumPy() #E2 ProL.vec.data.FV().NumPy()[:] = RerrorReduced2[:, i] ProL.vec.data -= m.mat * ErrorGFU.vec ErrorGFU.vec.data += inverse * ProL.vec MR2[:, i] = ErrorGFU.vec.FV().NumPy() #E3 ProL.vec.data.FV().NumPy()[:] = RerrorReduced3[:, i] ProL.vec.data -= m.mat * ErrorGFU.vec ErrorGFU.vec.data += inverse * ProL.vec MR3[:, i] = ErrorGFU.vec.FV().NumPy() G1 = np.transpose(np.conjugate(RerrorReduced1)) @ MR1 G2 = np.transpose(np.conjugate(RerrorReduced2)) @ MR2 G3 = np.transpose(np.conjugate(RerrorReduced3)) @ MR3 G12 = np.transpose(np.conjugate(RerrorReduced1)) @ MR2 G13 = np.transpose(np.conjugate(RerrorReduced1)) @ MR3 G23 = np.transpose(np.conjugate(RerrorReduced2)) @ MR3 #Clear the variables RerrorReduced1, RerrorReduced2, RerrorReduced3 = None, None, None MR1, MR2, MR3 = None, None, None fes0, m, c, inverse = None, None, None, None fes3 = HCurl(mesh, order=Order, dirichlet="outer", gradientdomains=dom_nrs_metal) ndof3 = fes3.ndof Omega = Array[0] u, v = fes3.TnT() amax = BilinearForm(fes3) amax += (mu**(-1)) * curl(u) * curl(v) * dx amax += (1 - inout) * epsi * u * v * dx amax += inout * sigma * (alpha**2) * Mu0 * Omega * u * v * dx m = BilinearForm(fes3) m += u * v * dx apre = BilinearForm(fes3) apre += curl(u) * curl(v) * dx + u * v * dx pre = Preconditioner(amax, "bddc") with TaskManager(): amax.Assemble() m.Assemble() apre.Assemble() # build gradient matrix as sparse matrix (and corresponding scalar FESpace) gradmat, fesh1 = fes3.CreateGradient() gradmattrans = gradmat.CreateTranspose() # transpose sparse matrix math1 = gradmattrans @ m.mat @ gradmat # multiply matrices math1[0, 0] += 1 # fix the 1-dim kernel invh1 = math1.Inverse(inverse="sparsecholesky") # build the Poisson projector with operator Algebra: proj = IdentityMatrix() - gradmat @ invh1 @ gradmattrans @ m.mat projpre = proj @ pre.mat evals, evecs = solvers.PINVIT(amax.mat, m.mat, pre=projpre, num=1, maxit=50) alphaLB = evals[0] #Clear the variables fes3, amax, apre, pre, invh1, m = None, None, None, None, None, None ######################################################################## #Produce the sweep using the lower dimensional space #Setup variables for calculating tensors Theta_0j = GridFunction(fes) Theta_1i = GridFunction(fes2) Theta_1j = GridFunction(fes2) if PODErrorBars == True: rom1 = np.zeros([2 * cutoff + 1, 1], dtype=complex) rom2 = np.zeros([2 * cutoff + 1, 1], dtype=complex) rom3 = np.zeros([2 * cutoff + 1, 1], dtype=complex) ErrorTensors = np.zeros([NumberofFrequencies, 6]) for k, omega in enumerate(Array): #This part is for obtaining the solutions in the lower dimensional space print(' solving reduced order system %d/%d ' % (k + 1, NumberofFrequencies), end='\r') t1 = time.time() g1 = np.linalg.solve(HA0H1 + HA1H1 * omega, HR1 * omega) g2 = np.linalg.solve(HA0H2 + HA1H2 * omega, HR2 * omega) g3 = np.linalg.solve(HA0H3 + HA1H3 * omega, HR3 * omega) #This part projects the problem to the higher dimensional space W1 = np.dot(u1Truncated, g1).flatten() W2 = np.dot(u2Truncated, g2).flatten() W3 = np.dot(u3Truncated, g3).flatten() #Calculate the tensors nu = omega * Mu0 * (alpha**2) R = np.zeros([3, 3]) I = np.zeros([3, 3]) for i in range(3): Theta_0.vec.FV().NumPy()[:] = Theta0Sol[:, i] xii = xivec[i] if i == 0: Theta_1i.vec.FV().NumPy()[:] = W1 if i == 1: Theta_1i.vec.FV().NumPy()[:] = W2 if i == 2: Theta_1i.vec.FV().NumPy()[:] = W3 for j in range(i + 1): Theta_0j.vec.FV().NumPy()[:] = Theta0Sol[:, j] xij = xivec[j] if j == 0: Theta_1j.vec.FV().NumPy()[:] = W1 if j == 1: Theta_1j.vec.FV().NumPy()[:] = W2 if j == 2: Theta_1j.vec.FV().NumPy()[:] = W3 #Real and Imaginary parts R[i, j] = -(((alpha**3) / 4) * Integrate( (mu**(-1)) * (curl(Theta_1j) * Conj(curl(Theta_1i))), mesh)).real I[i, j] = ((alpha**3) / 4) * Integrate( inout * nu * sigma * ((Theta_1j + Theta_0j + xij) * (Conj(Theta_1i) + Theta_0 + xii)), mesh).real R += np.transpose(R - np.diag(np.diag(R))).real I += np.transpose(I - np.diag(np.diag(I))).real #Save in arrays TensorArray[k, :] = (N0 + R + 1j * I).flatten() EigenValues[k, :] = np.sort( np.linalg.eigvals(N0 + R)) + 1j * np.sort(np.linalg.eigvals(I)) if PODErrorBars == True: rom1[0, 0] = omega rom2[0, 0] = omega rom3[0, 0] = omega rom1[1:1 + cutoff, 0] = -g1.flatten() rom2[1:1 + cutoff, 0] = -g2.flatten() rom3[1:1 + cutoff, 0] = -g3.flatten() rom1[1 + cutoff:, 0] = -(g1 * omega).flatten() rom2[1 + cutoff:, 0] = -(g2 * omega).flatten() rom3[1 + cutoff:, 0] = -(g3 * omega).flatten() error1 = np.conjugate(np.transpose(rom1)) @ G1 @ rom1 error2 = np.conjugate(np.transpose(rom2)) @ G2 @ rom2 error3 = np.conjugate(np.transpose(rom3)) @ G3 @ rom3 error12 = np.conjugate(np.transpose(rom1)) @ G12 @ rom2 error13 = np.conjugate(np.transpose(rom1)) @ G13 @ rom3 error23 = np.conjugate(np.transpose(rom2)) @ G23 @ rom3 error1 = abs(error1)**(1 / 2) error2 = abs(error2)**(1 / 2) error3 = abs(error3)**(1 / 2) error12 = error12.real error13 = error13.real error23 = error23.real Errors = [error1, error2, error3, error12, error13, error23] for j in range(6): if j < 3: ErrorTensors[k, j] = ( (alpha**3) / 4) * (Errors[j]**2) / alphaLB else: ErrorTensors[k, j] = -2 * Errors[j] if j == 3: ErrorTensors[k, j] += (Errors[0]**2) + (Errors[1]**2) ErrorTensors[k, j] = ((alpha**3) / (8 * alphaLB)) * ( (Errors[0]**2) + (Errors[1]**2) + ErrorTensors[k, j]) if j == 4: ErrorTensors[k, j] += (Errors[0]**2) + (Errors[2]**2) ErrorTensors[k, j] = ((alpha**3) / (8 * alphaLB)) * ( (Errors[0]**2) + (Errors[1]**2) + ErrorTensors[k, j]) if j == 5: ErrorTensors[k, j] += (Errors[1]**2) + (Errors[2]**2) ErrorTensors[k, j] = ((alpha**3) / (8 * alphaLB)) * ( (Errors[0]**2) + (Errors[1]**2) + ErrorTensors[k, j]) #print(ErrorTensors) print(' reduced order systems solved ') print(' frequency sweep complete') if PlotPod == True: if PODErrorBars == True: return TensorArray, EigenValues, N0, PODTensors, PODEigenValues, numelements, ErrorTensors else: return TensorArray, EigenValues, N0, PODTensors, PODEigenValues, numelements else: if PODErrorBars == True: return TensorArray, EigenValues, N0, numelements, ErrorTensors else: return TensorArray, EigenValues, N0, numelements
rank = MPIManager.GetRank() np = MPIManager.GetNP() print("Hello from rank " + str(rank) + " of " + str(np)) if rank == 0: # master-proc generates mesh mesh = unit_cube.GenerateMesh(maxh=0.1) # and saves it to file mesh.Save("some_mesh.vol") # wait for master to be done meshing MPIManager.Barrier() # now load mesh from file ngmesh = netgen.Mesh(dim=3) ngmesh.Load("some_mesh.vol") #refine once? # ngmesh.Refine() mesh = Mesh(ngmesh) # build H1-FESpace as usual V = H1(mesh, order=3, dirichlet=[1, 2, 3, 4]) u = V.TrialFunction() v = V.TestFunction() print("rank " + str(rank) + " has " + str(V.ndof) + " of " + str(V.ndofglobal) + " dofs!")
def SingleFrequency(Object, Order, alpha, inorout, mur, sig, Omega, CPUs, VTK, Refine): Object = Object[:-4] + ".vol" #Set up the Solver Parameters Solver, epsi, Maxsteps, Tolerance = SolverParameters() #Loading the object file ngmesh = ngmeshing.Mesh(dim=3) ngmesh.Load("VolFiles/" + Object) #Creating the mesh and defining the element types mesh = Mesh("VolFiles/" + Object) mesh.Curve(5) #This can be used to refine the mesh numelements = mesh.ne #Count the number elements print(" mesh contains " + str(numelements) + " elements") #Set up the coefficients #Scalars Mu0 = 4 * np.pi * 10**(-7) #Coefficient functions mu_coef = [mur[mat] for mat in mesh.GetMaterials()] mu = CoefficientFunction(mu_coef) inout_coef = [inorout[mat] for mat in mesh.GetMaterials()] inout = CoefficientFunction(inout_coef) sigma_coef = [sig[mat] for mat in mesh.GetMaterials()] sigma = CoefficientFunction(sigma_coef) #Set up how the tensors will be stored N0 = np.zeros([3, 3]) R = np.zeros([3, 3]) I = np.zeros([3, 3]) ######################################################################### #Theta0 #This section solves the Theta0 problem to calculate both the inputs for #the Theta1 problem and calculate the N0 tensor #Setup the finite element space fes = HCurl(mesh, order=Order, dirichlet="outer", flags={"nograds": True}) #Count the number of degrees of freedom ndof = fes.ndof #Define the vectors for the right hand side evec = [ CoefficientFunction((1, 0, 0)), CoefficientFunction((0, 1, 0)), CoefficientFunction((0, 0, 1)) ] #Setup the grid functions and array which will be used to save Theta0i = GridFunction(fes) Theta0j = GridFunction(fes) Theta0Sol = np.zeros([ndof, 3]) #Setup the inputs for the functions to run Runlist = [] for i in range(3): if CPUs < 3: NewInput = (fes, Order, alpha, mu, inout, evec[i], Tolerance, Maxsteps, epsi, i + 1, Solver) else: NewInput = (fes, Order, alpha, mu, inout, evec[i], Tolerance, Maxsteps, epsi, "No Count", Solver) Runlist.append(NewInput) #Run on the multiple cores with multiprocessing.Pool(CPUs) as pool: Output = pool.starmap(Theta0, Runlist) print(' solved theta0 problem ') #Unpack the outputs for i, Direction in enumerate(Output): Theta0Sol[:, i] = Direction #Calculate the N0 tensor VolConstant = Integrate(1 - mu**(-1), mesh) for i in range(3): Theta0i.vec.FV().NumPy()[:] = Theta0Sol[:, i] for j in range(3): Theta0j.vec.FV().NumPy()[:] = Theta0Sol[:, j] if i == j: N0[i, j] = (alpha**3) * (VolConstant + (1 / 4) * (Integrate( mu**(-1) * (InnerProduct(curl(Theta0i), curl(Theta0j))), mesh))) else: N0[i, j] = (alpha**3 / 4) * (Integrate( mu**(-1) * (InnerProduct(curl(Theta0i), curl(Theta0j))), mesh)) ######################################################################### #Theta1 #This section solves the Theta1 problem and saves the solution vectors #Setup the finite element space dom_nrs_metal = [0 if mat == "air" else 1 for mat in mesh.GetMaterials()] fes2 = HCurl(mesh, order=Order, dirichlet="outer", complex=True, gradientdomains=dom_nrs_metal) #Count the number of degrees of freedom ndof2 = fes2.ndof #Define the vectors for the right hand side xivec = [ CoefficientFunction((0, -z, y)), CoefficientFunction((z, 0, -x)), CoefficientFunction((-y, x, 0)) ] #Setup the array which will be used to store the solution vectors Theta1Sol = np.zeros([ndof2, 3], dtype=complex) #Set up the inputs for the problem Runlist = [] nu = Omega * Mu0 * (alpha**2) for i in range(3): if CPUs < 3: NewInput = (fes, fes2, Theta0Sol[:, i], xivec[i], Order, alpha, nu, sigma, mu, inout, Tolerance, Maxsteps, epsi, Omega, i + 1, 3, Solver) else: NewInput = (fes, fes2, Theta0Sol[:, i], xivec[i], Order, alpha, nu, sigma, mu, inout, Tolerance, Maxsteps, epsi, Omega, "No Print", 3, Solver) Runlist.append(NewInput) #Run on the multiple cores with multiprocessing.Pool(CPUs) as pool: Output = pool.starmap(Theta1, Runlist) print(' solved theta1 problem ') #Unpack the outputs for i, OutputNumber in enumerate(Output): Theta1Sol[:, i] = OutputNumber #Create the VTK output if required if VTK == True: print(' creating vtk output', end='\r') ThetaE1 = GridFunction(fes2) ThetaE2 = GridFunction(fes2) ThetaE3 = GridFunction(fes2) ThetaE1.vec.FV().NumPy()[:] = Output[0] ThetaE2.vec.FV().NumPy()[:] = Output[1] ThetaE3.vec.FV().NumPy()[:] = Output[2] E1Mag = CoefficientFunction( sqrt( InnerProduct(ThetaE1.real, ThetaE1.real) + InnerProduct(ThetaE1.imag, ThetaE1.imag))) E2Mag = CoefficientFunction( sqrt( InnerProduct(ThetaE2.real, ThetaE2.real) + InnerProduct(ThetaE2.imag, ThetaE2.imag))) E3Mag = CoefficientFunction( sqrt( InnerProduct(ThetaE3.real, ThetaE3.real) + InnerProduct(ThetaE3.imag, ThetaE3.imag))) Sols = [] Sols.append(dom_nrs_metal) Sols.append((ThetaE1 * 1j * Omega * sigma).real) Sols.append((ThetaE1 * 1j * Omega * sigma).imag) Sols.append((ThetaE2 * 1j * Omega * sigma).real) Sols.append((ThetaE2 * 1j * Omega * sigma).imag) Sols.append((ThetaE3 * 1j * Omega * sigma).real) Sols.append((ThetaE3 * 1j * Omega * sigma).imag) Sols.append(E1Mag * Omega * sigma) Sols.append(E2Mag * Omega * sigma) Sols.append(E3Mag * Omega * sigma) savename = "Results/vtk_output/" + Object[:-4] + "/om_" + FtoS( Omega) + "/" if Refine == True: vtk = VTKOutput(ma=mesh, coefs=Sols, names=[ "Object", "E1real", "E1imag", "E2real", "E2imag", "E3real", "E3imag", "E1Mag", "E2Mag", "E3Mag" ], filename=savename + Object[:-4], subdivision=3) else: vtk = VTKOutput(ma=mesh, coefs=Sols, names=[ "Object", "E1real", "E1imag", "E2real", "E2imag", "E3real", "E3imag", "E1Mag", "E2Mag", "E3Mag" ], filename=savename + Object[:-4], subdivision=0) vtk.Do() print(' vtk output created ') ######################################################################### #Calculate the tensor and eigenvalues #Create the inputs for the calculation of the tensors print(' calculating the tensor ', end='\r') Runlist = [] nu = Omega * Mu0 * (alpha**2) R, I = MPTCalculator(mesh, fes, fes2, Theta1Sol[:, 0], Theta1Sol[:, 1], Theta1Sol[:, 2], Theta0Sol, xivec, alpha, mu, sigma, inout, nu, "No Print", 1) print(' calculated the tensor ') #Unpack the outputs MPT = N0 + R + 1j * I RealEigenvalues = np.sort(np.linalg.eigvals(N0 + R)) ImaginaryEigenvalues = np.sort(np.linalg.eigvals(I)) EigenValues = RealEigenvalues + 1j * ImaginaryEigenvalues return MPT, EigenValues, N0, numelements
def PODSweepMulti(Object, Order, alpha, inorout, mur, sig, Array, PODArray, PODTol, PlotPod, CPUs, sweepname, SavePOD, PODErrorBars, BigProblem): Object = Object[:-4] + ".vol" #Set up the Solver Parameters Solver, epsi, Maxsteps, Tolerance = SolverParameters() #Loading the object file ngmesh = ngmeshing.Mesh(dim=3) ngmesh.Load("VolFiles/" + Object) #Creating the mesh and defining the element types mesh = Mesh("VolFiles/" + Object) mesh.Curve(5) #This can be used to refine the mesh numelements = mesh.ne #Count the number elements print(" mesh contains " + str(numelements) + " elements") #Set up the coefficients #Scalars Mu0 = 4 * np.pi * 10**(-7) NumberofSnapshots = len(PODArray) NumberofFrequencies = len(Array) #Coefficient functions mu_coef = [mur[mat] for mat in mesh.GetMaterials()] mu = CoefficientFunction(mu_coef) inout_coef = [inorout[mat] for mat in mesh.GetMaterials()] inout = CoefficientFunction(inout_coef) sigma_coef = [sig[mat] for mat in mesh.GetMaterials()] sigma = CoefficientFunction(sigma_coef) #Set up how the tensor and eigenvalues will be stored N0 = np.zeros([3, 3]) TensorArray = np.zeros([NumberofFrequencies, 9], dtype=complex) RealEigenvalues = np.zeros([NumberofFrequencies, 3]) ImaginaryEigenvalues = np.zeros([NumberofFrequencies, 3]) EigenValues = np.zeros([NumberofFrequencies, 3], dtype=complex) ######################################################################### #Theta0 #This section solves the Theta0 problem to calculate both the inputs for #the Theta1 problem and calculate the N0 tensor #Setup the finite element space fes = HCurl(mesh, order=Order, dirichlet="outer", flags={"nograds": True}) #Count the number of degrees of freedom ndof = fes.ndof #Define the vectors for the right hand side evec = [ CoefficientFunction((1, 0, 0)), CoefficientFunction((0, 1, 0)), CoefficientFunction((0, 0, 1)) ] #Setup the grid functions and array which will be used to save Theta0i = GridFunction(fes) Theta0j = GridFunction(fes) Theta0Sol = np.zeros([ndof, 3]) #Setup the inputs for the functions to run Theta0CPUs = min(3, multiprocessing.cpu_count(), CPUs) Runlist = [] for i in range(3): if Theta0CPUs < 3: NewInput = (fes, Order, alpha, mu, inout, evec[i], Tolerance, Maxsteps, epsi, i + 1, Solver) else: NewInput = (fes, Order, alpha, mu, inout, evec[i], Tolerance, Maxsteps, epsi, "No Print", Solver) Runlist.append(NewInput) #Run on the multiple cores with multiprocessing.Pool(Theta0CPUs) as pool: Output = pool.starmap(Theta0, Runlist) print(' solved theta0 problems ') #Unpack the outputs for i, Direction in enumerate(Output): Theta0Sol[:, i] = Direction #Calculate the N0 tensor VolConstant = Integrate(1 - mu**(-1), mesh) for i in range(3): Theta0i.vec.FV().NumPy()[:] = Theta0Sol[:, i] for j in range(3): Theta0j.vec.FV().NumPy()[:] = Theta0Sol[:, j] if i == j: N0[i, j] = (alpha**3) * (VolConstant + (1 / 4) * (Integrate( mu**(-1) * (InnerProduct(curl(Theta0i), curl(Theta0j))), mesh))) else: N0[i, j] = (alpha**3 / 4) * (Integrate( mu**(-1) * (InnerProduct(curl(Theta0i), curl(Theta0j))), mesh)) ######################################################################### #Theta1 #This section solves the Theta1 problem and saves the solution vectors #Setup the finite element space dom_nrs_metal = [0 if mat == "air" else 1 for mat in mesh.GetMaterials()] fes2 = HCurl(mesh, order=Order, dirichlet="outer", complex=True, gradientdomains=dom_nrs_metal) #Count the number of degrees of freedom ndof2 = fes2.ndof #Define the vectors for the right hand side xivec = [ CoefficientFunction((0, -z, y)), CoefficientFunction((z, 0, -x)), CoefficientFunction((-y, x, 0)) ] #Work out where to send each frequency Theta1_CPUs = min(NumberofSnapshots, multiprocessing.cpu_count(), CPUs) Core_Distribution = [] Count_Distribution = [] for i in range(Theta1_CPUs): Core_Distribution.append([]) Count_Distribution.append([]) #Distribute between the cores CoreNumber = 0 count = 1 for i, Omega in enumerate(PODArray): Core_Distribution[CoreNumber].append(Omega) Count_Distribution[CoreNumber].append(i) if CoreNumber == CPUs - 1 and count == 1: count = -1 elif CoreNumber == 0 and count == -1: count = 1 else: CoreNumber += count #Create the inputs Runlist = [] manager = multiprocessing.Manager() counter = manager.Value('i', 0) for i in range(Theta1_CPUs): if PlotPod == True: Runlist.append( (Core_Distribution[i], mesh, fes, fes2, Theta0Sol, xivec, alpha, sigma, mu, inout, Tolerance, Maxsteps, epsi, Solver, N0, NumberofSnapshots, True, True, counter, BigProblem)) else: Runlist.append( (Core_Distribution[i], mesh, fes, fes2, Theta0Sol, xivec, alpha, sigma, mu, inout, Tolerance, Maxsteps, epsi, Solver, N0, NumberofSnapshots, True, False, counter, BigProblem)) #Run on the multiple cores with multiprocessing.Pool(Theta1_CPUs) as pool: Outputs = pool.starmap(Theta1_Sweep, Runlist) #Unpack the results if BigProblem == True: Theta1Sols = np.zeros([ndof2, NumberofSnapshots, 3], dtype=np.complex64) else: Theta1Sols = np.zeros([ndof2, NumberofSnapshots, 3], dtype=complex) if PlotPod == True: PODTensors = np.zeros([NumberofSnapshots, 9], dtype=complex) PODEigenValues = np.zeros([NumberofSnapshots, 3], dtype=complex) for i, Output in enumerate(Outputs): for j, Num in enumerate(Count_Distribution[i]): if PlotPod == True: PODTensors[Num, :] = Output[0][j] PODEigenValues[Num, :] = Output[1][j] Theta1Sols[:, Num, :] = Output[2][:, j, :] else: Theta1Sols[:, Num, :] = Output[:, j, :] ######################################################################### #POD print(' performing SVD ', end='\r') #Perform SVD on the solution vector matrices u1Truncated, s1, vh1 = np.linalg.svd(Theta1Sols[:, :, 0], full_matrices=False) u2Truncated, s2, vh2 = np.linalg.svd(Theta1Sols[:, :, 1], full_matrices=False) u3Truncated, s3, vh3 = np.linalg.svd(Theta1Sols[:, :, 2], full_matrices=False) #Get rid of the solution vectors Theta1Sols = None #Print an update on progress print(' SVD complete ') #scale the value of the modes s1norm = s1 / s1[0] s2norm = s2 / s2[0] s3norm = s3 / s3[0] #Decide where to truncate cutoff = NumberofSnapshots for i in range(NumberofSnapshots): if s1norm[i] < PODTol: if s2norm[i] < PODTol: if s3norm[i] < PODTol: cutoff = i break #Truncate the SVD matrices u1Truncated = u1Truncated[:, :cutoff] u2Truncated = u2Truncated[:, :cutoff] u3Truncated = u3Truncated[:, :cutoff] ######################################################################## #Create the ROM print(' creating reduced order model', end='\r') #Mu0=4*np.pi*10**(-7) nu_no_omega = Mu0 * (alpha**2) Theta_0 = GridFunction(fes) u, v = fes2.TnT() if BigProblem == True: a0 = BilinearForm(fes2, symmetric=True) else: a0 = BilinearForm(fes2) a0 += SymbolicBFI((mu**(-1)) * InnerProduct(curl(u), curl(v))) a0 += SymbolicBFI((1j) * (1 - inout) * epsi * InnerProduct(u, v)) if BigProblem == True: a1 = BilinearForm(fes2, symmetric=True) else: a1 = BilinearForm(fes2) a1 += SymbolicBFI((1j) * inout * nu_no_omega * sigma * InnerProduct(u, v)) a0.Assemble() a1.Assemble() Theta_0.vec.FV().NumPy()[:] = Theta0Sol[:, 0] r1 = LinearForm(fes2) r1 += SymbolicLFI(inout * (-1j) * nu_no_omega * sigma * InnerProduct(Theta_0, v)) r1 += SymbolicLFI(inout * (-1j) * nu_no_omega * sigma * InnerProduct(xivec[0], v)) r1.Assemble() read_vec = r1.vec.CreateVector() write_vec = r1.vec.CreateVector() Theta_0.vec.FV().NumPy()[:] = Theta0Sol[:, 1] r2 = LinearForm(fes2) r2 += SymbolicLFI(inout * (-1j) * nu_no_omega * sigma * InnerProduct(Theta_0, v)) r2 += SymbolicLFI(inout * (-1j) * nu_no_omega * sigma * InnerProduct(xivec[1], v)) r2.Assemble() Theta_0.vec.FV().NumPy()[:] = Theta0Sol[:, 2] r3 = LinearForm(fes2) r3 += SymbolicLFI(inout * (-1j) * nu_no_omega * sigma * InnerProduct(Theta_0, v)) r3 += SymbolicLFI(inout * (-1j) * nu_no_omega * sigma * InnerProduct(xivec[2], v)) r3.Assemble() if PODErrorBars == True: fes0 = HCurl(mesh, order=0, dirichlet="outer", complex=True, gradientdomains=dom_nrs_metal) ndof0 = fes0.ndof RerrorReduced1 = np.zeros([ndof0, cutoff * 2 + 1], dtype=complex) RerrorReduced2 = np.zeros([ndof0, cutoff * 2 + 1], dtype=complex) RerrorReduced3 = np.zeros([ndof0, cutoff * 2 + 1], dtype=complex) ProH = GridFunction(fes2) ProL = GridFunction(fes0) ######################################################################## #Create the ROM R1 = r1.vec.FV().NumPy() R2 = r2.vec.FV().NumPy() R3 = r3.vec.FV().NumPy() A0H = np.zeros([ndof2, cutoff], dtype=complex) A1H = np.zeros([ndof2, cutoff], dtype=complex) #E1 for i in range(cutoff): read_vec.FV().NumPy()[:] = u1Truncated[:, i] write_vec.data = a0.mat * read_vec A0H[:, i] = write_vec.FV().NumPy() write_vec.data = a1.mat * read_vec A1H[:, i] = write_vec.FV().NumPy() HA0H1 = (np.conjugate(np.transpose(u1Truncated)) @ A0H) HA1H1 = (np.conjugate(np.transpose(u1Truncated)) @ A1H) HR1 = (np.conjugate(np.transpose(u1Truncated)) @ np.transpose(R1)) if PODErrorBars == True: ProH.vec.FV().NumPy()[:] = R1 ProL.Set(ProH) RerrorReduced1[:, 0] = ProL.vec.FV().NumPy()[:] for i in range(cutoff): ProH.vec.FV().NumPy()[:] = A0H[:, i] ProL.Set(ProH) RerrorReduced1[:, i + 1] = ProL.vec.FV().NumPy()[:] ProH.vec.FV().NumPy()[:] = A1H[:, i] ProL.Set(ProH) RerrorReduced1[:, i + cutoff + 1] = ProL.vec.FV().NumPy()[:] #E2 for i in range(cutoff): read_vec.FV().NumPy()[:] = u2Truncated[:, i] write_vec.data = a0.mat * read_vec A0H[:, i] = write_vec.FV().NumPy() write_vec.data = a1.mat * read_vec A1H[:, i] = write_vec.FV().NumPy() HA0H2 = (np.conjugate(np.transpose(u2Truncated)) @ A0H) HA1H2 = (np.conjugate(np.transpose(u2Truncated)) @ A1H) HR2 = (np.conjugate(np.transpose(u2Truncated)) @ np.transpose(R2)) if PODErrorBars == True: ProH.vec.FV().NumPy()[:] = R2 ProL.Set(ProH) RerrorReduced2[:, 0] = ProL.vec.FV().NumPy()[:] for i in range(cutoff): ProH.vec.FV().NumPy()[:] = A0H[:, i] ProL.Set(ProH) RerrorReduced2[:, i + 1] = ProL.vec.FV().NumPy()[:] ProH.vec.FV().NumPy()[:] = A1H[:, i] ProL.Set(ProH) RerrorReduced2[:, i + cutoff + 1] = ProL.vec.FV().NumPy()[:] #E3 for i in range(cutoff): read_vec.FV().NumPy()[:] = u3Truncated[:, i] write_vec.data = a0.mat * read_vec A0H[:, i] = write_vec.FV().NumPy() write_vec.data = a1.mat * read_vec A1H[:, i] = write_vec.FV().NumPy() HA0H3 = (np.conjugate(np.transpose(u3Truncated)) @ A0H) HA1H3 = (np.conjugate(np.transpose(u3Truncated)) @ A1H) HR3 = (np.conjugate(np.transpose(u3Truncated)) @ np.transpose(R3)) if PODErrorBars == True: ProH.vec.FV().NumPy()[:] = R3 ProL.Set(ProH) RerrorReduced3[:, 0] = ProL.vec.FV().NumPy()[:] for i in range(cutoff): ProH.vec.FV().NumPy()[:] = A0H[:, i] ProL.Set(ProH) RerrorReduced3[:, i + 1] = ProL.vec.FV().NumPy()[:] ProH.vec.FV().NumPy()[:] = A1H[:, i] ProL.Set(ProH) RerrorReduced3[:, i + cutoff + 1] = ProL.vec.FV().NumPy()[:] #Clear the variables A0H, A1H = None, None a0, a1 = None, None ######################################################################## #Sort out the error bounds if PODErrorBars == True: if BigProblem == True: MR1 = np.zeros([ndof0, cutoff * 2 + 1], dtype=np.complex64) MR2 = np.zeros([ndof0, cutoff * 2 + 1], dtype=np.complex64) MR3 = np.zeros([ndof0, cutoff * 2 + 1], dtype=np.complex64) else: MR1 = np.zeros([ndof0, cutoff * 2 + 1], dtype=complex) MR2 = np.zeros([ndof0, cutoff * 2 + 1], dtype=complex) MR3 = np.zeros([ndof0, cutoff * 2 + 1], dtype=complex) u, v = fes0.TnT() m = BilinearForm(fes0) m += SymbolicBFI(InnerProduct(u, v)) f = LinearForm(fes0) m.Assemble() c = Preconditioner(m, "local") c.Update() inverse = CGSolver(m.mat, c.mat, precision=1e-20, maxsteps=500) ErrorGFU = GridFunction(fes0) for i in range(2 * cutoff + 1): #E1 ProL.vec.data.FV().NumPy()[:] = RerrorReduced1[:, i] ProL.vec.data -= m.mat * ErrorGFU.vec ErrorGFU.vec.data += inverse * ProL.vec MR1[:, i] = ErrorGFU.vec.FV().NumPy() #E2 ProL.vec.data.FV().NumPy()[:] = RerrorReduced2[:, i] ProL.vec.data -= m.mat * ErrorGFU.vec ErrorGFU.vec.data += inverse * ProL.vec MR2[:, i] = ErrorGFU.vec.FV().NumPy() #E3 ProL.vec.data.FV().NumPy()[:] = RerrorReduced3[:, i] ProL.vec.data -= m.mat * ErrorGFU.vec ErrorGFU.vec.data += inverse * ProL.vec MR3[:, i] = ErrorGFU.vec.FV().NumPy() G_Store = np.zeros([2 * cutoff + 1, 2 * cutoff + 1, 6], dtype=complex) G_Store[:, :, 0] = np.transpose(np.conjugate(RerrorReduced1)) @ MR1 G_Store[:, :, 1] = np.transpose(np.conjugate(RerrorReduced2)) @ MR2 G_Store[:, :, 2] = np.transpose(np.conjugate(RerrorReduced3)) @ MR3 G_Store[:, :, 3] = np.transpose(np.conjugate(RerrorReduced1)) @ MR2 G_Store[:, :, 4] = np.transpose(np.conjugate(RerrorReduced1)) @ MR3 G_Store[:, :, 5] = np.transpose(np.conjugate(RerrorReduced2)) @ MR3 #Clear the variables RerrorReduced1, RerrorReduced2, RerrorReduced3 = None, None, None MR1, MR2, MR3 = None, None, None fes0, m, c, inverse = None, None, None, None fes3 = HCurl(mesh, order=Order, dirichlet="outer", gradientdomains=dom_nrs_metal) ndof3 = fes3.ndof Omega = Array[0] u, v = fes3.TnT() amax = BilinearForm(fes3) amax += (mu**(-1)) * curl(u) * curl(v) * dx amax += (1 - inout) * epsi * u * v * dx amax += inout * sigma * (alpha**2) * Mu0 * Omega * u * v * dx m = BilinearForm(fes3) m += u * v * dx apre = BilinearForm(fes3) apre += curl(u) * curl(v) * dx + u * v * dx pre = Preconditioner(amax, "bddc") with TaskManager(): amax.Assemble() m.Assemble() apre.Assemble() # build gradient matrix as sparse matrix (and corresponding scalar FESpace) gradmat, fesh1 = fes3.CreateGradient() gradmattrans = gradmat.CreateTranspose() # transpose sparse matrix math1 = gradmattrans @ m.mat @ gradmat # multiply matrices math1[0, 0] += 1 # fix the 1-dim kernel invh1 = math1.Inverse(inverse="sparsecholesky") # build the Poisson projector with operator Algebra: proj = IdentityMatrix() - gradmat @ invh1 @ gradmattrans @ m.mat projpre = proj @ pre.mat evals, evecs = solvers.PINVIT(amax.mat, m.mat, pre=projpre, num=1, maxit=50) alphaLB = evals[0] else: alphaLB, G_Store = False, False #Clear the variables fes3, amax, apre, pre, invh1, m = None, None, None, None, None, None ###################################################################### #Produce the sweep on the lower dimensional space g = np.zeros([cutoff, NumberofFrequencies, 3], dtype=complex) for k, omega in enumerate(Array): g[:, k, 0] = np.linalg.solve(HA0H1 + HA1H1 * omega, HR1 * omega) g[:, k, 1] = np.linalg.solve(HA0H2 + HA1H2 * omega, HR2 * omega) g[:, k, 2] = np.linalg.solve(HA0H3 + HA1H3 * omega, HR3 * omega) #Work out where to send each frequency Tensor_CPUs = min(NumberofFrequencies, multiprocessing.cpu_count(), CPUs) Core_Distribution = [] Count_Distribution = [] for i in range(Tensor_CPUs): Core_Distribution.append([]) Count_Distribution.append([]) #Distribute frequencies between the cores CoreNumber = 0 for i, Omega in enumerate(Array): Core_Distribution[CoreNumber].append(Omega) Count_Distribution[CoreNumber].append(i) if CoreNumber == Tensor_CPUs - 1: CoreNumber = 0 else: CoreNumber += 1 #Distribute the lower dimensional solutions Lower_Sols = [] for i in range(Tensor_CPUs): TempArray = np.zeros([cutoff, len(Count_Distribution[i]), 3], dtype=complex) for j, Sim in enumerate(Count_Distribution[i]): TempArray[:, j, :] = g[:, Sim, :] Lower_Sols.append(TempArray) #Cteate the inputs Runlist = [] manager = multiprocessing.Manager() counter = manager.Value('i', 0) for i in range(Tensor_CPUs): Runlist.append( (Core_Distribution[i], mesh, fes, fes2, Lower_Sols[i], u1Truncated, u2Truncated, u3Truncated, Theta0Sol, xivec, alpha, sigma, mu, inout, N0, NumberofFrequencies, counter, PODErrorBars, alphaLB, G_Store)) #Run on the multiple cores with multiprocessing.Pool(Tensor_CPUs) as pool: Outputs = pool.starmap(Theta1_Lower_Sweep, Runlist) #Unpack the outputs if PODErrorBars == True: ErrorTensors = np.zeros([NumberofFrequencies, 6]) for i, Output in enumerate(Outputs): for j, Num in enumerate(Count_Distribution[i]): if PODErrorBars == True: TensorArray[Num, :] = Output[0][j] EigenValues[Num, :] = Output[1][j] ErrorTensors[Num, :] = Output[2][j] else: TensorArray[Num, :] = Output[0][j] EigenValues[Num, :] = Output[1][j] print(' reduced order systems solved ') print(' frequency sweep complete') if PlotPod == True: if PODErrorBars == True: return TensorArray, EigenValues, N0, PODTensors, PODEigenValues, numelements, ErrorTensors else: return TensorArray, EigenValues, N0, PODTensors, PODEigenValues, numelements else: if PODErrorBars == True: return TensorArray, EigenValues, N0, numelements, ErrorTensors else: return TensorArray, EigenValues, N0, numelements
from math import pi from time import sleep import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation import ngsolve as ngs import netgen.meshing as ngm from ngsolve import x, grad, exp from ngsolve.internal import viewoptions, visoptions viewoptions.drawedges = '1' visoptions.scaledeform1 = '100' ## 1D Mesh m = ngm.Mesh() m.dim = 1 n_elems = 1000 x_min = -50 x_max = 50 length = x_max - x_min pnums = [] xs = [] for i in range(0, n_elems + 1): pnt_x = x_min + length * i / n_elems xs.append(pnt_x) pnums.append(m.Add(ngm.MeshPoint(ngm.Pnt(pnt_x, 0, 0)))) for i in range(0, n_elems): m.Add(ngm.Element1D([pnums[i], pnums[i + 1]], index=1))
def get_Netgen_nonconformal(N, scale, offset, dim=2): """ Generate a structured quadrilateral/hexahedral NGSolve mesh over a prescribed square/cubic domain. Args: N (list): Number of mesh elements in each direction (N+1 nodes). scale (list): Extent of the meshed domain in each direction ([-2,2] square -> scale=[4,4]). offset (list): Centers the meshed domain in each direction ([-2,2] square -> offset=[2,2]). dim (int): Dimension of the domain (must be 2 or 3). Returns: mesh (Netgen mesh): Structured quadrilateral/hexahedral Netgen mesh. """ # Construct a Netgen mesh. ngmesh = ngmsh.Mesh() if dim == 2: ngmesh.SetGeometry(unit_square) ngmesh.dim = 2 # Set evenly spaced mesh nodes. points = [] for i in range(N[1] + 1): for j in range(N[0] + 1): x = -offset[0] + scale[0] * j / N[0] y = -offset[1] + scale[1] * i / N[1] z = 0 points.append(ngmesh.Add(ngmsh.MeshPoint(ngmsh.Pnt(x, y, z)))) # TODO: Should the user be able to set their own BC names? idx_dom = ngmesh.AddRegion('dom', dim=2) idx_bottom = ngmesh.AddRegion('bottom', dim=1) idx_right = ngmesh.AddRegion('right', dim=1) idx_top = ngmesh.AddRegion('top', dim=1) idx_left = ngmesh.AddRegion('left', dim=1) # Generate mesh faces. for i in range(N[1]): for j in range(N[0]): p1 = i * (N[0] + 1) + j p2 = i * (N[0] + 1) + j + 1 p3 = i * (N[0] + 1) + j + 2 + N[0] p4 = i * (N[0] + 1) + j + 1 + N[0] ngmesh.Add(ngmsh.Element2D(idx_dom, [points[p1], points[p2], points[p3], points[p4]])) # Assign each edge of the domain to the same boundary. for i in range(N[1]): ngmesh.Add(ngmsh.Element1D([points[N[0] + i * (N[0] + 1)], points[N[0] + (i + 1) * (N[0] + 1)]], index=idx_right)) ngmesh.Add(ngmsh.Element1D([points[(i + 1) * (N[0] + 1)], points[i * (N[0] + 1)]], index=idx_left)) for i in range(N[0]): ngmesh.Add(ngmsh.Element1D([points[i], points[i + 1]], index=idx_bottom)) ngmesh.Add(ngmsh.Element1D([points[1 + i + N[1] * (N[0] + 1)], points[i + N[1] * (N[0] + 1)]], index=idx_top)) elif dim == 3: ngmesh.dim = 3 p1 = (0, 0, 0) p2 = (1, 1, 1) cube = ngcsg.OrthoBrick(ngcsg.Pnt(p1[0], p1[1], p1[2]), ngcsg.Pnt(p2[0], p2[1], p2[2])).bc(1) geo = ngcsg.CSGeometry() geo.Add(cube) ngmesh.SetGeometry(geo) # Set evenly spaced mesh nodes. points = [] for i in range(N[0] + 1): for j in range(N[1] + 1): for k in range(N[2] + 1): x = -offset[0] + scale[0] * i / N[0] y = -offset[1] + scale[1] * j / N[1] z = -offset[2] + scale[2] * k / N[2] points.append(ngmesh.Add(ngmsh.MeshPoint(ngmsh.Pnt(x, y, z)))) # Generate mesh cells. for i in range(N[0]): for j in range(N[1]): for k in range(N[2]): base = i * (N[1] + 1) * (N[2] + 1) + j * (N[2] + 1) + k baseup = base + (N[1] + 1) * (N[2] + 1) p1 = base p2 = base + 1 p3 = base + (N[2] + 1) + 1 p4 = base + (N[2] + 1) p5 = baseup p6 = baseup + 1 p7 = baseup + (N[2] + 1) + 1 p8 = baseup + (N[2] + 1) idx = 1 ngmesh.Add(ngmsh.Element3D(idx, [points[p1], points[p2], points[p3], points[p4], points[p5], points[p6], points[p7], points[p8]])) def add_bc(p, d, N, deta, neta, facenr): def add_seg(i, j, os): base = p + i * d + j * deta p1 = base p2 = base + os ngmesh.Add(ngmsh.Element1D([points[p1], points[p2]], index=facenr)) return for i in range(N): for j in [0, neta]: add_seg(i, j, d) for i in [0, N]: for j in range(neta): add_seg(i, j, deta) for i in range(N): for j in range(neta): base = p + i * d + j * deta p1 = base p2 = base + d p3 = base + d + deta p4 = base + deta ngmesh.Add(ngmsh.Element2D(facenr, [points[p1], points[p2], points[p3], points[p4]])) return # Order is important! ngmesh.Add(ngmsh.FaceDescriptor(surfnr=4, domin=1, bc=1)) ngmesh.Add(ngmsh.FaceDescriptor(surfnr=2, domin=1, bc=2)) ngmesh.Add(ngmsh.FaceDescriptor(surfnr=5, domin=1, bc=3)) ngmesh.Add(ngmsh.FaceDescriptor(surfnr=3, domin=1, bc=4)) ngmesh.Add(ngmsh.FaceDescriptor(surfnr=0, domin=1, bc=5)) ngmesh.Add(ngmsh.FaceDescriptor(surfnr=1, domin=1, bc=6)) # Assign each exterior face of the domain to its respective boundary. add_bc(0, 1, N[2], N[2] + 1, N[1], 1) add_bc(0, (N[1] + 1) * (N[2] + 1), N[0], 1, N[2], 2) add_bc((N[0] + 1) * (N[1] + 1) * (N[2] + 1) - 1, -(N[2] + 1), N[1], -1, N[2], 3) add_bc((N[0] + 1) * (N[1] + 1) * (N[2] + 1) - 1, -1, N[2], -(N[1] + 1) * (N[2] + 1), N[0], 4) add_bc(0, N[2] + 1, N[1], (N[1] + 1) * (N[2] + 1), N[0], 5) add_bc((N[0] + 1) * (N[1] + 1) * (N[2] + 1) - 1, -(N[1] + 1) * (N[2] + 1), N[0], -(N[2] + 1), N[1], 6) # TODO: Should the user be able to specify their own bc names? bc_names = {0: 'back', 1: 'left', 2: 'front', 3: 'right', 4: 'bottom', 5: 'top'} for key, val in bc_names.items(): ngmesh.SetBCName(key, val) else: raise ValueError('Only works with 2D or 3D meshes.') return ngmesh
def FullSweepMulti(Object, Order, alpha, inorout, mur, sig, Array, CPUs, BigProblem): Object = Object[:-4] + ".vol" #Set up the Solver Parameters Solver, epsi, Maxsteps, Tolerance = SolverParameters() #Loading the object file ngmesh = ngmeshing.Mesh(dim=3) ngmesh.Load("VolFiles/" + Object) #Creating the mesh and defining the element types mesh = Mesh("VolFiles/" + Object) mesh.Curve(5) #This can be used to refine the mesh numelements = mesh.ne #Count the number elements print(" mesh contains " + str(numelements) + " elements") #Set up the coefficients #Scalars Mu0 = 4 * np.pi * 10**(-7) NumberofFrequencies = len(Array) #Coefficient functions mu_coef = [mur[mat] for mat in mesh.GetMaterials()] mu = CoefficientFunction(mu_coef) inout_coef = [inorout[mat] for mat in mesh.GetMaterials()] inout = CoefficientFunction(inout_coef) sigma_coef = [sig[mat] for mat in mesh.GetMaterials()] sigma = CoefficientFunction(sigma_coef) #Set up how the tensor and eigenvalues will be stored N0 = np.zeros([3, 3]) TensorArray = np.zeros([NumberofFrequencies, 9], dtype=complex) RealEigenvalues = np.zeros([NumberofFrequencies, 3]) ImaginaryEigenvalues = np.zeros([NumberofFrequencies, 3]) EigenValues = np.zeros([NumberofFrequencies, 3], dtype=complex) ######################################################################### #Theta0 #This section solves the Theta0 problem to calculate both the inputs for #the Theta1 problem and calculate the N0 tensor #Setup the finite element space fes = HCurl(mesh, order=Order, dirichlet="outer", flags={"nograds": True}) #Count the number of degrees of freedom ndof = fes.ndof #Define the vectors for the right hand side evec = [ CoefficientFunction((1, 0, 0)), CoefficientFunction((0, 1, 0)), CoefficientFunction((0, 0, 1)) ] #Setup the grid functions and array which will be used to save Theta0i = GridFunction(fes) Theta0j = GridFunction(fes) Theta0Sol = np.zeros([ndof, 3]) #Setup the inputs for the functions to run Theta0CPUs = min(3, multiprocessing.cpu_count(), CPUs) Runlist = [] for i in range(3): if Theta0CPUs < 3: NewInput = (fes, Order, alpha, mu, inout, evec[i], Tolerance, Maxsteps, epsi, i + 1, Solver) else: NewInput = (fes, Order, alpha, mu, inout, evec[i], Tolerance, Maxsteps, epsi, "No Print", Solver) Runlist.append(NewInput) #Run on the multiple cores with multiprocessing.Pool(Theta0CPUs) as pool: Output = pool.starmap(Theta0, Runlist) print(' solved theta0 problems ') #Unpack the outputs for i, Direction in enumerate(Output): Theta0Sol[:, i] = Direction #Calculate the N0 tensor VolConstant = Integrate(1 - mu**(-1), mesh) for i in range(3): Theta0i.vec.FV().NumPy()[:] = Theta0Sol[:, i] for j in range(3): Theta0j.vec.FV().NumPy()[:] = Theta0Sol[:, j] if i == j: N0[i, j] = (alpha**3) * (VolConstant + (1 / 4) * (Integrate( mu**(-1) * (InnerProduct(curl(Theta0i), curl(Theta0j))), mesh))) else: N0[i, j] = (alpha**3 / 4) * (Integrate( mu**(-1) * (InnerProduct(curl(Theta0i), curl(Theta0j))), mesh)) ######################################################################### #Theta1 #This section solves the Theta1 problem and saves the solution vectors #Setup the finite element space dom_nrs_metal = [0 if mat == "air" else 1 for mat in mesh.GetMaterials()] fes2 = HCurl(mesh, order=Order, dirichlet="outer", complex=True, gradientdomains=dom_nrs_metal) #Count the number of degrees of freedom ndof2 = fes2.ndof #Define the vectors for the right hand side xivec = [ CoefficientFunction((0, -z, y)), CoefficientFunction((z, 0, -x)), CoefficientFunction((-y, x, 0)) ] #Work out where to send each frequency Theta1_CPUs = min(NumberofFrequencies, multiprocessing.cpu_count(), CPUs) Core_Distribution = [] Count_Distribution = [] for i in range(Theta1_CPUs): Core_Distribution.append([]) Count_Distribution.append([]) #Distribute between the cores CoreNumber = 0 count = 1 for i, Omega in enumerate(Array): Core_Distribution[CoreNumber].append(Omega) Count_Distribution[CoreNumber].append(i) if CoreNumber == CPUs - 1 and count == 1: count = -1 elif CoreNumber == 0 and count == -1: count = 1 else: CoreNumber += count #Create the inputs Runlist = [] manager = multiprocessing.Manager() counter = manager.Value('i', 0) for i in range(Theta1_CPUs): Runlist.append( (Core_Distribution[i], mesh, fes, fes2, Theta0Sol, xivec, alpha, sigma, mu, inout, Tolerance, Maxsteps, epsi, Solver, N0, NumberofFrequencies, False, True, counter, False)) #Run on the multiple cores with multiprocessing.Pool(Theta1_CPUs) as pool: Outputs = pool.starmap(Theta1_Sweep, Runlist) #Unpack the results for i, Output in enumerate(Outputs): for j, Num in enumerate(Count_Distribution[i]): TensorArray[Num, :] = Output[0][j] EigenValues[Num, :] = Output[1][j] print("Frequency Sweep complete") return TensorArray, EigenValues, N0, numelements
def Checkvalid(Object,Order,alpha,inorout,mur,sig): Object = Object[:-4]+".vol" #Set order Ordercheck to be of low order to speed up computation. Ordercheck = 1 #Accuracy is increased by increaing noutput, but at greater cost noutput=20 #Set up the Solver Parameters Solver,epsi,Maxsteps,Tolerance = SolverParameters() #Loading the object file ngmesh = ngmeshing.Mesh(dim=3) ngmesh.Load("VolFiles/"+Object) #Creating the mesh and defining the element types mesh = Mesh("VolFiles/"+Object) mesh.Curve(5)#This can be used to refine the mesh #Set materials mu_coef = [ mur[mat] for mat in mesh.GetMaterials() ] mu = CoefficientFunction(mu_coef) inout_coef = [inorout[mat] for mat in mesh.GetMaterials() ] inout = CoefficientFunction(inout_coef) sigma_coef = [sig[mat] for mat in mesh.GetMaterials() ] sigma = CoefficientFunction(sigma_coef) #Scalars Mu0 = 4*np.pi*10**(-7) #Setup the finite element space dom_nrs_metal = [0 if mat == "air" else 1 for mat in mesh.GetMaterials()] femfull = H1(mesh, order=Ordercheck,dirichlet="default|outside") freedofs = femfull.FreeDofs() ndof=femfull.ndof Output = np.zeros([ndof,noutput],dtype=float) Averg = np.zeros([1,3],dtype=float) # we want to create a list of coordinates where we would like to apply BCs list=np.zeros([noutput,3],dtype=float) npp=0 for el in mesh.Elements(BND): if el.mat == "default": Averg[0,:]=0 #determine the average coordinate for v in el.vertices: Averg[0,:]+=mesh[v].point[:] Averg=Averg/3 if npp < noutput: list[npp,:]=Averg[0,:] npp+=1 print(" solving problems", end='\r') sval=(Integrate(inout, mesh))**(1/3) for i in range(noutput): sol=GridFunction(femfull) sol.Set(exp(-((x-list[i,0])**2 + (y-list[i,1])**2 + (z-list[i,2])**2)/sval**2),definedon=mesh.Boundaries("default")) u = femfull.TrialFunction() v = femfull.TestFunction() # the bilinear-form a = BilinearForm(femfull, symmetric=True, condense=True) a += 1/alpha**2*grad(u)*grad(v)*dx a += u*v*dx # the right hand side f = LinearForm(femfull) f += 0 * v * dx if Solver=="bddc": c = Preconditioner(a,"bddc")#Apply the bddc preconditioner a.Assemble() f.Assemble() if Solver=="local": c = Preconditioner(a,"local")#Apply the local preconditioner c.Update() #Solve the problem f.vec.data += a.harmonic_extension_trans * f.vec res = f.vec.CreateVector() res.data = f.vec - a.mat * sol.vec inverse= CGSolver(a.mat, c.mat, precision=Tolerance, maxsteps=Maxsteps) sol.vec.data += inverse * res sol.vec.data += a.inner_solve * f.vec sol.vec.data += a.harmonic_extension * sol.vec Output[:,i] = sol.vec.FV().NumPy() print(" problems solved ") Mc = np.zeros([noutput,noutput],dtype=float) M0 = np.zeros([noutput,noutput],dtype=float) print(" computing matrices", end='\r') # create numpy arrays by passing solutions back to NG Solve Soli=GridFunction(femfull) Solj=GridFunction(femfull) for i in range(noutput): Soli.Set(exp(-((x-list[i,0])**2 + (y-list[i,1])**2 + (z-list[i,2])**2)/sval**2),definedon=mesh.Boundaries("default")) Soli.vec.FV().NumPy()[:]=Output[:,i] for j in range(i,noutput): Solj.Set(exp(-((x-list[j,0])**2 + (y-list[j,1])**2 + (z-list[j,2])**2)/sval**2),definedon=mesh.Boundaries("default")) Solj.vec.FV().NumPy()[:]=Output[:,j] Mc[i,j] = Integrate(inout * (InnerProduct(grad(Soli),grad(Solj))/alpha**2+ InnerProduct(Soli,Solj)),mesh) Mc[j,i] = Mc[i,j] M0[i,j] = Integrate((1-inout) * (InnerProduct(grad(Soli),grad(Solj))/alpha**2+ InnerProduct(Soli,Solj)),mesh) M0[j,i] = M0[i,j] print(" matrices computed ") # solve the eigenvalue problem print(" solving eigenvalue problem", end='\r') out=slin.eig(Mc+M0,Mc,left=False, right=False) print(" eigenvalue problem solved ") # compute contants etasq = np.max((out.real)) C = 1 # It is not clear what this value is. C1 = C * ( 1 + np.sqrt(etasq) )**2 C2 = 2 * etasq epsilon = 8.854*10**-12 sigmamin = Integrate(inout * sigma, mesh)/Integrate(inout, mesh) mumax = Integrate(inout * mu * Mu0, mesh)/Integrate(inout, mesh) volume = Integrate(inout, mesh) D = (volume * alpha**3)**(1/3) cond1 = np.sqrt(1/epsilon/mumax/D**2/C1) cond2 = 1/epsilon*sigmamin/C2 cond = min(cond1,cond2) print(" maximum recomeneded frequency is ",str(round(cond/100))) return cond/100
def FolderMaker(Geometry, Single, Array, Omega, Pod, PlotPod, PODArray, PODTol, alpha, Order, MeshSize, mur, sig, ErrorTensors, VTK): #Find how the user wants the data saved FolderStructure = SaverSettings() if FolderStructure == "Default": #Create the file structure #Define constants for the folder name objname = Geometry[:-4] minF = Array[0] strminF = FtoS(minF) maxF = Array[-1] strmaxF = FtoS(maxF) stromega = FtoS(Omega) Points = len(Array) PODPoints = len(PODArray) strmur = DictionaryList(mur, False) strsig = DictionaryList(sig, True) strPODTol = FtoS(PODTol) #Find out the number of elements in the mesh Object = Geometry[:-4] + ".vol" #Loading the object file ngmesh = ngmeshing.Mesh(dim=3) ngmesh.Load("VolFiles/" + Object) #Creating the mesh and defining the element types mesh = Mesh("VolFiles/" + Object) #mesh.Curve(5)#This can be used to refine the mesh elements = mesh.ne #Define the main folder structure subfolder1 = "al_" + str(alpha) + "_mu_" + strmur + "_sig_" + strsig if Single == True: subfolder2 = "om_" + stromega + "_el_" + str( elements) + "_ord_" + str(Order) else: if Pod == True: subfolder2 = strminF + "-" + strmaxF + "_" + str( Points) + "_el_" + str(elements) + "_ord_" + str( Order) + "_POD_" + str(PODPoints) + "_" + strPODTol else: subfolder2 = strminF + "-" + strmaxF + "_" + str( Points) + "_el_" + str(elements) + "_ord_" + str(Order) sweepname = objname + "/" + subfolder1 + "/" + subfolder2 else: sweepname = FolderStructure if Single == True: subfolders = ["Data", "Input_files"] else: subfolders = ["Data", "Graphs", "Functions", "Input_files"] #Create the folders for folder in subfolders: try: os.makedirs("Results/" + sweepname + "/" + folder) except: pass #Create the folders for the VTK output if required if VTK == True and Single == True: try: os.makedirs("Results/vtk_output/" + objname + "/om_" + stromega) except: pass #Copy the .geo file to the folder copyfile( "GeoFiles/" + Geometry, "Results/vtk_output/" + objname + "/om_" + stromega + "/" + Geometry) #Copy the files required to be able to edit the graphs if Single != True: copyfile("Settings/PlotterSettings.py", "Results/" + sweepname + "/PlotterSettings.py") copyfile("Functions/Plotters.py", "Results/" + sweepname + "/Functions/Plotters.py") if Pod == True: if ErrorTensors == True: copyfile( "Functions/PlotEditorWithErrorBars.py", "Results/" + sweepname + "/PlotEditorWithErrorBars.py") if PlotPod == True: copyfile("Functions/PODPlotEditor.py", "Results/" + sweepname + "/PODPlotEditor.py") if ErrorTensors != False: copyfile( "Functions/PODPlotEditorWithErrorBars.py", "Results/" + sweepname + "/PODPlotEditorWithErrorBars.py") copyfile("Functions/PlotEditor.py", "Results/" + sweepname + "/PlotEditor.py") copyfile("GeoFiles/" + Geometry, "Results/" + sweepname + "/Input_files/" + Geometry) copyfile("Settings/Settings.py", "Results/" + sweepname + "/Input_files/Settings.py") copyfile("main.py", "Results/" + sweepname + "/Input_files/main.py") #Create a compressed version of the .vol file os.chdir('VolFiles') zipObj = ZipFile(objname + '.zip', 'w', ZIP_DEFLATED) zipObj.write(Object) zipObj.close() os.replace(objname + '.zip', '../Results/' + sweepname + '/Input_files/' + objname + '.zip') os.chdir('..') return
do_vtk = False print("Hello from rank " + str(rank) + " of " + str(np)) if rank == 0: # master-proc generates mesh mesh = unit_cube.GenerateMesh(maxh=0.3) # and saves it to file mesh.Save("some_mesh.vol") # wait for master to be done meshing comm.Barrier() # now load mesh from file ngmesh = netgen.Mesh(dim=3, comm=comm) ngmesh.Load("some_mesh.vol") #refine once? # ngmesh.Refine() mesh = Mesh(ngmesh) # build H1-FESpace as usual V = H1(mesh, order=3, dirichlet=[1, 2, 3, 4]) u = V.TrialFunction() v = V.TestFunction() print("rank " + str(rank) + " has " + str(V.ndof) + " of " + str(V.ndofglobal) + " dofs!")
def FullSweep(Object, Order, alpha, inorout, mur, sig, Array, BigProblem): Object = Object[:-4] + ".vol" #Set up the Solver Parameters Solver, epsi, Maxsteps, Tolerance = SolverParameters() #Loading the object file ngmesh = ngmeshing.Mesh(dim=3) ngmesh.Load("VolFiles/" + Object) #Creating the mesh and defining the element types mesh = Mesh("VolFiles/" + Object) mesh.Curve(5) #This can be used to refine the mesh numelements = mesh.ne #Count the number elements print(" mesh contains " + str(numelements) + " elements") #Set up the coefficients #Scalars Mu0 = 4 * np.pi * 10**(-7) NumberofFrequencies = len(Array) #Coefficient functions mu_coef = [mur[mat] for mat in mesh.GetMaterials()] mu = CoefficientFunction(mu_coef) inout_coef = [inorout[mat] for mat in mesh.GetMaterials()] inout = CoefficientFunction(inout_coef) sigma_coef = [sig[mat] for mat in mesh.GetMaterials()] sigma = CoefficientFunction(sigma_coef) #Set up how the tensor and eigenvalues will be stored N0 = np.zeros([3, 3]) R = np.zeros([3, 3]) I = np.zeros([3, 3]) ######################################################################### #Theta0 #This section solves the Theta0 problem to calculate both the inputs for #the Theta1 problem and calculate the N0 tensor #Setup the finite element space fes = HCurl(mesh, order=Order, dirichlet="outer", flags={"nograds": True}) #Count the number of degrees of freedom ndof = fes.ndof #Define the vectors for the right hand side evec = [ CoefficientFunction((1, 0, 0)), CoefficientFunction((0, 1, 0)), CoefficientFunction((0, 0, 1)) ] #Setup the grid functions and array which will be used to save Theta0i = GridFunction(fes) Theta0j = GridFunction(fes) Theta0Sol = np.zeros([ndof, 3]) #Run in three directions and save in an array for later for i in range(3): Theta0Sol[:, i] = Theta0(fes, Order, alpha, mu, inout, evec[i], Tolerance, Maxsteps, epsi, i + 1, Solver) print(' solved theta0 problems ') #Calculate the N0 tensor VolConstant = Integrate(1 - mu**(-1), mesh) for i in range(3): Theta0i.vec.FV().NumPy()[:] = Theta0Sol[:, i] for j in range(i + 1): Theta0j.vec.FV().NumPy()[:] = Theta0Sol[:, j] if i == j: N0[i, j] = (alpha**3) * (VolConstant + (1 / 4) * (Integrate( mu**(-1) * (InnerProduct(curl(Theta0i), curl(Theta0j))), mesh))) else: N0[i, j] = (alpha**3 / 4) * (Integrate( mu**(-1) * (InnerProduct(curl(Theta0i), curl(Theta0j))), mesh)) #Copy the tensor N0 += np.transpose(N0 - np.eye(3) @ N0) ######################################################################### #Theta1 #This section solves the Theta1 problem to calculate the solution vectors #of the snapshots #Setup the finite element space dom_nrs_metal = [0 if mat == "air" else 1 for mat in mesh.GetMaterials()] fes2 = HCurl(mesh, order=Order, dirichlet="outer", complex=True, gradientdomains=dom_nrs_metal) #Count the number of degrees of freedom ndof2 = fes2.ndof #Define the vectors for the right hand side xivec = [ CoefficientFunction((0, -z, y)), CoefficientFunction((z, 0, -x)), CoefficientFunction((-y, x, 0)) ] #Solve the problem TensorArray, EigenValues = Theta1_Sweep(Array, mesh, fes, fes2, Theta0Sol, xivec, alpha, sigma, mu, inout, Tolerance, Maxsteps, epsi, Solver, N0, NumberofFrequencies, False, True, False, False) print(' solved theta1 problems ') print(' frequency sweep complete') return TensorArray, EigenValues, N0, numelements
def ProdMesh(ngmeshbase, t_steps, dirichletsplit=False): ngmesh = ngm.Mesh() ngmesh.dim = 3 pnums = [] for p in ngmeshbase.Points(): x, y, z = p.p ngmesh.Add(ngm.MeshPoint(ngm.Pnt(x, y, 0))) for i, p in enumerate(ngmeshbase.Points()): x, y, z = p.p pnums.append(ngmesh.Add(ngm.MeshPoint(ngm.Pnt(x, y, t_steps)))) El1d = ngmeshbase.Elements1D() El2d = ngmeshbase.Elements2D() ngmesh.SetMaterial(1, "mat") for el in El2d: ngmesh.Add( ngm.Element3D(1, [ pnums[el.points[0].nr - 1], pnums[el.points[1].nr - 1], pnums[el.points[2].nr - 1], el.points[0].nr, el.points[1].nr, el.points[2].nr ])) fde = ngm.FaceDescriptor(surfnr=1, domin=1, bc=1) fde.bcname = "bottom" fdid = ngmesh.Add(fde) for el in El2d: ngmesh.Add( ngm.Element2D(fdid, [el.points[2].nr, el.points[1].nr, el.points[0].nr])) fde = ngm.FaceDescriptor(surfnr=2, domin=1, bc=2) fde.bcname = "top" fdid = ngmesh.Add(fde) for el in El2d: ngmesh.Add( ngm.Element2D(fdid, [ pnums[el.points[0].nr - 1], pnums[el.points[1].nr - 1], pnums[el.points[2].nr - 1] ])) if dirichletsplit == False: fde = ngm.FaceDescriptor(surfnr=3, domin=1, bc=3) fde.bcname = "dirichlet" fdid = ngmesh.Add(fde) for el in El1d: ngmesh.Add( ngm.Element2D(fdid, [ el.points[0].nr, el.points[1].nr, pnums[el.points[1].nr - 1], pnums[el.points[0].nr - 1] ])) ngmesh.SetBCName(2, "dirichlet") if dirichletsplit == True: fde = ngm.FaceDescriptor(surfnr=3, domin=1, bc=3) fde.bcname = "front" fdid = ngmesh.Add(fde) for el in El1d: if ngmeshbase.Points()[el.points[0]][1] == 0: ngmesh.Add( ngm.Element2D(fdid, [ el.points[0].nr, el.points[1].nr, pnums[el.points[1].nr - 1], pnums[el.points[0].nr - 1] ])) fde = ngm.FaceDescriptor(surfnr=4, domin=1, bc=4) fde.bcname = "back" fdid = ngmesh.Add(fde) for el in El1d: if ngmeshbase.Points()[el.points[0]][1] == 1: ngmesh.Add( ngm.Element2D(fdid, [ el.points[0].nr, el.points[1].nr, pnums[el.points[1].nr - 1], pnums[el.points[0].nr - 1] ])) fde = ngm.FaceDescriptor(surfnr=5, domin=1, bc=5) fde.bcname = "left" fdid = ngmesh.Add(fde) for el in El1d: if ngmeshbase.Points()[el.points[0]][0] == 0: ngmesh.Add( ngm.Element2D(fdid, [ el.points[0].nr, el.points[1].nr, pnums[el.points[1].nr - 1], pnums[el.points[0].nr - 1] ])) fde = ngm.FaceDescriptor(surfnr=6, domin=1, bc=6) fde.bcname = "right" fdid = ngmesh.Add(fde) for el in El1d: if ngmeshbase.Points()[el.points[0]][0] == 1: ngmesh.Add( ngm.Element2D(fdid, [ el.points[0].nr, el.points[1].nr, pnums[el.points[1].nr - 1], pnums[el.points[0].nr - 1] ])) ngmesh.SetBCName(2, "front") ngmesh.SetBCName(3, "back") ngmesh.SetBCName(4, "left") ngmesh.SetBCName(5, "right") ngmesh.SetBCName(0, "bottom") ngmesh.SetBCName(1, "top") mesh = Mesh(ngmesh) return mesh