/*--------------------------------------------------------------------------*/
/* ALBERTA:  an Adaptive multi Level finite element toolbox using           */
/*           Bisectioning refinement and Error control by Residual          */
/*           Techniques for scientific Applications                         */
/*                                                                          */
/* file:     level_common.c                                                 */
/*                                                                          */
/* description:  routines for extracting level set of a piecewise linear    */
/*               fe-function                                                */
/*                                                                          */
/*--------------------------------------------------------------------------*/
/*                                                                          */
/*            file is included by level.c in 2d and 3d!                     */
/*                                                                          */
/*--------------------------------------------------------------------------*/
/*                                                                          */
/*  authors:   Alfred Schmidt                                               */
/*             Zentrum fuer Technomathematik                                */
/*             Fachbereich 3 Mathematik/Informatik                          */
/*             Universitaet Bremen                                          */
/*             Bibliothekstr. 2                                             */
/*             D-28359 Bremen, Germany                                      */
/*                                                                          */
/*             Kunibert G. Siebert                                          */
/*             Institut fuer Mathematik                                     */
/*             Universitaet Augsburg                                        */
/*             Universitaetsstr. 14                                         */
/*             D-86159 Augsburg, Germany                                    */
/*                                                                          */
/*  http://www.mathematik.uni-freiburg.de/IAM/ALBERTA                       */
/*                                                                          */
/*  (c) by A. Schmidt and K.G. Siebert (1996-2003)                          */
/*                                                                          */
/*--------------------------------------------------------------------------*/

int find_level(MESH *mesh, FLAGS fill_flag, const DOF_REAL_VEC *Level,
	       REAL value, int (*init)(const EL_INFO *, REAL [], int, int,
				       const REAL [][DIM+1]),
	       void (*cal)(const EL_INFO *, REAL [], int, int,
			   const REAL [][DIM+1], const REAL_D [DIM]))
{
  FUNCNAME("find_level");
  REAL  max_abs = 1.e-15;

  TEST_EXIT((level = Level)  && level->fe_space)
    ("no level function or no fe-space in level function\n");
  TEST_EXIT(linear = level->fe_space->bas_fcts)
    ("no basis functions in level function\n");
  TEST_EXIT(linear->degree == 1)("only for degree 1\n");
  get_real_vec = linear->get_real_vec;
  
  level_value = value;
  init_element = init;
  cal_element = cal;

#if DIM == 2
  n_el = 0;
#else
  n_tri = n_quad = 0;
#endif

  FOR_ALL_DOFS(level->fe_space->admin, 
	       max_abs = MAX(max_abs, ABS(level->vec[dof] - value)));
  small = 1.0e-8*MIN(1.0e-2,max_abs);

  fill_flag |= CALL_LEAF_EL|FILL_COORDS;
  mesh_traverse(mesh, -1, fill_flag, level_fct);

#if DIM == 2
/*   MSG("%d levels\n", n_el); */
  return(n_el);
#else
/*MSG("%d levels, %d triangles, %d quads\n", n_tri+n_quad, n_tri, n_quad); */
  return(n_tri+n_quad);
#endif
}
static S_CHAR  marker;

static void set_mark_fct(const EL_INFO *el_info)
{
  el_info->el->mark = marker;
}

void set_element_mark(MESH *mesh, FLAGS fill_flag, S_CHAR mark)
{
  marker = mark;
  mesh_traverse(mesh, -1, fill_flag, set_mark_fct);
}
