Exemple #1
0
    def test_Poisson_t3(self):
        from context import spyfe
        from spyfe.meshing.generators.triangles import t3_ablock
        from spyfe.meshing.modification import mesh_boundary
        from spyfe.meshing.selection import connected_nodes
        from numpy import array
        from spyfe.materials.mat_heatdiff import MatHeatDiff
        from spyfe.femms.femm_heatdiff import FEMMHeatDiff
        from spyfe.fields.nodal_field import NodalField
        from spyfe.integ_rules import TriRule
        from spyfe.force_intensity import ForceIntensity
        from scipy.sparse.linalg import spsolve
        import time
        from spyfe.meshing.exporters.vtkexporter import vtkexport

        start0 = time.time()

        # These are the constants in the problem, k is kappa
        boundaryf = lambda x, y: 1.0 + x**2 + 2 * y**2
        Q = -6  # internal heat generation rate
        k = 1.0  # thermal conductivity
        m = MatHeatDiff(thermal_conductivity=array([[k, 0.0], [0.0, k]]))
        Dz = 1.0  # thickness of the slice
        start = time.time()
        N = 5
        Length, Width, nL, nW = 1.0, 1.0, N, N
        fens, fes = t3_ablock(Length, Width, nL, nW)
        print('Mesh generation', time.time() - start)
        bfes = mesh_boundary(fes)
        cn = connected_nodes(bfes)
        geom = NodalField(fens=fens)
        temp = NodalField(nfens=fens.count(), dim=1)
        for index in cn:
            temp.set_ebc([index],
                         val=boundaryf(fens.xyz[index, 0], fens.xyz[index, 1]))
        temp.apply_ebc()
        temp.numberdofs()
        femm = FEMMHeatDiff(material=m,
                            fes=fes,
                            integration_rule=TriRule(npts=1))
        start = time.time()
        fi = ForceIntensity(magn=lambda x, J: Q)
        F = femm.distrib_loads(geom, temp, fi, 3)
        print('Heat generation load', time.time() - start)
        start = time.time()
        F += femm.nz_ebc_loads_conductivity(geom, temp)
        print('NZ EBC load', time.time() - start)
        start = time.time()
        K = femm.conductivity(geom, temp)
        print('Matrix assembly', time.time() - start)
        start = time.time()
        temp.scatter_sysvec(spsolve(K, F))
        print('Solution', time.time() - start)
        print(temp.values)
        print('Done', time.time() - start0)
        from numpy.testing import assert_array_almost_equal
        assert_array_almost_equal(temp.values[-4:-1],
                                  array([[3.16], [3.36], [3.64]]))
Exemple #2
0
maxiter=150
lamb, v, converged = spyfe.bipwr.gepbinvpwr2(K,M,v,tol,maxiter)
if converged:
    ix = numpy.argsort(numpy.abs(lamb))
    lamb = lamb[ix].real
    v = v[:, ix]
    print([math.sqrt(om) / 2.0 / math.pi for om in lamb])
    print("Reference frequencies:")
    print([0.421, 1.029, 2.582, 3.306, 3.753, 6.555])
    print('Solution', time.time() - start)
else:
    print( 'Not converged!'  )


# start = time.time()
# w, v = eigsh(K, k=10, M=M, which='SM')
# ix = numpy.argsort(numpy.abs(w))
# w = w[ix].real
# v = v[:,ix]
# print('EP solution', time.time() - start)
# print([math.sqrt(om)/2.0/math.pi for om in w])
# print(w, v[:,0])
u.scatter_sysvec(v[:,0].real)

#
print('Done', time.time() - start0)


#
vtkexport("FV16_cantilevered_plate_abaqus_results", fes, geom, {"displacements": u})
temp.apply_ebc()
femm = FEMMHeatDiff(material=m,
                    fes=fes,
                    integration_rule=GaussRule(dim=3, order=3))
S = femm.connection_matrix(geom)
perm = reverse_cuthill_mckee(S, symmetric_mode=True)
temp.numberdofs(node_perm=perm)
# temp.numberdofs()
start = time.time()
fi = ForceIntensity(magn=lambda x, J: Q)
F = femm.distrib_loads(geom, temp, fi, 3)
print('Heat generation load', time.time() - start)
start = time.time()
F += femm.nz_ebc_loads_conductivity(geom, temp)
print('NZ EBC load', time.time() - start)
start = time.time()
K = femm.conductivity(geom, temp)
print('Matrix assembly', time.time() - start)
start = time.time()
# lu = splu(K)
# T = lu.solve(F)
# T = spsolve(K, F, use_umfpack=True)
T, info = minres(K, F)
print(info)
temp.scatter_sysvec(T)
print('Solution', time.time() - start)

print('Done', time.time() - start0)

vtkexport("Poisson_fe_H20_results", fes, geom, {"temp": temp})
Exemple #4
0
for index in cn:
    temp.set_ebc([index],
                 val=boundaryf(fens.xyz[index, 0], fens.xyz[index, 1]))
