示例#1
0
文件: elastic.py 项目: tjfulle/Legacy
    def _check_params(self):
        """Check parameters and set defaults

        """
        if self._params[self.E] < 0.:
            raise WasatchError("Young's modulus E must be > 0")
        if not -1 < self._params[self.NU] < .5:
            raise WasatchError("Poisson's ratio NU out of bounds")
        return
示例#2
0
文件: tensor.py 项目: tjfulle/Legacy
def reduce_map(i, j, ncoord, ndof=None):
    """Mapping from higher order tensor space to lower order

    Parameters
    ----------
    ij : tuple
        Indeces in the higher-order tensor space (1, 1)
        ij[0] -> ith index
        ij[1] -> jth index

    Returns
    -------
    I : int
        Index in the lower-order tensor space

    Comments
    --------
    Maps according to:

       2D               3D
    00 -> 0           00 -> 0
    11 -> 1           11 -> 1
                      22 -> 2
    01 -> 2           01 -> 3
                      12 -> 4
                      02 -> 5

    """
    ij = (i, j)
    if ndof is None:
        ndof = ncoord
    if ndof != ncoord:
        raise WasatchError("NDOF must equal NCOORD (for now)")

    # sort the indices
    ij = sorted(ij)

    if ij[0] == ij[1]:
        return ij[0]

    if ncoord == 2:
        if any(i > 1 for i in ij):
            raise WasatchError("Bad index for 2D mapping: {0}".format(
                repr(ij)))
        return 2

    if ij == [0, 1]:
        return 3
    elif ij == [1, 2]:
        return 4
    elif ij == [0, 2]:
        return 5
    raise WasatchError("Bad index for 3D mapping: {0}".format(repr(ij)))
示例#3
0
    def register_variable(self, var, vtype="SCALAR"):
        """Register element variable

        """
        vtype = vtype.upper()
        var = var.upper()
        if vtype == "SCALAR":
            self._variables.append(var)

        elif vtype == "TENS":
            self._variables.extend([
                "{0}-{1}".format(var, x)
                for x in ("XX", "XY", "XZ", "YX", "YY", "YZ", "ZX", "ZY", "ZZ")
            ])
        elif vtype == "SYMTENS":
            self._variables.extend([
                "{0}-{1}".format(var, x)
                for x in ("XX", "YY", "ZZ", "XY", "YZ", "XZ")
            ])

        elif vtype == "SKEWTENS":
            self._variables.extend(
                ["{0}-{1}".format(var, x) for x in ("XY", "YZ", "XZ")])

        else:
            raise WasatchError("{0}: unrecognized vtype".format(vtype))
示例#4
0
def numberofintegrationpoints(ncoord, nelnodes, elident):
    """Return the number of integration points for each element type

    Parameters
    ----------
    ncoord : int
        No. spatial coords (2 for 2D, 3 for 3D)

    nelnodes : int
        No. nodes on the element

    elident : int
        Element identifier

    Returns
    -------
    n : int
        Number of integration points on element

    """
    n = None

    if ncoord == 1:

        n = nelnodes

    elif ncoord == 2:

        if nelnodes == 3:
            n = 1

        elif nelnodes == 6:
            n = 3

        elif nelnodes == 4:
            n = 4

        elif nelnodes == 8:
            n = 9

    elif ncoord == 3:

        if nelnodes == 4:
            n = 1

        elif nelnodes == 10:
            n = 4

        elif nelnodes == 8:
            n = 8

        elif nelnodes == 20:
            n = 27

    if n is None:
        raise WasatchError(
            "error: {0}D element with {1} nodes not supported".format(
                ncoord, nelnodes))
    return n
示例#5
0
 def parse_input_parameters(self, pdict):
     self.pdict = pdict
     for name, val in pdict.items():
         i = self.param_map.get(name.upper())
         if i is None:
             if cfg.debug:
                 raise WasatchError(
                     "{0}: {1}: unrecognized parameter".format(
                         self.name, name))
             continue
         self._params[i] = val
示例#6
0
    def element_data(self, ave=False, exo=False, item=None):
        """Return the current element data

        Returns
        -------
        data : array_like
            Element data

        """
        a, b = 0, self.ndat
        if item is not None:
            # Get the index of item
            try:
                a, b = DATMAP.get(item.upper())
            except TypeError:
                raise WasatchError("{0}: not in element data".format(item))
            if b == -1:
                b = self.ndat
        if ave or exo:
            return self.data[0, self.ngauss][a:b]
        return self.data[0, :, a:b]
