- The material system operates by creating a producer/consumer relationship among objects
    * `Material` objects produce properties.
    * Other MOOSE objects (including Materials) consume these properties.

- `Material` objects produce properties:
    * Each property must be declared to be available for use by Kernels, boundary conditions, etc.
    * `declareProperty<TYPE>()` declares a material property, and returns a writable reference.
    * Override `computeQpProperties()` to compute all of the declared properties at one quadrature point. Within this method, the references obtained from `declareProperty` are updated.
    * Can use coupled variables in the same way as Kernels (e.g., `coupledValue()`, etc.)

[](---)

- Objects consume material properties:
    * To use a material property, call `getMaterialProperty<TYPE>()` in a `Kernel` or other object, and store the constant reference.
- Quantities are recomputed at quadrature points, as needed.
- The values are not stored between timesteps unless "stateful" properties are enabled.
    * Call `declarePropertyOld<TYPE>()` or `declarePropertyOlder<TYPE>()` to enable stateful material properties.
- Multiple `Material` objects may define the same "property" for different parts of the subdomain or boundaries.

[](---)
# Example 8

Look at [Example 8](/wiki/MooseExamples/Example_08)

[](---)
# Default Material Properties
- Default values for material properties may be assigned within the `validParams` function.
```cpp
addParam<MaterialPropertyName>("combination_property_name", 12345,
 "The name of the property providing the luggage combination");
```
- Only scalar (`Real`) values may have defaults.
- When `getMaterialProperty<Real>("combination_property_name")` is called, the default will be returned if the value has not been computed via a `delcareProperty` call within a `Material` object.




[](---)
# Automatic Material Property Output
- `Material` properties can be output, provided they are one of the supported types.
- Output of `Material` properties is enabled by setting the "outputs" parameter. 
- The following example creates two additional variables called "mat1" and "mat2" that will show up in the output file. 

```text
[Materials]
  [./generic]
    type = GenericConstantMaterial
    block = 0
    prop_names  = 'mat1 mat2'
    prop_values = '1 2'
    outputs = exodus
  [../]
[]
[Outputs]
  console = true
  exodus = true
  [./oversample]
    type = Exodus
    oversample = true
    refinements = 2
  [../]
[]
```

[](---)

- A list of possible options for the 'outputs' parameter:

|'outputs = ' |Behavior |
| :- | :- |
| `none` | disables outputting of all properties to all possible outputs (default) |
| `all` | enables outputting of all properties to all possible outputs |
| `exodus` | enables outputting of all properties to the output named "exodus" from the "[Outputs]" block |
| 'property1 property2' | limits the output to the properties listed |


- Supported types include: `Real`, `RealVectorValue`, and `RealTensorValue`

[](---)

- Setting `outputs=all` will write to all possible outputs; by default `outputs` is set to "none". 
- It is possible to limit which properties are written to the output for each `Material` using the "output_properties" parameter. 
- For example, setting `output_properties = mat1` in the above example ensures that only "mat1" is written. 
- Leaving this parameter empty will result in all properties being written (the default).
- For additional examples, see the associated tests in `$MOOSE_DIR/test/tests/materials/output`.

[](---)
# Output via the `Outputs` block

- The following input file section writes the `Material` property named 'mat1'. 
- Notice that this method does not require changing anything within the `Material` blocks, which is useful if a material is defined on many subdomains and/or boundaries. 
- The `show_material_properties` parameter is optional. Without it, all supported `Material` properties will be written.

```text
[Materials]
  [./generic]
    type = GenericConstantMaterial
    block = 0
    prop_names  = 'mat1 mat2'
    prop_values = '1 2'
  [../]
[]
[Outputs]
  console = true
  [./out]
    type = Exodus
    output_material_properties = true
    show_material_properties = 'mat1'
  [../]
[]
```

[](---)
# Supported Output Types

- `Material` properties can be of arbitrary (C++) type, but not all types can be output.
- The following is a list of the `Material` property types that support automatic output. (Assume you named your property "prop" when calling `declareProperty`.)

|Type |AuxKernel |Variable Name(s)|
|:-|:-|:-|
| Real| [`MaterialRealAux`][real] | prop |
| RealVectorValue | [`MaterialRealVectorValueAux`][vector] | prop_1, prop_2, and prop_3 |
| RealTensorValue | [`MaterialRealTensorValueAux`][tensor] | prop_11, prop_12, prop_13, prop_21, etc. |

  [real]: http://www.mooseframework.org/docs/doxygen/moose/classMaterialRealAux.html
  [vector]: http://www.mooseframework.org/docs/doxygen/moose/classMaterialRealVectorValueAux.html  
  [tensor]: http://www.mooseframework.org/docs/doxygen/moose/classMaterialRealTensorValueAux.html

[](---)
# Stateful Material Properties

- It can sometimes be useful to have "old" values of `Material` properties available in a simulation.
- For example, this situation arises in solid mechanics plasticity constitutive models.
- Traditionally, this type of value is called a "state variable".
- In MOOSE, they are called "Stateful Material Properties".
- To provide a material property with an old state, use `declarePropertyOld<TYPE>()` and `declarePropertyOlder<TYPE>()`.
- Stateful `Material` properties require more memory.


[](---)
# Example 9

Look at [Example 9](/wiki/MooseExamples/Example_09)