temp.apply_ebc()
femm = FEMMHeatDiff(material=m,
                    fes=fes,
                    integration_rule=GaussRule(dim=2, order=3))
# S = femm.connection_matrix(geom)
# perm = reverse_cuthill_mckee(S,symmetric_mode=True)
# temp.numberdofs(node_perm=perm)
temp.numberdofs()
start = time.time()
fi = ForceIntensity(magn=lambda x, J: Q)
F = femm.distrib_loads(geom, temp, fi, 3)
print('Heat generation load', time.time() - start)
start = time.time()
F += femm.nz_ebc_loads_conductivity(geom, temp)
print('NZ EBC load', time.time() - start)
start = time.time()
K = femm.conductivity(geom, temp)
print('Matrix assembly', time.time() - start)
start = time.time()
temp.scatter_sysvec(spsolve(K, F))
print('Solution', time.time() - start)

print('Done', time.time() - start0)

# print(temp.values.T)

vtkexport("Poisson_fe_Q8_results", fes, geom, {"temp": temp})
Exemple #5
0
start = time.time()
dT = NodalField(nfens=fens.count(), dim=1)
dT.fun_set_values(fens.xyz, lambda x: math.sqrt(x[0]**2 + x[1]**2) + x[2])
print(numpy.max(dT.values))
print(numpy.min(dT.values))
F = femm.thermal_strain_loads(geom, u, dT)
print('Load vector assembly', time.time() - start)
print(numpy.max(F), numpy.min(F))

start = time.time()
# U, info = lgmres(K, F)
# print(info)
lu = splu(K)
del K
U = lu.solve(F)
u.scatter_sysvec(U)

print('Solution', time.time() - start)
#
print('Done', time.time() - start0)

stresses = femm.nodal_field_from_integr_points_spr(
    geom, u, u, dtempn1=dT, output=OUTPUT_CAUCHY, component=[0, 1, 2, 3, 4, 5])
pointA = fenode_select(
    fens,
    box=[707.107E-03, 707.107E-03, -707.107E-03, -707.107E-03, 0., 0.],
    inflate=htol)
print(pointA)
sigzzA = stresses.values[pointA, 2]
print('Stress sigz @ A=', sigzzA / 1.e6, ', ', (sigzzA / sigma_z_A_ref * 100),
      ' %')