示例#7
0
文件: rve.py 项目: tjfulle/Legacy
    def __init__(self, lmnid, nodes, coords, material, mat_params, perturbed,
                 *args, **kwargs):

        import src.fem.core.fe_model as fem

        # Find parent and child elements
        parent = kwargs.get("ParentElement")
        if parent is None:
            raise UserInputError("RVE element expected a parent element")
        parent = DEFAULT_ELEMENTS.get(parent.upper())
        if parent not in (Quad4, ):
            raise WasatchError("RVE requires Quad4 parent element")
        self.name = parent.name

        # The analysis driver
        analysis_driver = kwargs.get("AnalysisDriver")
        if analysis_driver is None:
            raise UserInputError("No rve driver specified for RVE")
        analysis_driver = analysis_driver.upper()
        if analysis_driver not in ("WASATCH", ):
            raise UserInputError("{0}: unsupported rve driver")
        self.analysis_driver = analysis_driver

        ki = kwargs.get("KeepIntermediateResults")
        if ki is not None:
            ki = {"FALSE": 0, "TRUE": 1}.get(ki.upper(), 1)
        self.wipe_intermediate = not bool(ki)

        template = kwargs.get("InputTemplate")
        if template is None:
            raise UserInputError("RVE element expected an input template")
        if not os.path.isfile(template):
            raise UserInputError("{0}: no such template file".format(template))
        self.input_template_file = template
        self.template = open(template, "r").read()

        # RVE inherits from parent.  Is there a better way to do this?
        self.parent = parent(lmnid, nodes, coords, material, mat_params,
                             perturbed, *args, **kwargs)
        self.bndry = self.parent.bndry
        self.nnodes = self.parent.nnodes
        self.ncoord = self.parent.ncoord
        self.ndof = self.parent.ndof
        self.dim = self.parent.dim
        self.ngauss = self.parent.ngauss
        self.cornernodes = self.parent.cornernodes
        self.facenodes = self.parent.facenodes
        self.gauss_coords = self.parent.gauss_coords
        self.gauss_weights = self.parent.gauss_weights

        # Find the refinement level and form the child mesh
        self.refinement = kwargs.get("Refinement", 10)
        self.generate_child_mesh_info(coords)

        self.end_state = None

        super(RVE, self).__init__(lmnid, nodes, coords, material, mat_params,
                                  perturbed, *args, **kwargs)

        # setup FEModel object for the entire RVE simulation
        wasatch_input = self.generate_wasatch_input(0.,
                                                    np.zeros((self.nnodes, 3)))
        runid = "{0}_EID={1}_RVE".format(kwargs["RUNID"], lmnid)
        self.rve_model = fem.FEModel.from_input_string(runid,
                                                       wasatch_input,
                                                       rundir=os.getcwd())
示例#8
0
 def volume(self, coords):
     raise WasatchError("Element {0} must define volume".format(self.name))
