예제 #1
0
파일: elastic.py 프로젝트: adesam01/fempy
    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 프로젝트: adesam01/fempy
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
파일: element.py 프로젝트: adesam01/fempy
    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 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
예제 #5
0
파일: element.py 프로젝트: adesam01/fempy
    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]
예제 #6
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
예제 #7
0
파일: main.py 프로젝트: adesam01/fempy
def run_from_cl(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=1,
                        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]")
    parser.add_argument(
        "--ccompiler",
        default="gcc",
        help=("(Optional) C compiler for compiling weave.inline code "
              "[default: %(default)s]"))
    args = parser.parse_args(argv)

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

    # set some simulation wide configurations
    set_runopt("SQA", args.sqa)
    set_runopt("DEBUG", args.dbg)
    set_runopt("VERBOSITY", args.v)
    cc = has_c_compiler(args.ccompiler)

    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 = os.path.realpath(args.file)
    if not os.path.isfile(infile):
        raise SystemExit("{0}: no such file".format(infile))

    # find where to run the simulation
    fdir, fname = os.path.split(infile)
    runid, ext = os.path.splitext(fname)
    rundir = args.d or os.getcwd()

    if rundir != os.getcwd():
        # wants to run simulation in alternate directory
        if rundir == "_RUNID_":
            rundir = os.path.join(fdir, runid)
        else:
            rundir = os.path.realpath(rundir)
        try:
            os.makedirs(rundir)
        except OSError:
            pass

        dest = os.path.join(rundir, fname)
        try:
            os.remove(dest)
        except:
            pass

        shutil.copyfile(infile, dest)
        os.chdir(rundir)

        infile = dest

    input_lines = open(infile, "r").read()
    ui = UserInputParser(input_lines)
    implicit = ui.control[0] == 0.

    # set up the mesh
    mesh = femesh.Mesh(runid, ui.dim, ui.coords, ui.connect, ui.el_blocks,
                       ui.ssets, ui.nsets, ui.prdisps, ui.prforces,
                       ui.tractions, ui.blk_options, ui.materials)

    if implicit:
        import core.lento as lento
        fe_model = lento.Lento(runid)
    else:
        import core.veloz as veloz
        fe_model = veloz.Veloz(runid)

    fe_model.attach_mesh(mesh)
    fe_model.attach_control(ui.control)
    fe_model.setup()

    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
예제 #8
0
    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
        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
        global_data.set_var("TIME", t)
        global_data.set_var("TIME_STEP", dt)
        nodal_data.set_var("DISPL", u)

        findstiff = True

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

        logger.write(HEAD)

        for step in range(nsteps):

            loadfactor = float(step + 1) / float(nsteps)
            err1 = 1.
            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 = linsolve(K, b)
                if info > 0:
                    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)

                logger.write_formatted(step + 1,
                                       nit + 1,
                                       loadfactor,
                                       t,
                                       dt,
                                       err1,
                                       err2,
                                       tol,
                                       fmt=ITER_FMT)
                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()

            global_data.set_var("TIME", t)
            global_data.set_var("TIME_STEP", dt)
            nodal_data.set_var("DISPL", u)

            self.io.write_data_to_db()

            continue

        self.io.finish()
        tf = time.time()

        logger.write("\n{0}: execution finished".format(self.runid))
        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
예제 #9
0
파일: elemdb.py 프로젝트: adesam01/fempy
def initialize(eltyp, material):
    el = elemdb.get(eltyp.upper())
    if el:
        return el(material)
    raise WasatchError("{0}: element type not recognized".format(eltyp))
예제 #10
0
파일: elemdb.py 프로젝트: adesam01/fempy
def element_class_from_id(eid):
    for name, el in elemdb.items():
        if el.eid == eid:
            return el
    raise WasatchError("{0}: unkown element type".format(eid))
예제 #11
0
파일: elemdb.py 프로젝트: adesam01/fempy
def element_class_from_name(name):
    for clsnam, el in elemdb.items():
        if el.name[:3].upper() == name[:3].upper():
            return el
    raise WasatchError("{0}: unkown element type".format(name))
예제 #12
0
 def update_state(self, *args, **kwargs):
     raise WasatchError("update_state must be provided by model")
예제 #13
0
 def setup(self, pdict):
     raise WasatchError("setup must be provided by model")
예제 #14
0
파일: element.py 프로젝트: adesam01/fempy
 def volume(self, coords):
     raise WasatchError("Element {0} must define volume".format(self.name))