def statics(model_data):
    """Algorithm for static linear deformation (stress) analysis.

    :param model_data: Model data dictionary.

    model_data['fens'] = finite element node set (mandatory)

    For each region (connected piece of the domain made of a particular material), mandatory:
    model_data['regions']= list of dictionaries, one for each region
        Each region:
        region['femm'] = finite element set that covers the region (mandatory)
        
    For essential boundary conditions (optional):
    model_data['boundary_conditions']['essential']=list of dictionaries, one for each 
        application of an essential boundary condition.
        For each EBC dictionary ebc:
            ebc['node_list'] =  node list,
            ebc['comp'] = displacement component (zero-based),
            ebc['value'] = function to supply the prescribed value, default is lambda x: 0.0
      

    :return: Success?  True or false.  The model_data object is modified.
    model_data['geom'] =the nodal field that is the geometry
    model_data['temp'] =the nodal field that is the computed temperature
    model_data['timings'] = timing of the individual operations
    """
    # To be done
    # For essential boundary conditions (optional):
    #  cell array of struct,
    #           each piece of surface with essential boundary condition gets one
    #           element of the array with a struct with the attributes
    #     essential.temperature=fixed (prescribed) temperature (scalar),  or
    #           handle to a function with signature
    #               function T =f(x)
    #     essential.fes = finite element set on the boundary to which
    #                       the condition applies
    #               or alternatively
    #     essential.node_list = list of nodes on the boundary to which
    #                       the condition applies
    #               Only one of essential.fes and essential.node_list needs a given.
    #
    # For convection boundary conditions (optional):
    # model_data.boundary_conditions.convection = cell array of struct,
    #           each piece of surface with convection boundary condition gets one
    #           element of the array with a struct with the attributes
    #     convection.ambient_temperature=ambient temperature (scalar)
    #     convection.surface_transfer_coefficient  = surface heat transfer coefficient
    #     convection.fes = finite element set on the boundary to which
    #                       the condition applies
    #     convection.integration_rule= integration rule
    #
    # For flux boundary conditions (optional):
    # model_data.boundary_conditions.flux = cell array of struct,
    #           each piece of surface with flux boundary condition gets one
    #           element of the array with a struct with the attributes
    #     flux.normal_flux= normal flux component, positive when outward-bound (scalar)
    #     flux.fes = finite element set on the boundary to which
    #                       the condition applies
    #     flux.integration_rule= integration rule
    #
    # Control parameters:
    # model_data.renumber = true or false flag (default is true)
    # model_data.renumbering_method = optionally choose the renumbering
    #       method  (symrcm or symamd)

    # renumber = ~true; # Should we renumber?
    # if (isfield(model_data,'renumber'))
    #     renumber  =model_data.renumber;
    # end
    # Renumbering_options =struct( [] );
    #
    # # Should we renumber the nodes to minimize the cost of the solution of
    # # the coupled linear algebraic equations?
    # if (renumber)
    #     renumbering_method = 'symamd'; # default choice
    #     if ( isfield(model_data,'renumbering_method'))
    #         renumbering_method  =model_data.renumbering_method;;
    #     end
    #     # Run the renumbering algorithm
    #     model_data =renumber_mesh(model_data, renumbering_method);;
    #     # Save  the renumbering  (permutation of the nodes)
    #     clear  Renumbering_options; Renumbering_options.node_perm  =model_data.node_perm;
    # end

    timings = []

    task = 'Preliminaries'
    start = time.time()

    # Extract the nodes
    fens = model_data['fens']

    # Construct the geometry field
    geom = NodalField(fens=fens)

    # Construct the displacement field
    u = NodalField(dim=geom.dim, nfens=geom.nfens)

    # Apply the essential boundary conditions on the temperature field
    if 'boundary_conditions' in model_data:
        if 'essential' in model_data['boundary_conditions']:
            ebcs = model_data['boundary_conditions']['essential']
            for ebc in ebcs:
                fenids = ebc['node_list']
                value = ebc['value'] if 'value' in ebc \
                    else lambda xyz: 0.0
                comp = ebc['comp']
                for index in fenids:
                    u.set_ebc([index],
                              comp=comp,
                              val=value(fens.xyz[index, :]))
            u.apply_ebc()

    # Number the equations
    u.numberdofs()

    timings.append((task, time.time() - start))

    # Initialize the loads vector
    F = numpy.zeros((u.nfreedofs, ))

    # #  Flux boundary condition:
    # if (isfield(model_data.boundary_conditions, 'flux' ))
    #     for j=1:length(model_data.boundary_conditions.flux)
    #         flux =model_data.boundary_conditions.flux{j};
    #         flux.femm = femm_heat_diffusion (struct (...
    #             'fes',flux.fes,...
    #             'integration_rule',flux.integration_rule));
    #         model_data.boundary_conditions.flux{j}=flux;
    #     end
    #     clear flux fi  femm
    # end
    #

    task = 'Stiffness matrix'
    start = time.time()

    # Make sure the model machines are given a chance to perform
    # some geometry-related preparations
    for region in model_data['regions']:
        region['femm'].associate_geometry(geom)

    # Construct the system stiffness matrix
    K = csr_matrix((u.nfreedofs, u.nfreedofs))  # (all zeros, for the moment)
    for region in model_data['regions']:
        # Add up all the stiffness matrices for all the regions
        K += region['femm'].stiffness(geom, u)

    timings.append((task, time.time() - start))

    # Apply the traction boundary conditions
    if 'boundary_conditions' in model_data:
        if 'traction' in model_data['boundary_conditions']:
            tbcs = model_data['boundary_conditions']['traction']
            for tbc in tbcs:
                femm = tbc['femm']
                fi = tbc['force_intensity']
                F += femm.distrib_loads(geom, u, fi, 2)

    # task = 'Body loads'
    # start = time.time()
    #
    # for region in model_data['regions']:
    #     Q = None  # default is no internal heat generation rate
    #     if 'heat_generation' in region:  # Was it defined?
    #         Q = region['heat_generation']
    #     if Q is not None:  # If it was supplied, and it is nonzero, compute its contribution.
    #         F = F + region['femm'].distrib_loads(geom, temp, Q, 3)
    #
    # timings.append((task, time.time() - start))

    task = 'NZEBC loads'
    start = time.time()

    if 'boundary_conditions' in model_data:
        if 'essential' in model_data['boundary_conditions']:
            for region in model_data['regions']:
                # Loads due to the essential boundary conditions on the temperature field
                F += region['femm'].nz_ebc_loads(geom, u)

    timings.append((task, time.time() - start))

    # # Process the flux boundary condition
    # if (isfield(model_data.boundary_conditions, 'flux' ))
    #     for j=1:length(model_data.boundary_conditions.flux)
    #         flux =model_data.boundary_conditions.flux{j};
    #         fi= force_intensity(struct('magn',flux.normal_flux));
    #         # Note the sign  which reflects the formula (negative sign
    #         # in front of the integral)
    #         F = F - distrib_loads(flux.femm, sysvec_assembler, geom, temp, fi, 2);
    #     end
    #     clear flux fi
    # end

    task = 'System solution'
    start = time.time()

    # Solve for the displacement
    u.scatter_sysvec(spsolve(K, F))

    timings.append((task, time.time() - start))

    # Update the model data
    model_data['geom'] = geom
    model_data['u'] = u
    model_data['timings'] = timings
    return True