示例#9
0
文件: wasatch.py 项目: tjfulle/Legacy
def main(argv=None):
    if argv is None:
        argv = sys.argv[1:]

    parser = argparse.ArgumentParser()
    parser.add_argument("file")
    parser.add_argument("--chk-mesh", default=False, action="store_true",
        help="Stop to check mesh before running simulation [default: %(default)s]")
    parser.add_argument("--piecewise", default=False, action="store_true",
        help="""Print the piecewise solution as a function of x
                [default: %(default)s""")
    parser.add_argument("--dbg", default=False, action="store_true",
        help="Debug mode [default: %(default)s]")
    parser.add_argument("--sqa", default=False, action="store_true",
        help="SQA mode [default: %(default)s]")
    parser.add_argument("-v", default=None, type=int,
        help="Verbosity [default: %(default)s]")
    parser.add_argument("--wm", default=False, action="store_true",
        help="Write mesh to ascii file [default: %(default)s]")
    parser.add_argument("-j", default=1, type=int,
        help="Number of proccesses to run simultaneously [default: %(default)s]")
    parser.add_argument("-E", default=False, action="store_true",
        help="Write exodus file [default: %(default)s]")
    parser.add_argument("--clean", default=False, action="store_true",
        help="Clean simulation output [default: %(default)s]")
    parser.add_argument("--cleanall", default=False, action="store_true",
        help="Clean all simulation output [default: %(default)s]")
    parser.add_argument("--profile", default=False, action="store_true",
        help="Run the simulation in a profiler [default: %(default)s]")
    parser.add_argument("-d", nargs="?", default=None, const="_RUNID_",
        help="Directory to run analysis [default: %(default)s]")
    args = parser.parse_args(argv)

    if args.profile:
        raise WasatchError("Profiling must be run from __main__")

    # set some simulation wide configurations
    ro.debug = args.dbg
    ro.sqa = args.sqa
    ro.verbosity = args.v
    if not cfg.exodus:
        cfg.exodus = args.E

    if args.clean or args.cleanall:
        from src.base.utilities import clean_wasatch
        clean_wasatch(os.path.splitext(args.file)[0], args.cleanall)
        return 0

    ti = time.time()

    infile = args.file
    if args.d is not None:
        fdir, fname = os.path.split(os.path.realpath(args.file))
        if args.d == "_RUNID_":
            d = os.path.join(fdir, os.path.splitext(fname)[0])
        else:
            d = os.path.realpath(args.d)
        try: os.makedirs(d)
        except OSError: pass
        infile = os.path.join(d, fname)
        try: os.remove(infile)
        except: pass
        shutil.copyfile(args.file, infile)
        os.chdir(d)

    fe_model = fem.FEModel.from_input_file(infile, verbosity=args.v)

    if args.wm:
        fe_model.mesh.write_ascii(fe_model.runid)

    if args.chk_mesh:
        fe_model.logger.write("See {0} for initial mesh".format(
                fe_model.runid + ".exo"))
        resp = raw_input("Continue with simulation? (Y/N) [N]: ")
        stop = not {"Y": True}.get(resp.upper().strip(), False)
        if stop:
            return 0

    try:
        retval = fe_model.solve(nproc=args.j)
    except KeyboardInterrupt:
        sys.stderr.write("\nKeyboard interrupt\n")
        retval = -1

    tf = time.time()
    fe_model.logger.write("wasatch: total simulation time: {0:.2f}s".format(
            tf - ti))
    fe_model.logger.close()
    return retval
