Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
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
Ejemplo n.º 4
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
Ejemplo n.º 5
0
 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]
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
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
Ejemplo n.º 11
0
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
Ejemplo n.º 12
0
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
Ejemplo n.º 13
0
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
Ejemplo n.º 14
0
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!")
Ejemplo n.º 15
0
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
Ejemplo n.º 16
0
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
Ejemplo n.º 17
0
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))
Ejemplo n.º 18
0
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
Ejemplo n.º 19
0
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
Ejemplo n.º 20
0
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
Ejemplo n.º 21
0
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
Ejemplo n.º 22
0
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!")
Ejemplo n.º 23
0
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
Ejemplo n.º 24
0
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