# Overview

A Recompute or "[Discrete](http://www.dictionary.com/browse/discrete)" is `Material` that may be detached from MOOSE and computed explicitly from other objects. An object inheriting from [MaterialPropertyInterface](http://www.mooseframework.org/docs/doxygen/moose/classMaterialPropertyInterface.html) may explicitly call the compute methods of a `Material` object via the `getMaterial` method.

The following should be considered when computing `Material` properties explicitly.

  * Foremost, it is possible to disable the automatic computation of a `Material` object by MOOSE by setting the `compute=false`.
  * When `compute=false` is set the compute method (`computeQpProperties`) is *not* called by MOOSE, instead it must be called explicitly in your application using the `computeProperties` method that accepts a quadrature point index.
  * When `compute=false` an additional method should be defined, `resetQpProperties`, which sets the properties to a safe value (e.g., 0) for later calls to the compute method. Not doing this can lead to erroneous material properties values. 


# Example
The original intent for this functionality was to enable to ability for material properties to be computed via iteration by another object, as in the following example.

First, consider define a material (`RecomputeMaterial`) that computes the value of a function and its derivative.

$$ f(p) = p^2*v $$


$$ f'(p) = 2*p*v, $$

where v is known value and not a function of p.

Second, define a second material (`NewtonMaterial`) that computes the value of $$p: f(p)=0$$ using Newton iterations. This material declares a material property (`_p`) which is what is solved for by iterating on the material properties containing `f` and `f'` from `RecomputeMaterial`. The `_discrete` member is a reference to a `Material` object retrieved with `getMaterial`.

for (unsigned int i = 0; i < _max_iterations; ++i)
  _p[_qp] -= _f[_qp] / _f_prime[_qp];
  if (std::abs(_f[_qp]) < _tol)

Please refer to the following test and test objects for the complete example.

* [NewtonMaterial.C](https://github.com/idaholab/moose/blob/devel/test/src/materials/NewtonMaterial.C)
* [NewtonMaterial.h](https://github.com/idaholab/moose/blob/devel/test/include/materials/NewtonMaterial.h)
* [RecomputeMaterial.C](https://github.com/idaholab/moose/blob/devel/test/src/materials/RecomputeMaterial.C)
* [RecomuteMaterial.h](https://github.com/idaholab/moose/blob/devel/test/include/materials/RecomputeMaterial.h)
* [recompute.i](https://github.com/idaholab/moose/blob/devel/test/tests/materials/discrete/recompute.i)

# Using/Creating a "Discrete" `Material`

1. Create a `Material` object by, in typical MOOSE fashion, inheriting from the `Material` object in your own application.
1. In your input file, set `compute=false`.
1. From within another object (e.g., another Material) that inherits from [`MaterialPropertyInterface`](http://www.mooseframework.org/docs/doxygen/moose/classMaterialPropertyInterface.html) call the `getMaterial` method. Note, this method returns a reference to a `Material` object, be sure to include `&` when using it.
1. When needed, call the `computeProperties` method of the `Material` being sure to provide the current quadrature point index to the method (`_qp` in most cases).