示例#10
0
文件: lento.py 项目: tjfulle/Legacy
    def solve(self, nproc=1, disp=0):
        """ 2D and 3D Finite Element Code

        Currently configured to run either plane strain in 2D or general 3D but
        could easily be modified for plane stress or axisymmetry.

        """
        # Local Variables
        # ---------------
        # du : array_like, (i,)
        #     Nodal displacements.
        #     Let wij be jth displacement component at ith node. Then du
        #     contains [w00, w01, w10, w11, ...] for 2D
        #     and [w00, w01, w02, w10, w11, w12, ...) for 3D

        # dw : array_like, (i,)
        #     Correction to nodal displacements.

        # K : array_like, (i, j,)
        #     Global stiffness matrix. Stored as
        #              [K_1111 K_1112 K_1121 K_1122...
        #               K_1211 K_1212 K_1221 K_1222...
        #               K_2111 K_2112 K_2121 K_2122...]
        #     for 2D problems and similarly for 3D problems

        # F : array_like, (i, )
        #     Force vector.
        #     Currently only includes contribution from tractions acting on
        #     element faces (body forces are neglected)
        # R : array_like, (i, )
        #     Volume contribution to residual
        # b : array_like (i, )
        #     RHS of equation system
        exo_io = self.io
        runid = self.runid
        control = self.control_params()
        X = self.mesh.nodes()
        connect = self.mesh.connect()
        elements = self.mesh.elements()
        fixnodes = self.mesh.displacement_bcs()
        nforces = self.mesh.nodal_forces()
        tractions = self.mesh.traction_bcs()

        t0 = time.time()

        dim = elements[0].ndof
        nelems = elements.shape[0]
        nnode = X.shape[0]
        ndof = elements[0].ndof
        ncoord = elements[0].ncoord
        u = np.zeros((nnode * ndof))
        du = np.zeros((nnode * ndof))
        nodal_stresses = np.zeros((nnode, 6))
        # tjf: nodal_state will have to be adjusted for multi-material where
        # each node may be connected to elements of different material.
        # nodal_state = np.zeros((nnode, max(el.material.nxtra for el in elements)))

        nproc = 1.

        #  Simulation setup
        (tint, nsteps, tol, maxit, relax, tstart, tterm, dtmult,
         verbosity) = control

        nsteps, maxit = int(nsteps), int(maxit)
        t = tstart
        dt = (tterm - tstart) / float(nsteps) * dtmult

        findstiff = True

        self.logger.write(
            intro("Implicit", runid, nsteps, tol, maxit, relax, tstart, tterm,
                  ndof, nelems, nnode, elements))

        for step in range(nsteps):

            loadfactor = float(step + 1) / float(nsteps)
            err1 = 1.
            t += dt

            self.logger.write("Step {0:.5f} Load factor {1:.5f}, "
                              "Time: {2}, Time step: {3}".format(
                                  step + 1, loadfactor, t, dt))

            # Newton-Raphson loop
            mult = 10 if step == 0 and ro.reducedint else 1
            for nit in range(mult * maxit):

                # --- Update the state of each element to end of Newton step
                update_element_states(t, dt, X, elements, connect, u, du)

                # --- Update nodal stresses
                for (inode, els) in enumerate(self.mesh._node_el_map):
                    sig = np.zeros(6)
                    # nx = elements[els[0]].material.nxtra
                    # xtra = np.zeros(nx)
                    acc_volume = 0.
                    for iel in els:
                        if iel == -1:
                            break
                        el = elements[iel]
                        vol = el._volume
                        sig += el.element_data(ave=True, item="STRESS") * vol
                        # xtra += el.element_data(ave=True, item="XTRA") * vol
                        acc_volume += vol
                    nodal_stresses[inode][:] = sig / acc_volume
                    # nodal_state[inode][0:nx] = xtra / acc_volume
                    continue

                # --- Get global quantities
                if findstiff:
                    gK = global_stiffness(t, dt, X, elements, connect, du,
                                          nproc)
                    findstiff = False
                K = np.array(gK)
                F = global_traction(t, dt, X, elements, connect, tractions,
                                    nforces, du)
                R = global_residual(t, dt, X, elements, connect, du)
                b = loadfactor * F - R

                apply_dirichlet_bcs(ndof, nnode, t, fixnodes, u, du,
                                    loadfactor, K, b)

                # --- Solve for the correction
                c, dw, info = utils.linsolve(K, b)
                if info > 0:
                    self.logger.write("using least squares to solve system",
                                      beg="*** ")
                    dw = np.linalg.lstsq(K, b)[0]
                elif info < 0:
                    raise WasatchError(
                        "illegal value in %d-th argument of internal dposv" %
                        -info)

                # --- update displacement increment
                du += relax * dw

                # --- Check convergence
                wnorm = np.dot(du, du)
                err1 = np.dot(dw, dw)
                if err1 > 1.E-10:
                    findstiff = True
                if wnorm != 0.:
                    err1 = np.sqrt(err1 / wnorm)
                err2 = np.sqrt(np.dot(b, b)) / float(ndof * nnode)

                self.logger.write("Iteration number {0}: "
                                  "Correction {1} "
                                  "Residual {2} "
                                  "tolerance {3}".format(nit, err1, err2, tol),
                                  beg="  ")

                if err1 < tol:
                    break

                continue

            else:
                raise WasatchError("Problem did not converge")

            # Update the total displacecment
            u += du

            # Update the nodal coordinates
            x = np.zeros((nnode, ndof))
            for i in range(nnode):
                for j in range(ndof):
                    x[i, j] = X[i, j] + u[ndof * i + j]
                    continue
                continue

            # Advance the state of each element
            for element in elements:
                element.advance_state()
                if element.rve_model:
                    element.dump_rve_end_state()

            if exo_io:
                self.dump_time_step_data(t, dt, u)

            continue

        if exo_io:
            exo_io.finish()
        tf = time.time()

        self.logger.write("\n{0}: execution finished".format(self.runid))
        self.logger.write("{0}: total execution time: {1:8.6f}s".format(
            runid, tf - t0))

        retval = 0
        if disp:
            retval = {
                "DISPLACEMENT": u,
                "TIME": t,
                "DT": dt,
                "ELEMENT DATA":
                np.array([el.element_data() for el in elements]),
                "NODAL STRESSES": nodal_stresses,
                # "NODAL STATES": nodal_state,
                "NODAL COORDINATES": x
            }

        return retval
