Metadata-Version: 2.1
Name: formable
Version: 0.1.5
Summary: Formability analysis in materials science.
Home-page: UNKNOWN
Author: Adam J. Plowman
Author-email: adam.plowman@manchester.ac.uk
License: UNKNOWN
Project-URL: Github, https://github.com/LightForm-group/formable
Description: [![PyPI version](https://badge.fury.io/py/formable.svg)](https://badge.fury.io/py/formable)
        
        `formable` provides tools for formability analysis in materials science.
        
        ## Installation
        
        `pip install formable`
        
        To support showing visualisations within a Jupyter notebook, you will also need to make sure Plotly is set up to work within the notebook environment:
        
        `pip install "notebook>=5.3" "ipywidgets>=7.2"`
        
        ## Getting Started
        
        ### `LoadResponse` and `LoadResponseSet`
        
        The response of a material to a load is represented by the `LoadResponse` class. Use the following code snippet create a `LoadResponse`, where the arguments passed represent incremental data (i.e. data for each of the "steps" in the loading):
        
        ```python
        from formable import LoadResponse
        
        load_response = LoadResponse(true_stress=true_stress, equivalent_strain=equivalent_strain)
        
        ```
        
        `true_stress` and `equivalent_strain` are Numpy arrays of shapes `(N, 3, 3)` and `(N,)`, respectively, for `N` increments within the load response.
        
        A collection of load responses that contain the same incremental data are represented by the `LoadResponseSet` class:
        
        ```python
        from formable import LoadResponse, LoadResponseSet
        
        all_responses = [LoadResponse(...), LoadResponse(...), ...]
        load_set = LoadResponseSet(all_responses)
        
        ```
        
        ### Yield functions
        
        A number of yield functions as defined in the literature can be fitted and visualised. As an example, let's visualise the difference between the Von Mises and the Tresca yield criteria:
        
        ```python
        from formable.yielding.yield_functions import YieldFunction, VonMises, Tresca
        
        von_mises = VonMises(equivalent_stress=70e6)
        tresca = Tresca(equivalent_stress=70e6)
        
        YieldFunction.compare_3D([von_mises, tresca])
        
        ```
        
        If run within a Jupyter environment, this code snippet will generated a 3D visualisation of the yield surfaces in principal stress space:
        
        ![yield_function_3D_viz](https://raw.githubusercontent.com/LightForm-group/formable/master/img/yield_function_3D_viz.gif)
        
        To look at a single plane within principal stress space, we can do this:
        
        ```python
        
        YieldFunction.compare_2D([von_mises, tresca], plane=[0, 0, 1])
        
        ```
        
        which generates a figure like this:
        
        ![yield_function_2D_viz](https://raw.githubusercontent.com/LightForm-group/formable/master/img/yield_function_2D_viz.png)
        
        We can choose any plane that intercepts the origin. For instance, we can also look at the π-plane (σ<sub>1</sub> = σ<sub>2</sub> = σ<sub>3</sub>):
        
        ```python
        
        YieldFunction.compare_2D([von_mises, tresca], plane=[1, 1, 1])
        
        ```
        
        which generates a figure like this:
        
        ![yield_function_2D_viz](https://raw.githubusercontent.com/LightForm-group/formable/master/img/yield_function_2D_viz_pi_plane.png)
        
        ### Yield function fitting
        
        Using experimental or simulated yielding tests, we can fit yield functions to the results. Consider a `LoadResponseSet` object that has a sufficiently large number of increments of `true_stress` and `equivalent_strain` data to enable such a fit. Using the Barlat "Yld2000-2D" anisotropic yield function as an example, we can perform a fit:
        
        ```python
        
        from formable import LoadResponse, LoadResponseSet
        from formable.yielding import YieldPointCriteria
        
        # First generate a LoadResponseSet, using the results from experiment/simulation:
        all_responses = [LoadResponse(...), LoadResponse(...), ...]
        load_set = LoadResponseSet(all_responses)
        
        # Then define a yield point criterion:
        yield_point = YieldPointCriteria('equivalent_strain', 1e-3)
        
        # Now calculate yield stresses according to the yield point criteria:
        load_set.calculate_yield_stresses(yield_point)
        
        # Now we can fit to the resulting yield stresses:
        load_set.fit_yield_function('Barlat_Yld2000_2D', equivalent_stress=70e6)
        
        ```
        
        #### Choosing the fitting parameters and initial guesses
        
        We can specify which of the yield function parameters we would like to fit, and which should remain fixed. We can also pass initial values to the fitting procedure. A least squares fit is employed to fit yield functions in `formable`.
        
        To fix a parameter during the fit, just pass it as a keyword argument to the `fit_yield_function` method, as we did in the above example, where we fixed the `equivalent_stress` parameter. To pass initial values for some of the parameters, we can pass a `initial_params` dictionary:
        
        ```python
        load_set.fit_yield_function('Barlat_Yld2000_2D', initial_params={'a1': 1.4})
        ```
        
        We can see the available parameters of a given yield function by using the `PARAMETERS` attribute of a `YieldFunction` class:
        
        ```python
        
        from formable.yielding.yield_functions import Barlat_Yld2000_2D
        
        print(Barlat_Yld2000_2D.PARAMETERS)
        
        ```
        
        which prints:
        
        ```
        ['a1',
         'a2',
         'a3',
         'a4',
         'a5',
         'a6',
         'a7',
         'a8',
         'equivalent_stress',
         'exponent']
         ```
        
         Alternatively, if we have created a yield function object (from a fitting procedure, or directly), we can use the `get_parameters` method to get the parameters and their values:
        
         ```python
         print(von_mises.get_parameters())
         ```
        
         which prints:
        
         ```
         {'equivalent_stress': 70000000.0}
         ```
        
        #### Visualising the fit
        
        Once a yield function has been fit to a load set, we can visualise the fitted yield function like this:
        
        ```python
        load_set.show_yield_functions_3D()
        ```
        
        or, in a similar way to above, we can visualise the fitted yield functions in a given principal stress plane, using:
        
        ```python
        load_set.show_yield_functions_2D(plane=[0, 0, 1])
        ```
        
        
        # Change Log
        
        ## [0.1.5] - 2020.08.18
        
        ### Changed
        
        - Default tolerance for `LoadResponse.is_uniaxial` check loosened to 0.3.
        
        ## [0.1.4] - 2020.07.01
        
        ### Changed
        
        - Print out the degree to which the stress state is uniaxial in `LoadResponse.is_uniaxial`.
        
        ## [0.1.3] - 2020.06.09
        
        ### Added
        
        - Add a method to estimate the Lankford coefficient via the tangent of the yield surface at a uniaxial stress state: `YieldFunction.get_numerical_lankford`
        - Add options to `YieldFunction.show_2D`, `YieldFunction.compare_2D` and `LoadResponseSet.show_yield_functions_2D` to visualise the tangent and normal to the yield function at a uniaxial stress state.
        - Add incremental data: `equivalent_plastic_strain` and `accumulated_shear_strain`, and associated `YieldPointCriteria` mappings for getting the yield stress (using the same method as that used for `equivalent_stress` [total]).
        - Add `show_stress_states` to `LoadResponseSet.show_yield_functions_3D` and `LoadResponseset.show_yield_functions_2D` to optionally hide stress states.
        - Add option to pass Plotly `layout` parameters to yield function visualisation methods.
        - Add property `num_increments` to `LoadResponse`.
        - Add `repr` to `LoadResponse` and `LoadResponseSet`.
        - Add `YieldFunction.from_name()` class method for generating a yield function from a string name and parameters.
        - Add `LoadResponse.incremental_data` property to return all incremental data as a `dict`.
        
        ### Changed
        
        - Check each `incremental_data` array passed to `LoadResponse` has the same outer shape (i.e. same number of increments).
        - `AVAILABLE_YIELD_FUNCTIONS` and `YIELD_FUNCTION_MAP` have been replaced with functions `get_available_yield_functions` and `get_yield_function_map`, respectively.
        - Number of excluded load responses is printed when performing yield function fitting.
        
        ## [0.1.2] - 2020.05.09
        
        ### Fixed
        
        - Fixed an issue when visualising yield surfaces in 3D (via `YieldSurface.compare_3D()`) (and also 2D) where, if the value of the yield function residual was already normalised (e.g. by the equivalent stress), then the isosurface drawn by Plotly was defective (showing spikes beyond the bounds of the contour grid), since the values that were being contoured were of the order 10^-8. This was because we normalised by the equivalent stress again when calculating the contour values. This was fixed by normalising by the absolute maximum value in the values that are returned by the residual function, rather than always normalising by the equivalent stress, so the contour values should be of the order 1 now, regardless of whether a given yield function residual value is normalised or not.
        - Fixed yield function residual for `Barlat_Yld91`, where hydrostatic stresses would return `np.nan`.
        - Check for bad `kwargs` in `LoadResponseSet.fit_yield_function`.
        - Added an `equivalent_stress` parameter to `Hill1948` to make it fit and visualise like the others. Not sure if this is the correct approach.
        
        ### Added
        
        - Added an option to show the bounds of the 3D contour grid when visualising yield functions in 3D.
        - Added an option to associate additional text in visualising yield functions (for the legend): `legend_text`.
        - Added module `load_cases` for generating load cases for simulations.
        - Added hover text in `YieldFunction.compare_2D` that shows the value(s) of the yield function at each grid point.
        - Added `lankford` property to `Hill1948` that returns the Lankford coefficient, as determined by the values of the anisotropic parameters.
        
        ### Changed
        
        - The tolerance for checking if a `uniaxial_response` passed to `LoadResponseSet.fit_yield_function` is in fact uniaxial has been loosened, since this way failing when it shouldn't have.
        - Normalise all yield function residuals by their equivalent stress parameter.
        
        ## [0.1.1] - 2020.04.12
        
        ### Changed
        
        Image URLs in README
        
        ## [0.1.0] - 2020.04.12
        
        Initial release.
        
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Topic :: Scientific/Engineering
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)
Classifier: Operating System :: OS Independent
Description-Content-Type: text/markdown
