<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def face_normals(self, values):
 """ Assign values to face normals. Parameters values : (len(self.faces), 3) float Unit face normals """

        if values is not None:
            # make sure face normals are C- contiguous float
            values = np.asanyarray(values,
                                   order='C',
                                   dtype=np.float64)

            # check if any values are larger than tol.merge
            # this check is equivalent to but 25% faster than:
            # `np.abs(values) > tol.merge`
            nonzero = np.logical_or(values > tol.merge,
                                    values < -tol.merge)

            # don't set the normals if they are all zero
            if not nonzero.any():
                log.warning('face_normals all zero, ignoring!')
                return

            # make sure the first few normals match the first few triangles
            check, valid = triangles.normals(
                self.vertices.view(np.ndarray)[self.faces[:20]])
            compare = np.zeros((len(valid), 3))
            compare[valid] = check

            if not np.allclose(compare, values[:20]):
                log.warning('face_normals didn\'t match triangles, ignoring!')
                return

        self._cache['face_normals'] = values