示例#11
0
def brick_mesh(xpoints, ypoints, zpoints=None, test=False):
    """Generate a [2,3]D block mesh.

    Parameters
    ----------
    xpoints : array_like
        Points defining the x-axis from x0 to xf
    ypoints : array_like
        Points defining the y-axis from y0 to yf
    zpoints : array_like [optional]
        Points defining the z-axis from z0 to zf

    Returns
    -------
    coords : array_like, (i, j)
        Nodal coordinates
        coords[i, j] -> jth coordinate of ith node
    conn : array_like, (i, j)
        nodal connectivity
        conn[i, j] -> jth node of the ith element

    """
    dim = 2 if zpoints is None else 3

    if dim == 3:
        raise WasatchError("3D inline mesh not done")

    shape = [
        xpoints.size,
        ypoints.size,
    ]
    if dim == 3:
        shape.append(zpoints.size)
    shape = np.array(shape, dtype=np.int)

    nnode = np.prod(shape)
    nel = np.prod(shape - 1)

    # Nodal coordinates
    if dim == 3:
        coords = [[x, y, z] for z in zpoints for y in ypoints for x in xpoints]
    else:
        coords = [(x, y, 0) for y in ypoints for x in xpoints]
    coords = np.array(coords, dtype=np.float64)

    # Connectivity
    if dim == 2:
        row = 0
        conn = np.zeros((nel, 4), dtype=np.int)
        nelx = xpoints.size - 1
        for lmn in range(nel):
            ii = lmn + row
            conn[lmn, :] = [ii, ii + 1, ii + nelx + 2, ii + nelx + 1]
            if (lmn + 1) % (nelx) == 0:
                row += 1
            continue

    else:
        grid = np.zeros(shape, dtype=np.int)
        for ii, ic in enumerate(_cycle(shape)):
            grid[tuple(ic)] = ii
        conn = np.zeros((nel, 8), dtype=np.int)
        for ii, (ix, iy, iz) in enumerate(_cycle(shape - 1)):
            conn[ii, :] = [
                grid[ix, iy, iz], grid[ix + 1, iy, iz], grid[ix + 1, iy + 1,
                                                             iz],
                grid[ix, iy + 1, iz], grid[ix, iy, iz + 1], grid[ix + 1, iy,
                                                                 iz + 1],
                grid[ix + 1, iy + 1, iz + 1], grid[ix, iy + 1, iz + 1]
            ]

    return coords, conn
示例#12
0
def plane_stress_unit(nel):
    import src.fem.element.element as el

    if nel not in (1, 2):
        raise WasatchError("wrong NEL")

    # E, nu, Y, e0, n, edot0, m
    materialprops = np.array([96, .333333, 1.e99, 0., 0., 0., 1.])
    ncoord = 2
    ndof = 2

    def _mesh(n):
        """     3        [2]        2
                 o --------------- o
                 |                 |
                 |                 |
             [3] |                 | [1]
                 |                 |
                 |                 |
                 o --------------- o
                0        [0]        1
        """
        if n == 1:
            # 1 element
            coords = np.array([[0., 0.], [2., 0.], [2., 1.], [0., 1.]])
            connect = np.array([[0, 1, 2, 3]])

        elif n == 2:
            # 2 elements
            coords = np.array([[0., 0.], [.5, 0.], [.5, 1.], [0., 1.],
                               [.5, 0.], [1., 0.], [1., 1.], [.5, 1.]])
            connect = np.array([[0, 1, 2, 3], [4, 5, 6, 7]])

        return coords, connect

    coords, connect = _mesh(nel)
    nelnodes = np.array([len(x != np.nan) for x in connect])
    elident = np.array([el.initialize("Quad4") for i in range(len(connect))])

    # fixnodes : List of prescribed displacements at nodes
    #   fixnodes[i, 0] -> Node number
    #   fixnodes[i, 1] -> Displacement component (x: 0, y: 1, or z: 2)
    #   fixnodes[i, 2] -> Value of the displacement (function)
    comp = lambda x: {"x": 0, "y": 1, "z": 2}.get(x.lower())
    fixnodes = np.array([[0, comp("x"), lambda t: 0.],
                         [0, comp("y"), lambda t: 0.],
                         [3, comp("x"), lambda t: 0.],
                         [3, comp("y"), lambda t: 0.]])

    # dloads : List of element tractions
    #   dloads[i, 0] -> Element number
    #   dloads[i, 1] -> face number
    #   dloads[i, 2], dloads[i, 3], dloads[i, 4] -> Components of traction
    n = len(elident) - 1
    dloads = np.array([[n, 1, 10.e5, 0., 0.]])

    # control: nsteps, tol, maxit, relax, tstart, tterm, dtmult
    control = np.array([10, 1.e-4, 60, .5, 0., 5., 1.])
    control = np.array([10, 1.e-4, 30, 1., 0., 5., 1.])
    fe_solve(sys.stdout, control, ncoord, ndof, coords, connect, nelnodes,
             elident, fixnodes, dloads)
示例#13
0
 def update_state(self, *args, **kwargs):
     raise WasatchError("update_state must be provided by model")
示例#14
0
 def setup(self, pdict):
     raise WasatchError("setup must be provided by model")