Beispiel #1
0
    def SetupElectrostaticsImplicit(self, mesh, formulation,
                                    boundary_condition, material, fem_solver,
                                    solver, Eulerx, Increment):
        """setup implicit electrostatic problem
        """

        from Florence import BoundaryCondition, FEMSolver, LaplacianSolver, IdealDielectric, AnisotropicIdealDielectric
        from Florence.VariationalPrinciple import LaplacianFormulation, ExplicitPenaltyContactFormulation

        # EMULATE ELECTROSTATICS MODEL
        emesh = deepcopy(mesh)

        if fem_solver.activate_explicit_multigrid:
            # WE GET THE MAX EPS - NOT ELEGANT BUT SEEMINGLY WORKS WELL
            eps_s = []
            for key, value in list(material.__dict__.items()):
                if "eps" in key:
                    eps_s.append(value)
            max_eps = max(eps_s)
            ematerial = IdealDielectric(emesh.InferSpatialDimension(),
                                        eps_1=max_eps)

            eanalysis_nature = "linear"
            eoptimise = True
        else:
            ematerial = deepcopy(material)
            ematerial.Hessian = ematerial.Permittivity
            ematerial.KineticMeasures = ematerial.ElectrostaticMeasures
            ematerial.H_VoigtSize = formulation.ndim
            ematerial.nvar = 1
            ematerial.fields = "electrostatics"

            eanalysis_nature = "nonlinear"
            eoptimise = False

        # SET UP BOUNDARY CONDITION DURING SOLUTION
        eboundary_condition = BoundaryCondition()

        eformulation = LaplacianFormulation(mesh)
        efem_solver = FEMSolver(
            number_of_load_increments=1,
            analysis_nature=eanalysis_nature,
            newton_raphson_tolerance=fem_solver.newton_raphson_tolerance,
            optimise=eoptimise)

        self.emesh = emesh
        self.ematerial = ematerial
        self.eformulation = eformulation
        self.eboundary_condition = eboundary_condition
        self.efem_solver = efem_solver
Beispiel #2
0
def QuadBallSurface(center=(0., 0., 0.), radius=1., n=10, element_type="quad"):
    """Creates a surface quad mesh on sphere using midpoint subdivision algorithm
        by creating a cube and spherifying it using PostMesh's projection schemes.
        Unlike the volume QuadBall method there is no restriction on number of divisions
        here as no system of equations is solved

        inputs:

            n:                          [int] number of divsion in every direction.
                                        Given that this implementation is based on
                                        high order bases different divisions in
                                        different directions is not possible
    """

    try:
        from Florence import Mesh, BoundaryCondition, DisplacementFormulation, FEMSolver, LinearSolver
        from Florence import LinearElastic, NeoHookean
        from Florence.Tensor import prime_number_factorisation
    except ImportError:
        raise ImportError("This function needs Florence's core support")

    n = int(n)
    if not isinstance(center, tuple):
        raise ValueError(
            "The center of the circle should be given in a tuple with two elements (x,y,z)"
        )
    if len(center) != 3:
        raise ValueError(
            "The center of the circle should be given in a tuple with two elements (x,y,z)"
        )

    if n == 2 or n == 3 or n == 5 or n == 7:
        ps = [n]
    else:

        def factorise_all(n):
            if n < 2:
                n = 2
            factors = prime_number_factorisation(n)
            if len(factors) == 1 and n > 2:
                n += 1
                factors = prime_number_factorisation(n)
            return factors

        factors = factorise_all(n)
        ps = []
        for factor in factors:
            ps += factorise_all(factor)

    # Do high ps first
    ps = np.sort(ps)[::-1].tolist()
    niter = len(ps)

    sphere_igs_file_content = SphereIGS()
    with open("sphere_cad_file.igs", "w") as f:
        f.write(sphere_igs_file_content)

    sys.stdout = open(os.devnull, "w")

    ndim = 3
    scale = 1000.
    condition = 1.e020

    mesh = Mesh()
    material = LinearElastic(ndim, mu=1., lamb=4.)

    for it in range(niter):

        if it == 0:
            mesh.Parallelepiped(element_type="hex",
                                nx=1,
                                ny=1,
                                nz=1,
                                lower_left_rear_point=(-0.5, -0.5, -0.5),
                                upper_right_front_point=(0.5, 0.5, 0.5))
            mesh = mesh.CreateSurface2DMeshfrom3DMesh()
            mesh.GetHighOrderMesh(p=ps[it], equally_spaced=True)
            mesh = mesh.CreateDummy3DMeshfrom2DMesh()
            formulation = DisplacementFormulation(mesh)
        else:
            mesh.GetHighOrderMesh(p=ps[it], equally_spaced=True)
            mesh = mesh.CreateDummy3DMeshfrom2DMesh()

        boundary_condition = BoundaryCondition()
        boundary_condition.SetCADProjectionParameters(
            "sphere_cad_file.igs",
            scale=scale,
            condition=condition,
            project_on_curves=True,
            solve_for_planar_faces=True,
            modify_linear_mesh_on_projection=True,
            fix_dof_elsewhere=False)
        boundary_condition.GetProjectionCriteria(mesh)
        nodesDBC, Dirichlet = boundary_condition.PostMeshWrapper(
            formulation, mesh, None, None, FEMSolver())

        mesh.points[nodesDBC.ravel(), :] += Dirichlet
        mesh = mesh.CreateSurface2DMeshfrom3DMesh()
        mesh = mesh.ConvertToLinearMesh()

    os.remove("sphere_cad_file.igs")

    if not np.isclose(radius, 1):
        mesh.points *= radius

    mesh.points[:, 0] += center[0]
    mesh.points[:, 1] += center[1]
    mesh.points[:, 2] += center[2]

    if element_type == "tri":
        mesh.ConvertQuadsToTris()

    sys.stdout = sys.__stdout__

    return mesh
Beispiel #3
0
def QuadBall(center=(0., 0., 0.), radius=1., n=10, element_type="hex"):
    """Creates a fully hexahedral mesh on sphere using midpoint subdivision algorithm
        by creating a cube and spherifying it using PostMesh's projection schemes

        inputs:

            n:                          [int] number of divsion in every direction.
                                        Given that this implementation is based on
                                        high order bases different divisions in
                                        different directions is not possible
    """

    try:
        from Florence import Mesh, BoundaryCondition, DisplacementFormulation, FEMSolver, LinearSolver
        from Florence import LinearElastic, NeoHookean
        from Florence.Tensor import prime_number_factorisation
    except ImportError:
        raise ImportError("This function needs Florence's core support")

    n = int(n)
    if n > 50:
        # Values beyond this result in >1M DoFs due to internal prime factoristaion splitting
        raise ValueError(
            "The value of n={} (division in each direction) is too high".
            format(str(n)))

    if not isinstance(center, tuple):
        raise ValueError(
            "The center of the circle should be given in a tuple with two elements (x,y,z)"
        )
    if len(center) != 3:
        raise ValueError(
            "The center of the circle should be given in a tuple with two elements (x,y,z)"
        )

    if n == 2 or n == 3 or n == 5 or n == 7:
        ps = [n]
    else:

        def factorise_all(n):
            if n < 2:
                n = 2
            factors = prime_number_factorisation(n)
            if len(factors) == 1 and n > 2:
                n += 1
                factors = prime_number_factorisation(n)
            return factors

        factors = factorise_all(n)
        ps = []
        for factor in factors:
            ps += factorise_all(factor)

    # Do high ps first
    ps = np.sort(ps)[::-1].tolist()
    niter = len(ps)

    # IGS file for sphere with radius 1000.
    sphere_igs_file_content = SphereIGS()

    with open("sphere_cad_file.igs", "w") as f:
        f.write(sphere_igs_file_content)

    sys.stdout = open(os.devnull, "w")

    ndim = 3
    scale = 1000.
    condition = 1.e020

    mesh = Mesh()
    material = LinearElastic(ndim, mu=1., lamb=4.)
    # Keep the solver iterative for low memory consumption. All boundary points are Dirichlet BCs
    # so they will be exact anyway
    solver = LinearSolver(linear_solver="iterative",
                          linear_solver_type="cg2",
                          dont_switch_solver=True,
                          iterative_solver_tolerance=1e-9)

    for it in range(niter):

        if it == 0:
            mesh.Parallelepiped(element_type="hex",
                                nx=1,
                                ny=1,
                                nz=1,
                                lower_left_rear_point=(-0.5, -0.5, -0.5),
                                upper_right_front_point=(0.5, 0.5, 0.5))
        mesh.GetHighOrderMesh(p=ps[it], equally_spaced=True)

        boundary_condition = BoundaryCondition()
        boundary_condition.SetCADProjectionParameters(
            "sphere_cad_file.igs",
            scale=scale,
            condition=condition,
            project_on_curves=True,
            solve_for_planar_faces=True,
            modify_linear_mesh_on_projection=True,
            fix_dof_elsewhere=False)
        boundary_condition.GetProjectionCriteria(mesh)

        formulation = DisplacementFormulation(mesh)
        fem_solver = FEMSolver(number_of_load_increments=1,
                               analysis_nature="linear",
                               force_not_computing_mesh_qualities=True,
                               report_log_level=0,
                               optimise=True)

        solution = fem_solver.Solve(formulation=formulation,
                                    mesh=mesh,
                                    material=material,
                                    boundary_condition=boundary_condition,
                                    solver=solver)

        mesh.points += solution.sol[:, :, -1]
        mesh = mesh.ConvertToLinearMesh()

    os.remove("sphere_cad_file.igs")

    if not np.isclose(radius, 1):
        mesh.points *= radius

    mesh.points[:, 0] += center[0]
    mesh.points[:, 1] += center[1]
    mesh.points[:, 2] += center[2]

    if element_type == "tet":
        mesh.ConvertHexesToTets()

    sys.stdout = sys.__stdout__

    return mesh
            ematerial.Hessian = ematerial.Permittivity
            ematerial.KineticMeasures = ematerial.ElectrostaticMeasures
            ematerial.H_VoigtSize = formulation.ndim
            ematerial.nvar = 1
            ematerial.fields = "electrostatics"

            eanalysis_nature = "nonlinear"
            eoptimise = False
>>>>>>> upstream/master

        # SET UP BOUNDARY CONDITION DURING SOLUTION
        eboundary_condition = BoundaryCondition()

        eformulation = LaplacianFormulation(mesh)
<<<<<<< HEAD
        efem_solver = FEMSolver(number_of_load_increments=1,analysis_nature="nonlinear",
            newton_raphson_tolerance=fem_solver.newton_raphson_tolerance)
=======
        efem_solver = FEMSolver(number_of_load_increments=1,analysis_nature=eanalysis_nature,
            newton_raphson_tolerance=fem_solver.newton_raphson_tolerance,optimise=eoptimise)
>>>>>>> upstream/master

        self.emesh = emesh
        self.ematerial = ematerial
        self.eformulation = eformulation
        self.eboundary_condition = eboundary_condition
        self.efem_solver = efem_solver


    def SolveElectrostaticsImplicit(self, mesh, formulation, boundary_condition, material, fem_solver, solver, Eulerx, Increment):
        """Solve implicit electrostatic problem
        """