static void reset_time_stopwatch_handler(ClickRecognizerRef recognizer, void *context) {
  bool is_running = started;
  stop_stopwatch();
  start_time = 0;
  elapsed_time = 0;
  if(is_running) start_stopwatch();
  update_stopwatch();}
static void end_half_handler(ClickRecognizerRef recognizer, void *context) {
  bool is_running = started;
  stop_stopwatch();
  start_time = 0;
  elapsed_time = 0;
  if(is_running) start_stopwatch();
  if (half == FIRST_HALF) half = SECOND_HALF;
  else half = NO_HALF;
  update_stopwatch();}
Exemplo n.º 3
0
int wff2obdd(const_serializable input,
             serializable *output,
             const int brute_force)
{
    register unsigned int ix;

    tv_wff_expr e;

    start_stopwatch("compilation time");
    if (input->tag == TAGtv_wff_flat_kb) {
        tv_wff input_wff = to_tv_wff(to_tv_wff_flat_kb(input)->constraints);
        *output = to_serializable(new_obdd_flat_kb(to_tv_wff_flat_kb(input)->name,
                                                   to_kb(new_obdd(rdup_values_set_list(input_wff->domains),
                                                                  rdup_variable_list(input_wff->variables),
                                                                  rdup_variable_list(input_wff->encoded_variables),
                                                                  rdup_constant_list(input_wff->constants),
                                                                  input_wff->encoding,
                                                                  new_obdd_node_list(),
                                                                  -1))));
        
        e = flatten_expr_list(input_wff->e);
        to_obdd(to_obdd_flat_kb(*output)->constraints)->root = tv_wff_expr_to_obdd(input_wff->variables,
                                                                                   e,
                                                                                   to_obdd(to_obdd_flat_kb(*output)->constraints)->nodes,
                                                                                   brute_force);
        rfre_tv_wff_expr(e);
    } else if (input->tag == TAGtv_wff_hierarchy) {
        node_list nodes = new_node_list();
        *output = to_serializable(new_obdd_hierarchy(nodes));
        for (ix = 0; ix < to_hierarchy(input)->nodes->sz; ix++) {
            tv_wff node_input = to_tv_wff(to_hierarchy(input)->nodes->arr[ix]->constraints);
            obdd node_output = new_obdd(rdup_values_set_list(node_input->domains),
                                        rdup_variable_list(node_input->variables),
                                        rdup_variable_list(node_input->encoded_variables),
                                        rdup_constant_list(node_input->constants),
                                        node_input->encoding,
                                        new_obdd_node_list(),
                                        -1);
            node result;
            e = flatten_expr_list(node_input->e);
            node_output->root = tv_wff_expr_to_obdd(node_input->variables, e, node_output->nodes, brute_force);
            rfre_tv_wff_expr(e);
            result = new_node(rdup_lydia_symbol(to_hierarchy(input)->nodes->arr[ix]->type),
                              rdup_edge_list(to_hierarchy(input)->nodes->arr[ix]->edges),
                              to_kb(node_output));
            append_node_list(nodes, result);
        }
    } else {
        assert(0);
        abort();
    }
    stop_stopwatch("compilation time");

    return 1;
}
Exemplo n.º 4
0
// *************************************************************************************************
// @fn          mx_stopwatch
// @brief       Stopwatch set routine. Mx stops stopwatch and resets count.
// @param       u8 line LINE2
// @return      none
// *************************************************************************************************
void mx_stopwatch(u8 line)
{
    // Stop stopwatch
    stop_stopwatch();

    // Reset stopwatch count
    reset_stopwatch();

    // Display "00:00:00"
    display_stopwatch(line, DISPLAY_LINE_UPDATE_FULL);
}
// *************************************************************************************************
// @fn          mx_stopwatch
// @brief       Stopwatch set routine. Mx stops stopwatch and resets count.
// @param       u8 line	LINE2
// @return      none
// *************************************************************************************************
void mx_stopwatch(u8 line)
{
	// Stop stopwatch
	stop_stopwatch();
			
	// Reset stopwatch count
	init_stopwatch();	
	LAP_TimeFlag = LAP_CATCHED;
	
	// Set mode
	set_stopwatchmode();
	
	// Display "00:00:00"
	display_stopwatch(line, DISPLAY_LINE_UPDATE_FULL);
}
Exemplo n.º 6
0
// *************************************************************************************************
// @fn          sx_stopwatch
// @brief       Stopwatch direct function. Button DOWN starts/stops stopwatch, but does not reset
// count.
// @param       u8 line LINE2
// @return      none
// *************************************************************************************************
void sx_stopwatch(u8 line)
{
    // DOWN: RUN, STOP
    if (button.flag.down)
    {
        if (sStopwatch.state == STOPWATCH_STOP)
        {
            // (Re)start stopwatch
            start_stopwatch();
        }
        else
        {
            // Stop stopwatch
            stop_stopwatch();
        }

    }
}
Exemplo n.º 7
0
int cardio_state(void){
	if(stopwatch_started_or_stopped()){
			switch(stopwatch_started()){
				case true:
					stop_stopwatch();
					break;
				case false:
					start_stopwatch();
					break;
				default:
					return -1;
			}
		}
		if(stopwatch_reset()){			
			reset_stopwatch(); 	   // Save observed values, set stopwatch to 00:00:00:00
			save_to_data();	   	   // Push observed values to datastate
			reset_observed_data(); // Reset the observed values
		}
			
	output_heartrate();
	output_stopwatch();
	
	return 0;
}
Exemplo n.º 8
0
int gotcha_set_input(diagnostic_problem problem,
                     const_tv_dnf_hierarchy input,
                     const_node root)
{
    dnf_tree sd;
    int_list_list variable_mappings;

    unsigned int ix = 0;

    start_stopwatch("preprocessing time");

    if (int_list_listNIL == (variable_mappings = new_int_list_list())) {
        return 0;
    }

    if (values_set_listNIL == (problem->domains = new_values_set_list())) {
        rfre_int_list_list(variable_mappings);
    }
    if (variable_listNIL == (problem->variables = new_variable_list())) {
        rfre_int_list_list(variable_mappings);
        rfre_values_set_list(problem->domains);
    }
    if (variable_listNIL == (problem->encoded_variables = new_variable_list())) {
        rfre_int_list_list(variable_mappings);
        rfre_values_set_list(problem->domains);
        rfre_variable_list(problem->encoded_variables);
    }

    inline_variables(to_hierarchy(input),
                     root,
                     mapping_listNIL,
                     problem->domains,
                     problem->variables,
                     problem->encoded_variables,
                     constant_listNIL,
                     variable_mappings,
                     int_list_listNIL,
                     NULL);

    sd = dnf_tree_make(to_const_hierarchy(input), root, variable_mappings, &ix);

    problem->u.tv_tdnf_sd.model = sd;

    rfre_int_list_list(variable_mappings);

    problem->encoding = root->constraints->encoding;

    gotcha_var_buffer = (signed char *)malloc(problem->variables->sz * sizeof(signed char));
    if (NULL == gotcha_var_buffer) {
        return 0;
    }

    problem->tv_cache = initialize_tv_variables_cache(problem->variables);
    problem->mv_cache = initialize_mv_variables_cache(problem->encoded_variables,
                                                      problem->domains);

    dnf_tree_sort(sd, sd, problem->tv_cache, problem->mv_cache, problem->encoding);

    stop_stopwatch("preprocessing time");

    return 1;
}
Exemplo n.º 9
0
int gotcha_diag(diagnostic_problem problem, const_tv_term alpha)
{
    priority_queue opened;
    gotcha_node initial;

    dnf_tree consistent_input;
    tv_term_list_list systems;

    unsigned int old_diagnoses;

    int terminate = 0;
    int result = 1;

    diagnostic_problem_reset(problem);

    sort_int_list(alpha->neg);
    sort_int_list(alpha->pos);

    start_stopwatch("observation filtering time");
    consistent_input = dnf_tree_filter(dnf_tree_copy(problem->u.tv_tdnf_sd.model),
                                       alpha);
    stop_stopwatch("observation filtering time");
    systems = new_tv_term_list_list();

    get_systems(consistent_input, systems);

/* Start the timer. */
    start_stopwatch("search time");

    opened = priority_queue_new(cmp_nodes,
                                (priority_queue_element_destroy_func_t)gotcha_node_free,
                                (void *)systems->sz);
    initial = gotcha_node_new(systems->sz);
    priority_queue_push(opened, initial);
    increase_int_counter("pushed");
    maximize_int_counter("max", 1);

    while (!terminate && !priority_queue_empty(opened)) {
        gotcha_node current = priority_queue_pop(opened);
        candidate_found(current->cardinality);
        if (is_terminate()) {
            gotcha_node_free(current);
            break;
        }

        if (current->depth != 0) {
/* The root node has no siblings. */
            if (!enqueue_sibling(problem, opened, current, systems)) {
                result = 0;

                gotcha_node_free(current);
                break;
            }
        }
        if (is_diagnosis(current, systems)) {
            tv_term diagnosis = build_term(current, systems);
            if (NULL == diagnosis) {
                result = 0;

                gotcha_node_free(current);
                break;
            }
            old_diagnoses = problem->diagnoses->sz;
            if (!add_diagnosis_from_tv_term(problem,
                                            diagnosis,
                                            &terminate,
                                            1)) {
                result = 0;
                rfre_tv_term(diagnosis);
                gotcha_node_free(current);
                break;
            }


            if (cones != NULL && problem->diagnoses->sz - 1 == old_diagnoses) {
                assert(problem->diagnoses->sz > 0);
/* @todo: Fix the termination here. */
                expand_cone_exhaustive(cones,
                                       alpha,
                                       problem->diagnoses->arr[problem->diagnoses->sz - 1]);
            }

            rfre_tv_term(diagnosis);
            gotcha_node_free(current);
        } else {
            if (!enqueue_next_best_state(problem, opened, current, systems)) {
                result = 0;

                gotcha_node_free(current);
                break;
            }
        }
    }

    priority_queue_free(opened);
    fre_tv_term_list_list(systems);

/* Stop the timer. */
    stop_stopwatch("search time");

    dnf_tree_free(consistent_input);

    return result;
}
Exemplo n.º 10
0
int
main(int argc, char **argv)
{

  uint      prob;		/* Used for selecting the problem: 2d or 3d? */
  uint      L;			/* Number of grid refinements */
  uint      clf;		/* Leafsize */
  uint      clustermode;	/* Used for selecting the cluster strategy */
  uint      decomp;		/* Used for selecting the type of the decomposition */
  uint      i, j;		/* Auxiliary variable for loops */
  ptri2d   *gr_2d;		/* 2d mesh hierarchy */
  ptri2dp1  p1_2d;		/* Linear p1 basis functions in 2d */
  ptet3d   *gr_3d;		/* 3d mesh hierarchy */
  ptet3dp1  p1_3d;		/* Linear p1 basis functions in 3d */
  psparsematrix sp;		/* Sparsematrix object */
  uint      ndof;		/* Number of degrees of freedom */
  uint     *idx;		/* Array of indices for the clustergeometry */
  pclustergeometry cg;		/* Clustergeometry object */
  uint      dim;		/* Dimension for domain decomposition clustering */
  uint     *flag;		/* Auxiliary array for domain decompostion clustering */
  pcluster  root;		/* Cluster tree object */
  pblock    broot;		/* Block cluster tree object */
  real      eta;		/* Admissibility parameter */
  phmatrix  hm;			/* Hierarchical matrices */
  real      tol_decomp;		/* Tolerance for decompositions */
  real      tol_coarsen;	/* Tolerance for coarsening of the hierarchical matrix */
  phmatrix  l;			/* Hierarchical matrices for storing the Cholesky factor */
  ptruncmode tm;		/* truncmode for truncations within the arithmetic */
  real      error;		/* Auxiliary variable for testing */
  pstopwatch sw;		/* Stopwatch for time measuring */
  real      time;		/* Variable for time measuring */
  size_t    sz, sz_rk, sz_full;	/* Variables for memory footprint */

  /* First initialise the library */
  init_h2lib(&argc, &argv);

  /*Initialise variables */
  eta = 2.0;
  tol_coarsen = 1e-16;
  tol_decomp = 1e-12;
  tm = new_releucl_truncmode();
  sw = new_stopwatch();

  /* Set problem parameters */
  printf("Select problem\n");
  prob = askforint("1 = fem2d,\t 2 = fem3d\t \n", "h2lib_fem", 1);
  L = askforint("Refinement?\n", "h2lib_L", 4);
  clf = askforint("Leafsize?\n", "h2lib_clf", 32);
  clustermode =
    askforint("1 = adaptive, \t 2 = ddcluster", "h2lib_clusterstrategy", 2);
  decomp =
    askforint("1 = LU-decomposition,\t, 2 = cholesky-decomposition\n",
	      "h2lib_decomp", 1);
  tol_decomp = askforreal("tol_decomp=?\n", "h2lib_tol_decomp", 1e-13);

  /* Build geometry and discretisation for laplace equation */
  if (prob == 1) {
    printf("========================================\n"
	   "  Create and fill fem2d sparsematrix\n");
    /* Mesh hierarchy */
    gr_2d = (ptri2d *) allocmem((size_t) sizeof(ptri2d) * (L + 1));
    gr_2d[0] = new_unitsquare_tri2d();	/* Set domain */
    //gr_2d[0]=new_unitcircle_tri2d();
    //gr_2d[0] = new_lshape_tri2d();
    for (i = 0; i < L; i++) {	/* Mesh refinements */
      gr_2d[i + 1] = refine_tri2d(gr_2d[i], NULL);
    }
    check_tri2d(gr_2d[L]);	/* Check mesh for inconsistencies */
    p1_2d = new_tri2dp1(gr_2d[L]);	/* Build discretisation */
    sp = build_tri2dp1_sparsematrix(p1_2d);	/* Build corresponding sparsematrix */
    assemble_tri2dp1_laplace_sparsematrix(p1_2d, sp, 0);	/* Fill the sparsematrix */
    ndof = p1_2d->ndof;
    printf("ndof = %u\n", ndof);
    /* Initialise index array for the cluster geometry */
    idx = allocuint(ndof);
    for (i = 0; i < ndof; i++)
      idx[i] = i;
    /* Build clustergeometry for the problem */
    cg = build_tri2dp1_clustergeometry(p1_2d, idx);
    del_tri2dp1(p1_2d);
    for (i = 0; i <= L; i++) {
      j = L - i;
      del_tri2d(gr_2d[j]);
    }
    freemem(gr_2d);
    dim = 2;			/* Set dimenison for domain decomposition clustering */
  }
  else {
    assert(prob == 2);
    printf("========================================\n"
	   "  Create and fill fem3d sparsematrix\n");
    /* Mesh hierarchy */
    gr_3d = (ptet3d *) allocmem((size_t) sizeof(ptri2d) * (L + 1));
    gr_3d[0] = new_unitcube_tet3d();	/* Set domain */
    for (i = 0; i < L; i++) {
      gr_3d[i + 1] = refine_tet3d(gr_3d[i], NULL);
    }
    check_tet3d(gr_3d[L]);	/* Check mesh for inconsistencies */
    p1_3d = new_tet3dp1(gr_3d[L]);	/* build discretisation */
    sp = build_tet3dp1_sparsematrix(p1_3d);	/* Build corresponding sparsematrix */
    assemble_tet3dp1_laplace_sparsematrix(p1_3d, sp, 0);	/* Fill the sparsematrix */
    ndof = p1_3d->ndof;
    printf("ndof = %u\n", ndof);
    /* initialise index array for the clustergeometry */
    idx = allocuint(ndof);
    for (i = 0; i < ndof; i++)
      idx[i] = i;
    /* Build clustergeometry for the problem */
    cg = build_tet3dp1_clustergeometry(p1_3d, idx);
    del_tet3dp1(p1_3d);
    for (i = 0; i <= L; i++) {
      j = L - i;
      del_tet3d(gr_3d[j]);
    }
    freemem(gr_3d);
    dim = 3;
  }

  /* Build and fill the corresponding hierarchical matrix */
  printf("========================================\n"
	 "  Create and fill hierarchical matrix\n");
  if (clustermode == 1) {
    /* Build cluster tree based on adaptive clustering */
    root = build_cluster(cg, ndof, idx, clf, H2_ADAPTIVE);
    /* Build block cluster tree using the euclidian (maximum) admissibilty condition */
    broot = build_nonstrict_block(root, root, &eta, admissible_2_cluster);
    /*Build hierarchical matrix from block */
    hm = build_from_block_hmatrix(broot, 0);
    /* Fill hierarchical matrix with sparsematrix entries */
    copy_sparsematrix_hmatrix(sp, hm);
    /* Compute error */
    error = norm2diff_sparsematrix_hmatrix(hm, sp);
    printf("error = %g\n", error);
    del_block(broot);
  }
  else {			/* clustermode == 2 */
    /* Initialise auxiliary array for domain decomposition clustering */
    flag = allocuint(ndof);
    for (i = 0; i < ndof; i++)
      flag[i] = 0;
    /* build cluster tree based adaptive doamin decomposition clustering */
    root = build_adaptive_dd_cluster(cg, ndof, idx, clf, sp, dim, flag);
    freemem(flag);
    /* Build block cluster tree using the domain decompostion admissibilty condition */
    broot = build_nonstrict_block(root, root, &eta, admissible_dd_cluster);
    /* Build hierarchical matrix from block cluster tree */
    hm = build_from_block_hmatrix(broot, 0);
    /* Fill hierarchical matrix with sparsematrix entries */
    copy_sparsematrix_hmatrix(sp, hm);
    /* Compute error */
    error = norm2diff_sparsematrix_hmatrix(hm, sp);
    printf("error = %g\n", error);
    del_block(broot);
  }

  /* Draw hierarchical matrix with cairo */
#if 0
#ifdef USE_CAIRO
  cairo_t  *cr;
  printf("Draw hmatrix to \"hm_p1.pdf\"\n");
  cr = new_cairopdf("../hm_p1.pdf", 1024.0, 1024.0);
  draw_cairo_hmatrix(cr, hm, false, 0);
  cairo_destroy(cr);
#endif
#endif

  /* Compute size of the hierarchical matrix */
  sz = getsize_hmatrix(hm);
  sz_rk = getfarsize_hmatrix(hm);
  sz_full = getnearsize_hmatrix(hm);
  printf("size original matrix:\t \t %.2f MB \t %.2f KB \t %.2f KB/DoF\n",
	 sz / 1024.0 / 1024.0, sz / 1024.0, sz / 1024.0 / ndof);
  printf("size rk: \t %.2f MB\t size full: \t %.2f MB \n",
	 sz_rk / 1024.0 / 1024.0, sz_full / 1024.0 / 1024.0);
  printf("Coarsen hmatrix\n");

  /* Coarsening of the hierarchical matrix to safe storage */
  coarsen_hmatrix(hm, tm, tol_coarsen, true);

  /* Compute size of the hierarchical matrix after coarsening */
  sz = getsize_hmatrix(hm);
  sz_rk = getfarsize_hmatrix(hm);
  sz_full = getnearsize_hmatrix(hm);
  printf("size original matrix:\t \t %.2f MB \t %.2f KB \t %.2f KB/DoF\n",
	 sz / 1024.0 / 1024.0, sz / 1024.0, sz / 1024.0 / ndof);
  printf("size rk: \t %.2f MB\t size full: \t %.2f MB \n",
	 sz_rk / 1024.0 / 1024.0, sz_full / 1024.0 / 1024.0);
  /* Compute error after coarseing */
  error = norm2diff_sparsematrix_hmatrix(hm, sp);
  printf("error = %g\n", error);

  /* Draw the hierarchical matrix after coarsening */
#if 0
#ifdef USE_CAIRO
  cairo_t  *cr2;
  printf("Draw hmatrix to \"hm_p1_coarsend.pdf\"\n");
  cr2 = new_cairopdf("../hm_p1_coarsend.pdf", 1024.0, 1024.0);
  draw_cairo_hmatrix(cr2, hm, false, 0);
  cairo_destroy(cr2);
#endif
#endif

  /* Compute decomposition of the hierarchical matrix */
  if (decomp == 1) {
    printf("========================================\n"
	   "  Test lu-decomposition\n");
    /* Compute size of the hierarchical matrix */
    sz = getsize_hmatrix(hm);
    printf("size original matrix:\t \t %.2f MB \t %.2f KB \t %.2f KB/DoF\n",
	   sz / 1024.0 / 1024.0, sz / 1024.0, sz / 1024.0 / ndof);
    /* Compute lu-decomposition of the hierarchical matrix */
    start_stopwatch(sw);
    lrdecomp_hmatrix(hm, 0, tol_decomp);
    time = stop_stopwatch(sw);
    /* Compute size of the lu-decomposition */
    sz = getsize_hmatrix(hm);
    sz_rk = getfarsize_hmatrix(hm);
    sz_full = getnearsize_hmatrix(hm);
    printf
      ("size lu-decomposition (lu):\t %.2f MB \t %.2f KB \t %.2f KB/DoF\n",
       sz / 1024.0 / 1024.0, sz / 1024.0, sz / 1024.0 / ndof);
    printf("size rk: \t %.2f MB\t size full: \t %.2f MB \n",
	   sz_rk / 1024.0 / 1024.0, sz_full / 1024.0 / 1024.0);
    printf("time = %f s\n", time);
#if 0
#ifdef USE_CAIRO
    cairo_t  *cr;
    printf("Draw lu-decomposition to \"hm_p1_lu.pdf\"\n");
    cr = new_cairopdf("../hm_p1_lu_staging.pdf", 512.0, 512.0);
    draw_cairo_hmatrix(cr, hm, false, 100);
    cairo_destroy(cr);
#endif
#endif
    /* Compute error */
    error = norm2lu_sparsematrix(hm, sp);
    printf("||I-(lu)^-1 sp||_2 ");
    printf("error = %g\n", error);
  }
  else {			/*decomp == 2 */
    printf("========================================\n"
	   "  Test cholesky-decomposition\n");
    /* Compute size of the hierarchical matrix */
    sz = getsize_hmatrix(hm);
    printf("size original matrix:\t %.2f MB \t %.2f KB \t %.2f KB/DoF\n",
	   sz / 1024.0 / 1024.0, sz / 1024.0, sz / 1024.0 / ndof);
    /* Compute cholesky-decomposition */
    start_stopwatch(sw);
    choldecomp_hmatrix(hm, 0, tol_decomp);
    time = stop_stopwatch(sw);
    /* Compute size of the cholesky-factor */
    l = clone_lower_hmatrix(false, hm);
    sz = getsize_hmatrix(l);
    sz_rk = getfarsize_hmatrix(l);
    sz_full = getnearsize_hmatrix(l);
    printf
      ("size chol-decomposition (l):\t %.2f MB \t %.2f KB \t %.2f KB/DoF\n",
       sz / 1024.0 / 1024.0, sz / 1024.0, sz / 1024.0 / ndof);
    printf("size rk: \t %.2f MB\t size full: \t %.2f MB \n",
	   sz_rk / 1024.0 / 1024.0, sz_full / 1024.0 / 1024.0);
    printf("time = %f s\n", time);
#if 0
#ifdef USE_CAIRO
    cairo_t  *cr;
    printf("Draw chol-factor to \"hm_chol_staging.pdf\"\n");
    cr = new_cairopdf("../hm_chol_staging.pdf", 512.0, 512.0);
    draw_cairo_hmatrix(cr, l, false, 1000);
    cairo_destroy(cr);
#endif
#endif
    /* Compute error */
    error = norm2chol_sparsematrix(hm, sp);
    printf("||I-(ll*)^-1 sp||_2 ");
    printf("error = %g\n", error);

    del_hmatrix(l);
  }

  /* Cleaning up */
  del_truncmode(tm);
  del_stopwatch(sw);
  del_hmatrix(hm);

  del_cluster(root);
  del_clustergeometry(cg);
  del_sparsematrix(sp);
  freemem(idx);
  (void) printf("  %u matrices and\n"
		"  %u vectors still active\n",
		getactives_amatrix(), getactives_avector());
  uninit_h2lib();
  printf("The end\n");
  return 0;
}
Exemplo n.º 11
0
int
main(int argc, char **argv)
{
  ptet3d   *gr;
  ptet3dp1 *dc;
  ptet3dref *rf;
  psparsematrix A, Af;
  pavector  xd, b, x;
  uint      L;
  real      error;
  pstopwatch sw;
  real      runtime;
  uint      i;
  real      eps;
  uint      steps;
  uint      iter;

  init_h2lib(&argc, &argv);

  sw = new_stopwatch();

  L = 5;
  eps = 1e-12;
  steps = 2500;

  (void) printf("----------------------------------------\n"
		"Creating mesh hierarchy\n");
  gr = (ptet3d *) allocmem(sizeof(ptet3d) * (L + 1));
  rf = (ptet3dref *) allocmem(sizeof(ptet3dref) * L);

  gr[0] = new_unitcube_tet3d();
  (void)
    printf("  Level %2u: %u vertices, %u edges, %u faces, %u tetrahedra\n", 0,
	   gr[0]->vertices, gr[0]->edges, gr[0]->faces, gr[0]->tetrahedra);
  for (i = 0; i < L; i++) {
    gr[i + 1] = refine_tet3d(gr[i], rf + i);
    (void)
      printf("  Level %2u: %u vertices, %u edges, %u faces, %u tetrahedra\n",
	     i + 1, gr[i + 1]->vertices, gr[i + 1]->edges, gr[i + 1]->faces,
	     gr[i + 1]->tetrahedra);
  }

  (void) printf("Creating discretizations\n");
  dc = (ptet3dp1 *) allocmem(sizeof(ptet3dp1) * (L + 1));
  for (i = 0; i <= L; i++) {
    dc[i] = new_tet3dp1(gr[i]);
    (void) printf("  Level %2u: %u degrees of freedom, %u fixed\n",
		  i, dc[i]->ndof, dc[i]->nfix);
  }

  for (i = 2; i <= L; i++) {
    (void) printf("Testing level %u\n" "  Setting up matrix\n", i);
    start_stopwatch(sw);
    A = build_tet3dp1_sparsematrix(dc[i]);
    Af = build_tet3dp1_interaction_sparsematrix(dc[i]);
    assemble_tet3dp1_laplace_sparsematrix(dc[i], A, Af);
    runtime = stop_stopwatch(sw);
    (void) printf("  %.1f seconds\n"
		  "  %.1f MB (interaction %.1f MB)\n"
		  "  %.1f KB/DoF (interaction %.1f KB/DoF)\n"
		  "  %u non-zero entries (interaction %u)\n",
		  runtime,
		  getsize_sparsematrix(A) / 1048576.0,
		  getsize_sparsematrix(Af) / 1048576.0,
		  getsize_sparsematrix(A) / 1024.0 / dc[i]->ndof,
		  getsize_sparsematrix(Af) / 1024.0 / dc[i]->ndof,
		  A->nz, Af->nz);

    (void) printf("  Setting up Dirichlet data\n");
    xd = new_avector(dc[i]->nfix);
    assemble_tet3dp1_dirichlet_avector(dc[i], sin_solution, 0, xd);

    (void) printf("  Setting up right-hand side\n");
    b = new_avector(dc[i]->ndof);
    assemble_tet3dp1_functional_avector(dc[i], sin_rhs, 0, b);

    (void) printf("  Starting iteration\n");
    x = new_avector(dc[i]->ndof);
    random_real_avector(x);

    start_stopwatch(sw);
    iter = solve_cg_sparsematrix_avector(A, b, x, eps, steps);
    runtime = stop_stopwatch(sw);
    (void) printf("  %u CG iterations\n", iter);

    (void) printf("\n"
		  "  %.1f seconds\n"
		  "  %.1f seconds per step\n", runtime, runtime / iter);

    error = norml2_tet3dp1(dc[i], sin_solution, 0, x, xd);
    (void) printf("  rel. L^2 error %.4e     %s\n", error,
		  (IS_IN_RANGE(1.0e-3, error, 9.0e-2) ? "    okay" :
		   "NOT okay"));
    if (!IS_IN_RANGE(1.0e-3, error, 9.0e-2))
      problems++;



    del_avector(x);
    del_avector(b);
    del_avector(xd);
    del_sparsematrix(Af);
    del_sparsematrix(A);
  }

  (void) printf("----------------------------------------\n" "Cleaning up\n");
  for (i = 0; i <= L; i++)
    del_tet3dp1(dc[i]);
  freemem(dc);

  for (i = 0; i < L; i++)
    del_tet3dref(rf[i]);
  freemem(rf);

  for (i = 0; i <= L; i++)
    del_tet3d(gr[i]);
  freemem(gr);

  del_stopwatch(sw);

  uninit_h2lib();

  return problems;
}
Exemplo n.º 12
0
__interrupt void PORT2_ISR(void)
{
    // Clear flags
    u8 int_flag, int_enable;
    u8 buzzer = 0;
    u8 simpliciti_button_event = 0;
    static u8 simpliciti_button_repeat = 0;

    // Remember interrupt enable bits
    int_enable = BUTTONS_IE;

    if ((!button.flag.star_long) && (!button.flag.num_long))
    {
        // Clear button flags
        button.all_flags = 0;

        // Store valid button interrupt flag
        int_flag = BUTTONS_IFG & int_enable;

        // ---------------------------------------------------
        // While SimpliciTI stack is active, buttons behave differently:
        //  - Store button events in SimpliciTI packet data
        //  - Exit SimpliciTI when button DOWN was pressed
        if (is_rf())
        {
            // Erase previous button press after a number of resends (increase number if link
            // quality is low)
            // This will create a series of packets containing the same button press
            // Necessary because we have no acknowledge
            // Filtering (edge detection) will be done by receiver software
            if (simpliciti_button_repeat++ > 6)
            {
                simpliciti_data[0] &= ~0xF0;
                simpliciti_button_repeat = 0;
            }

            if ((int_flag & BUTTON_STAR_PIN) == BUTTON_STAR_PIN)
            {
                simpliciti_data[0] |= SIMPLICITI_BUTTON_STAR;
                simpliciti_button_event = 1;
            }
            else if ((int_flag & BUTTON_NUM_PIN) == BUTTON_NUM_PIN)
            {
                simpliciti_data[0] |= SIMPLICITI_BUTTON_NUM;
                simpliciti_button_event = 1;
            }
            else if ((int_flag & BUTTON_UP_PIN) == BUTTON_UP_PIN)
            {
                simpliciti_data[0] |= SIMPLICITI_BUTTON_UP;
                simpliciti_button_event = 1;
            }
            else if ((int_flag & BUTTON_DOWN_PIN) == BUTTON_DOWN_PIN)
            {
                simpliciti_flag |= SIMPLICITI_TRIGGER_STOP;
            }

            // Trigger packet sending inside SimpliciTI stack
            if (simpliciti_button_event)
                simpliciti_flag |= SIMPLICITI_TRIGGER_SEND_DATA;
        }
        else                    // Normal operation
        {
            // Debounce buttons
            if ((int_flag & ALL_BUTTONS) != 0)
            {
                // Disable PORT2 IRQ
                __disable_interrupt();
                BUTTONS_IE = 0x00;
                __enable_interrupt();

                // Debounce delay 1
                Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_IN));

                // Reset inactivity detection
                sTime.last_activity = sTime.system_time;
            }

            // ---------------------------------------------------
            // STAR button IRQ
            if (IRQ_TRIGGERED(int_flag, BUTTON_STAR_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_STAR_IS_PRESSED)
                {
                    button.flag.star = 1;
                    button.flag.star_not_long = 0;
                    // Generate button click
                    buzzer = 1;
                }
                else if ((BUTTONS_IES & BUTTON_STAR_PIN) == BUTTON_STAR_PIN)
                {
                    button.flag.star = 1;
                    button.flag.star_not_long = 0;
                    BUTTONS_IES &= ~BUTTON_STAR_PIN;
                }
            }
            // ---------------------------------------------------
            // NUM button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_NUM_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_NUM_IS_PRESSED)
                {
                    button.flag.num = 1;
                    button.flag.num_not_long = 0;
                    // Generate button click
                    buzzer = 1;
                }
                else if ((BUTTONS_IES & BUTTON_NUM_PIN) == BUTTON_NUM_PIN)
                {
                    button.flag.num = 1;
                    button.flag.num_not_long = 0;
                    BUTTONS_IES &= ~BUTTON_NUM_PIN;
                }
            }
            // ---------------------------------------------------
            // UP button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_UP_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_UP_IS_PRESSED)
                {
                    button.flag.up = 1;

                    // Generate button click
                    buzzer = 1;
                }
            }
            // ---------------------------------------------------
            // DOWN button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_DOWN_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_DOWN_IS_PRESSED)
                {
                    button.flag.down = 1;

                    // Generate button click
                    buzzer = 1;

                    // Faster reaction for stopwatch stop button press
                    if (is_stopwatch() && !sys.flag.lock_buttons)
                    {
                        stop_stopwatch();
                        button.flag.down = 0;
                    }
                }
            }
            // ---------------------------------------------------
            // B/L button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_BACKLIGHT_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_BACKLIGHT_IS_PRESSED)
                {
                    sButton.backlight_status = 1;
                    sButton.backlight_timeout = 0;
                    P2OUT |= BUTTON_BACKLIGHT_PIN;
                    P2DIR |= BUTTON_BACKLIGHT_PIN;
                }
            }
        }

        // Trying to lock/unlock buttons?
        if (button.flag.num && button.flag.down)
        {
            // No buzzer output
            buzzer = 0;
            button.all_flags = 0;
        }

        // Generate button click when button was activated
        if (buzzer)
        {
            // Any button event stops active alarm
            if (sAlarm.state == ALARM_ON)
            {
                stop_alarm();
                button.all_flags = 0;
            }
            else if (!sys.flag.up_down_repeat_enabled)
            {
                start_buzzer(1, CONV_MS_TO_TICKS(20), CONV_MS_TO_TICKS(150));
            }

            // Debounce delay 2
            Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT));
        }

        // ---------------------------------------------------
        // Acceleration sensor IRQ
        if (IRQ_TRIGGERED(int_flag, AS_INT_PIN))
        {
            // Get data from sensor
            request.flag.acceleration_measurement = 1;
        }

        // ---------------------------------------------------
        // Pressure sensor IRQ
        if (IRQ_TRIGGERED(int_flag, PS_INT_PIN))
        {
            // Get data from sensor
            request.flag.altitude_measurement = 1;
        }

        // ---------------------------------------------------
        // Safe long button event detection
        if (button.flag.star || button.flag.num)
        {
            // Additional debounce delay to enable safe high detection - 50ms
            Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_LEFT));

            // Check if this button event is short enough
            if (BUTTON_STAR_IS_PRESSED)
            {
                // Change interrupt edge to detect button release
                BUTTONS_IES |= BUTTON_STAR_PIN;
                button.flag.star = 0;
                // This flag is used to detect if the user released the button before the
                // time for a long button press (3s)
                button.flag.star_not_long = 1;
            }
            if (BUTTON_NUM_IS_PRESSED)
            {
                // Change interrupt edge to detect button release
                BUTTONS_IES |= BUTTON_NUM_PIN;
                button.flag.num = 0;
                // This flag is used to detect if the user released the button before the
                // time for a long button press (3s)
                button.flag.num_not_long = 1;
            }
        }

    }
    // Reenable PORT2 IRQ
    __disable_interrupt();
    BUTTONS_IFG = 0x00;
    BUTTONS_IE = int_enable;
    __enable_interrupt();

    // Exit from LPM3/LPM4 on RETI
    __bic_SR_register_on_exit(LPM4_bits);
}
Exemplo n.º 13
0
Arquivo: ports.c Projeto: epall/cage
__interrupt void PORT2_ISR(void)
{
	u8 int_flag, int_enable;
	u8 buzzer = 0;
	u8 simpliciti_button_event = 0;
	static u8 simpliciti_button_repeat = 0;

	// Clear button flags
	button.all_flags = 0;

	// Remember interrupt enable bits
	int_enable = BUTTONS_IE;

	// Store valid button interrupt flag
	int_flag = BUTTONS_IFG & int_enable;

	// ---------------------------------------------------
	// While SimpliciTI stack is active, buttons behave differently:
	//  - Store M1/M2/S1 button events in SimpliciTI packet data
	//  - Exit SimpliciTI when S2 was pressed 
  	if (is_rf())
  	{
  		// Erase previous button press after a number of resends (increase number if link quality is low)
  		// This will create a series of packets containing the same button press
  		// Necessary because we have no acknowledge
  		// Filtering (edge detection) will be done by receiver software
  		if (simpliciti_button_repeat++ > 6) 
  		{
  			simpliciti_data[0] &= ~0xF0;
  			simpliciti_button_repeat = 0;
  		}
  		
  		if ((int_flag & BUTTON_M1_PIN) == BUTTON_M1_PIN)			
  		{
  			simpliciti_data[0] |= SIMPLICITI_BUTTON_M1;
  			simpliciti_button_event = 1;
  		}
  		else if ((int_flag & BUTTON_M2_PIN) == BUTTON_M2_PIN)	
  		{
  			simpliciti_data[0] |= SIMPLICITI_BUTTON_M2;
  			simpliciti_button_event = 1;
  		}
		else if ((int_flag & BUTTON_S1_PIN) == BUTTON_S1_PIN)	
		{
			simpliciti_data[0] |= SIMPLICITI_BUTTON_S1;
			simpliciti_button_event = 1;
		}
		else if ((int_flag & BUTTON_S2_PIN) == BUTTON_S2_PIN)	
		{
			simpliciti_flag |= SIMPLICITI_TRIGGER_STOP;
		}
		
		// Trigger packet sending inside SimpliciTI stack
		if (simpliciti_button_event) simpliciti_flag |= SIMPLICITI_TRIGGER_SEND_DATA;
  	}
  	else // Normal operation
  	{
		// Debounce buttons
		if ((int_flag & ALL_BUTTONS) != 0)
		{ 
			// Disable PORT2 IRQ
			__disable_interrupt();
			BUTTONS_IE = 0x00; 
			__enable_interrupt();
	
			// Debounce delay 1
			Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_IN));
	
			// Reset inactivity detection
			sTime.last_activity = sTime.system_time;
			
			// Reset M button high detection
			sTime.previous_m_button_event = sTime.system_time;
		}

		// ---------------------------------------------------
		// M1 button IRQ
		if (IRQ_TRIGGERED(int_flag, BUTTON_M1_PIN))
		{
			// Filter bouncing noise 
			if (BUTTON_M1_IS_PRESSED)
			{
				button.flag.m1 = 1;
				
				sys.flag.mask_m1_button = 0;
		
				// Generate button click
				buzzer = 1;
			}
		}
		// ---------------------------------------------------
		// M2 button IRQ
		else if (IRQ_TRIGGERED(int_flag, BUTTON_M2_PIN))
		{
			// Filter bouncing noise 
			if (BUTTON_M2_IS_PRESSED)
			{
				button.flag.m2 = 1;
				
				sys.flag.mask_m2_button = 0;
	
				// Generate button click
				buzzer = 1;
			}
		}
		// ---------------------------------------------------
		// S1 button IRQ
		else if (IRQ_TRIGGERED(int_flag, BUTTON_S1_PIN))
		{
			// Filter bouncing noise 
			if (BUTTON_S1_IS_PRESSED)
			{
				button.flag.s1 = 1;
		
				// Generate button click
				buzzer = 1;
			}
		}
		// ---------------------------------------------------
		// S2 button IRQ
		else if (IRQ_TRIGGERED(int_flag, BUTTON_S2_PIN))
		{
			// Filter bouncing noise 
			if (BUTTON_S2_IS_PRESSED)
			{
				button.flag.s2 = 1;
	
				// Generate button click
				buzzer = 1;
				
				// Faster reaction for stopwatch stop button press
				if (is_stopwatch()) 
				{
					stop_stopwatch();
					button.flag.s2 = 0;
				}
					
			}
		}
		// ---------------------------------------------------
		// B/L button IRQ
		else if (IRQ_TRIGGERED(int_flag, BUTTON_BL_PIN))
		{
			// Filter bouncing noise 
			if (BUTTON_BL_IS_PRESSED)
			{
				button.flag.bl = 1;
			}
		}	
	}

	// Generate button click when button was activated
	if (buzzer)
	{
		// Any button event stops active alarm
		if (sAlarm.state == ALARM_ON) 
		{
			stop_alarm();
			button.all_flags = 0;
		}
		else if (!sys.flag.s_button_repeat_enabled)
		{
			start_buzzer(1, CONV_MS_TO_TICKS(20), CONV_MS_TO_TICKS(150));
		}
		
		// Debounce delay 2
		Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_OUT));
	}
	
	// ---------------------------------------------------
	// Acceleration sensor IRQ
	if (IRQ_TRIGGERED(int_flag, AS_INT_PIN))
	{
		// Get data from sensor
		request.flag.acceleration_measurement = 1;
  	}
  	
  	// ---------------------------------------------------
	// Pressure sensor IRQ
	if (IRQ_TRIGGERED(int_flag, PS_INT_PIN)) 
	{
		// Get data from sensor
		request.flag.altitude_measurement = 1;
  	}
  	
  	// ---------------------------------------------------
  	// Enable safe long button event detection
  	if(button.flag.m1 || button.flag.m2) 
	{
		// Additional debounce delay to enable safe high detection
		Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_M));
	
		// Check if this button event is short enough
		if (BUTTON_M1_IS_PRESSED) button.flag.m1 = 0;
		if (BUTTON_M2_IS_PRESSED) button.flag.m2 = 0;	
	}
	
	// Reenable PORT2 IRQ
	__disable_interrupt();
	BUTTONS_IFG = 0x00; 	
	BUTTONS_IE  = int_enable; 	
	__enable_interrupt();

	// Exit from LPM3/LPM4 on RETI
	__bic_SR_register_on_exit(LPM4_bits); 
}
static void start_pause_stopwatch_handler(ClickRecognizerRef recognizer, void *context) {
  if(started) {
      stop_stopwatch();
  } else {
      start_stopwatch();
  }}
__interrupt void PORT2_ISR(void)
{
    // Clear flags
    unsigned char int_flag, int_enable;
    unsigned char buzzer = 0;

    // Remember interrupt enable bits
    int_enable = BUTTONS_IE;

    if ((!button.flag.star_long) && (!button.flag.num_long))
    {
        // Clear button flags
        button.all_flags = 0;

        // Store valid button interrupt flag
        int_flag = BUTTONS_IFG & int_enable;

        {
            // Debounce buttons
            if ((int_flag & ALL_BUTTONS) != 0)
            {
                // Disable PORT2 IRQ
                __disable_interrupt();
                BUTTONS_IE = 0x00;
                __enable_interrupt();

                // Debounce delay 1
                Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_IN));
            }

            // ---------------------------------------------------
            // STAR button IRQ
            if (IRQ_TRIGGERED(int_flag, BUTTON_STAR_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_STAR_IS_PRESSED)
                {
                    button.flag.star = 1;
                    button.flag.star_not_long = 0;
                    // Generate button click
                    buzzer = 1;
                }
                else if ((BUTTONS_IES & BUTTON_STAR_PIN) == BUTTON_STAR_PIN)
                {
                    button.flag.star = 1;
                    button.flag.star_not_long = 0;
                    BUTTONS_IES &= ~BUTTON_STAR_PIN;
                }
            }
            // ---------------------------------------------------
            // NUM button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_NUM_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_NUM_IS_PRESSED)
                {
                    button.flag.num = 1;
                    button.flag.num_not_long = 0;
                    // Generate button click
                    buzzer = 1;
                }
                else if ((BUTTONS_IES & BUTTON_NUM_PIN) == BUTTON_NUM_PIN)
                {
                    button.flag.num = 1;
                    button.flag.num_not_long = 0;
                    BUTTONS_IES &= ~BUTTON_NUM_PIN;
                }
            }
            // ---------------------------------------------------
            // UP button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_UP_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_UP_IS_PRESSED)
                {
                    button.flag.up = 1;

                    // Generate button click
                    buzzer = 1;
                }
            }
            // ---------------------------------------------------
            // DOWN button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_DOWN_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_DOWN_IS_PRESSED)
                {
                    button.flag.down = 1;

                    // Generate button click
                    buzzer = 1;

                    // Faster reaction for stopwatch stop button press
                    if (is_stopwatch() && !sys.flag.lock_buttons)
                    {
                        stop_stopwatch();
                        button.flag.down = 0;
                    }
                }
            }
            // ---------------------------------------------------
            // B/L button IRQ
            else if (IRQ_TRIGGERED(int_flag, BUTTON_BACKLIGHT_PIN))
            {
                // Filter bouncing noise
                if (BUTTON_BACKLIGHT_IS_PRESSED)
                {
                    sButton.backlight_status = 1;
                    sButton.backlight_timeout = 0;
                    P2OUT |= BUTTON_BACKLIGHT_PIN;
                    P2DIR |= BUTTON_BACKLIGHT_PIN;
                }
            }
        }

        // Trying to lock/unlock buttons?
        if (button.flag.num && button.flag.down)
        {
            // No buzzer output
            buzzer = 0;
            button.all_flags = 0;
        }

        // ---------------------------------------------------
        // Acceleration sensor IRQ
        if (IRQ_TRIGGERED(int_flag, AS_INT_PIN))
        {
            // Get data from sensor
            request.flag.acceleration_measurement = 1;
        }

        // ---------------------------------------------------
        // Safe long button event detection
        if (button.flag.star || button.flag.num)
        {
            // Additional debounce delay to enable safe high detection - 50ms
            Timer0_A4_Delay(CONV_MS_TO_TICKS(BUTTONS_DEBOUNCE_TIME_LEFT));

            // Check if this button event is short enough
            if (BUTTON_STAR_IS_PRESSED)
            {
                // Change interrupt edge to detect button release
                BUTTONS_IES |= BUTTON_STAR_PIN;
                button.flag.star = 0;
                // This flag is used to detect if the user released the button before the
                // time for a long button press (3s)
                button.flag.star_not_long = 1;
            }
            if (BUTTON_NUM_IS_PRESSED)
            {
                // Change interrupt edge to detect button release
                BUTTONS_IES |= BUTTON_NUM_PIN;
                button.flag.num = 0;
                // This flag is used to detect if the user released the button before the
                // time for a long button press (3s)
                button.flag.num_not_long = 1;
            }
        }

    }
    // Reenable PORT2 IRQ
    __disable_interrupt();
    BUTTONS_IFG = 0x00;
    BUTTONS_IE = int_enable;
    __enable_interrupt();

    // Exit from LPM3/LPM4 on RETI
    __bic_SR_register_on_exit(LPM4_bits);
}
Exemplo n.º 16
0
int main (int argc, char **argv) {
  
  uint prob;		/* Used for selecting the problem: 2d or 3d? */
  uint L;		/* Number of grid refinements */
  uint clf;		/* Leafsize */
  uint clustermode;	/* Used for selecting the cluster strategy */ 
  uint decomp;		/* Used for selecting the type of the decomposition */
  uint i, j;		/* Auxiliary variables for loops */
  ptri2d *gr_2d;	/* 2d mesh hierarchy */
  ptri2drt0 rt0_2d;	/* Raviart_Thomas functions in 2d */	
  ptet3d *gr_3d;	/* 3d mesh hierarchy */
  ptet3drt0 rt0_3d;	/* Raviart-Thomas functions in 3d */
  psparsematrix sp_A, sp_B;	/* Sparsematrix object*/
  pavector k;		/* Vector for permeabilities */
  uint ndof;		/* Number of degree of freedom */
  uint *idx_B_rows, *idx_B_cols;	/* Array of indices for the clustergeometry */
  pclustergeometry cg_B_rows, cg_B_cols;/* Clustergeometry object */
  uint dim;		/* Dimension for domain decomposition clustering */
  pcluster root_B_cols, root_B_rows;	/* Cluster tree object */
  pblock broot_A, broot_B;		/* Block cluster tree object */
  real eta;		/* Admissibilty parameter*/
  phmatrix hm_A, hm_B;	/* Hierarchical matrices*/
  real tol_decomp;	/* Tolerance for decompositions*/
  real tol_coarsen;	/* Tolerance for coarsening of the hierarchical matrix */
  phmatrix l;		/* Hierarchical matrices for storing the cholesky factor*/
  ptruncmode tm;	/* Truncmode for truncations within the arithmetic */
  real error;		/* Auxiliary variable for testing*/
  pstopwatch sw;	/* Stopwatch for time measuring */
  real time;		/* Variable for time measurement */
  size_t sz, sz_rk, sz_full; /* Variables for memory footprint */
  uint elements;	/*Auxiliary variable: numberof elements*/
  
  /* First initialise the library */
  init_h2lib(&argc, &argv);	
  
  /*Initialise variables*/  
  eta = 2.0;
  tol_coarsen = 1e-16;
  tm = new_releucl_truncmode();
  sw = new_stopwatch();
  
  /* Set problme parameters */
  printf("Select problem\n");
  prob = askforint("1 = fem2d,\t 2 = fem3d\t \n","h2lib_fem", 1);
  L = askforint("Refinement?\n", "h2lib_L", 4);
  clf = askforint("Leafsize?\n", "h2lib_clf", 32);
  clustermode = askforint("1 = adaptive, \t 2 = adaptive from cluster", "h2lib_clusterstrategy", 2);
  decomp = askforint("1 = LU-decomposition of hm_A,\t, 2 = cholesky-decomposition of hm_A\n","h2lib_decomp",1);
  tol_decomp = askforreal("tol_decomp=?\n", "h2lib_tol_decomp", 1e-13);
  
  /* Build geomtery and discretisation for Darcy's equation */
  if(prob==1){
    printf("========================================\n"
	   "  Create and fill fem2d sparsematrix\n");
    /* Mesh hierarchy */
    gr_2d = (ptri2d *) allocmem((size_t) sizeof(ptri2d) * (L+1)); 
    gr_2d[0] = new_unitsquare_tri2d(); /* Set domain */
    //gr_2d[0]=new_unitcircle_tri2d();
    //gr_2d[0] = new_lshape_tri2d();
    for(i=0;i<L;i++){ /* Mesh refinements */
     gr_2d[i+1] = refine_tri2d(gr_2d[i], NULL); 
     fixnormals_tri2d(gr_2d[i]);
    }
    fixnormals_tri2d(gr_2d[i]);
    check_tri2d(gr_2d[L]); /*Check mesh for inconsistencies */
    rt0_2d = new_tri2drt0(gr_2d[L]); /*Build discretisation */
    set_boundary_unitsquare_tri2drt0(rt0_2d);  
    update_tri2drt0(rt0_2d);
    sp_A = build_tri2drt0_A_sparsematrix(rt0_2d); /*Build corresponding sparsematrices */
    sp_B = build_tri2drt0_B_sparsematrix(rt0_2d);
    k = new_avector(gr_2d[L]->triangles); /*Build and fill vector for the permeabilities */
    function_permeability_2d(gr_2d[L], k);
    assemble_tri2drt0_darcy_A_sparsematrix(rt0_2d, sp_A, 0, k); /*Fill the sparsematrices */
    assemble_tri2drt0_darcy_B_sparsematrix(rt0_2d, sp_B, 0);
    ndof = rt0_2d->ndof;printf("ndof = %u\n", ndof);
    /*Initialise index arrays for the cluster geometries */
    idx_B_rows = allocuint(rt0_2d->t2->triangles); 
    for(i=0;i<rt0_2d->t2->triangles;i++)
      idx_B_rows[i]  = i;
    idx_B_cols = allocuint(rt0_2d->ndof);
    for(i=0;i<rt0_2d->ndof;i++)
      idx_B_cols[i] = i;
    /* Build clustergeomtries for the problem */
    cg_B_rows = build_tri2drt0_B_clustergeometry(rt0_2d, idx_B_rows);
    cg_B_cols = build_tri2drt0_A_clustergeometry(rt0_2d, idx_B_cols);
    elements = gr_2d[L]->triangles;
    del_tri2drt0(rt0_2d);
    for(i=0;i<=L;i++){
      j =  L-i;
      del_tri2d(gr_2d[j]);
    }
    freemem(gr_2d);
    del_avector(k);
    dim = 2; /* Set dimenison for domain decomposition clustering */
  }
  else { assert(prob==2); 
    printf("========================================\n"
	   "  Create and fill fem3d sparsematrix\n");
    /* Mesh hierarchy */
    gr_3d = (ptet3d *) allocmem((size_t) sizeof(ptet3d) * (L+1));
    gr_3d[0] = new_unitcube_tet3d(); /* Set domain */
    for(i=0;i<L;i++){
      gr_3d[i+1] = refine_tet3d(gr_3d[i],NULL); 
      fixnormals_tet3d(gr_3d[i]);
    }
    fixnormals_tet3d(gr_3d[i]);
    check_tet3d(gr_3d[L]); /*Check mesh for inconsistencies */
    rt0_3d = new_tet3drt0(gr_3d[L]); /*build discretisation */
    set_boundary_unitcube_tet3drt0(rt0_3d);  
    update_tet3drt0(rt0_3d);
    sp_A = build_tet3drt0_A_sparsematrix(rt0_3d); /*Build corresponding sparsematrices*/
    sp_B = build_tet3drt0_B_sparsematrix(rt0_3d);
    k = new_avector(gr_3d[L]->tetrahedra); /* Build and fill vector for the permeabilities */
    function_permeability_3d(gr_3d[L], k);
    assemble_tet3drt0_darcy_A_sparsematrix(rt0_3d, sp_A, 0, k); /*Fill the sparsematrices*/
    assemble_tet3drt0_darcy_B_sparsematrix(rt0_3d, sp_B, 0);
    ndof = rt0_3d->ndof;printf("ndof = %u\n", ndof);
    /*Initialise index arrays for the cluster geometries */
    idx_B_rows = allocuint(rt0_3d->t3->tetrahedra); 
    for(i=0;i<rt0_3d->t3->tetrahedra;i++)
      idx_B_rows[i]  = i;
    idx_B_cols = allocuint(rt0_3d->ndof);
    for(i=0;i<rt0_3d->ndof;i++)
      idx_B_cols[i] = i;
    /* Build clustergeomtries for the problem */
    cg_B_rows = build_tet3drt0_B_clustergeometry(rt0_3d, idx_B_rows);
    cg_B_cols = build_tet3drt0_A_clustergeometry(rt0_3d, idx_B_cols);
    elements = gr_3d[L]->tetrahedra;
    del_tet3drt0(rt0_3d);
    for(i=0;i<=L;i++){
      j = L -i;
      del_tet3d(gr_3d[j]);
    }
    freemem(gr_3d);
    del_avector(k);
    dim = 3;
  }
  
  /* Build and fill the corresponding hierarchical matrices*/
  printf("========================================\n"
	 "  Create and fill hierarchical matrix\n");
  if(clustermode ==1){
    /* Build cluster trees based on adaptive clustering*/
    root_B_rows = build_cluster(cg_B_rows, elements, idx_B_rows, clf, H2_ADAPTIVE); 
    root_B_cols = build_cluster(cg_B_cols, ndof,     idx_B_cols, clf, H2_ADAPTIVE);
    /*Build block cluster trees using the euclidian (maximum) admissibilty condition*/
    broot_B = build_nonstrict_block(root_B_rows, root_B_cols, &eta, admissible_2_cluster);
    broot_A = build_nonstrict_block(root_B_cols, root_B_cols, &eta, admissible_2_cluster);
    /*Build hierarchical matrices from block*/
    hm_A = build_from_block_hmatrix(broot_A, 0);
    hm_B = build_from_block_hmatrix(broot_B, 0);
    /*Fill hierarchical matrices with sparsematrix entries*/
    copy_sparsematrix_hmatrix(sp_A, hm_A);
    copy_sparsematrix_hmatrix(sp_B, hm_B);
    /* Compute error */
    printf("sp_A: rows %u cols: %u\n", sp_A->rows, sp_A->cols);
    printf("sp_B: rows %u cols: %u\n", sp_B->rows, sp_B->cols);
    printf("hm_A: rows %u cols: %u\n", hm_A->rc->size, hm_A->cc->size);
    printf("hm_B: rows %u cols: %u\n", hm_B->rc->size, hm_B->cc->size);
    error = norm2diff_sparsematrix_hmatrix(hm_A, sp_A);
    printf("error A = %g\n", error);
    error = norm2diff_sparsematrix_hmatrix(hm_B, sp_B);
    printf("error B = %g\n", error);
    del_block(broot_A);
    del_block(broot_B);
  }
  else{ /*clustermode == 2*/
    /* Build cluster tree based on adaptive clustering */
    root_B_rows = build_cluster(cg_B_rows, elements, idx_B_rows, clf, H2_ADAPTIVE); 
    /* Build cluster tree based adaptive doamin decomposition clustering */
    root_B_cols = build_adaptive_fromcluster_cluster(root_B_rows, cg_B_cols, ndof, idx_B_cols, clf, dim);
   // freemem(flag);
    /* Build block cluster trees using the domain decompostion admissibilty (rt0) condition*/
    broot_B = build_nonstrict_block(root_B_rows, root_B_cols, &eta, admissible_2_cluster);
    //broot_B = build_nonstrict_block(root_B_rows, root_B_cols, &eta, admissible_dd_rt0_cluster);
    broot_A = build_nonstrict_block(root_B_cols, root_B_cols, &eta, admissible_dd_cluster);
    /* Build hierarchical matrices from block cluster tree*/
    hm_A = build_from_block_hmatrix(broot_A, 0);
    hm_B = build_from_block_hmatrix(broot_B, 0);
    /* Fill hierarchical matrices with sparsematrix entries*/
    copy_sparsematrix_hmatrix(sp_A, hm_A);
    copy_sparsematrix_hmatrix(sp_B, hm_B);
    /* Compute error */
    printf("sp_A: rows %u cols: %u\n", sp_A->rows, sp_A->cols);
    printf("sp_B: rows %u cols: %u\n", sp_B->rows, sp_B->cols);
    printf("hm_A: rows %u cols: %u\n", hm_A->rc->size, hm_A->cc->size);
    printf("hm_B: rows %u cols: %u\n", hm_B->rc->size, hm_B->cc->size);
    error = norm2diff_sparsematrix_hmatrix(hm_A, sp_A);
    printf("error A = %g\n", error);
    error = norm2diff_sparsematrix_hmatrix(hm_B, sp_B);
    printf("error B = %g\n", error);
    del_block(broot_A);
    del_block(broot_B);
  }
    
    /* Draw hierarchical matrix with cairo */
#if 0
    #ifdef USE_CAIRO
    cairo_t *cr;
    printf("Draw hmatrix to \"hm_p1.pdf\"\n");
    cr = new_cairopdf("../hm_p1.pdf", 1024.0, 1024.0);
    draw_cairo_hmatrix(cr, hm, false, 0);
    cairo_destroy(cr);
    #endif
#endif

  /*Compute size of the hierarchical matrix A*/
  sz = getsize_hmatrix(hm_A);
  sz_rk = getfarsize_hmatrix(hm_A);
  sz_full = getnearsize_hmatrix(hm_A);
  printf("matrix A:\t \t %.2f MB \t %.2f KB \t %.2f KB/DoF\n",
	 sz/1024.0/1024.0, sz/1024.0, sz/1024.0/ndof);
  printf("size rk: \t %.2f MB\t size full: \t %.2f MB \n", sz_rk/1024.0/1024.0, sz_full
            /1024.0/1024.0);
  printf("Coarsen hmatrix\n");
  
  /*Coarsening of the hierarchical matrix A to safe storage */
  coarsen_hmatrix(hm_A, tm, tol_coarsen, true);
  
  /* Compute size of the hierarchical matrix A after coarsening*/
  sz = getsize_hmatrix(hm_A);
  sz_rk = getfarsize_hmatrix(hm_A);
  sz_full = getnearsize_hmatrix(hm_A);
  printf("matrix A:\t \t %.2f MB \t %.2f KB \t %.2f KB/DoF\n",
	   sz/1024.0/1024.0, sz/1024.0, sz/1024.0/ndof);
  printf("size rk: \t %.2f MB\t size full: \t %.2f MB \n", sz_rk/1024.0/1024.0, sz_full
            /1024.0/1024.0);
  /* Compute error after coarseing */  
  error = norm2diff_sparsematrix_hmatrix(hm_A, sp_A);
  printf("error = %g\n", error);
  
  /*Compute size of the hierarchical matrix B */
  sz = getsize_hmatrix(hm_B);
  sz_rk = getfarsize_hmatrix(hm_B);
  sz_full = getnearsize_hmatrix(hm_B);
  printf("matrix B:\t \t %.2f MB \t %.2f KB \t %.2f KB/DoF\n",
	 sz/1024.0/1024.0, sz/1024.0, sz/1024.0/ndof);
  printf("size rk: \t %.2f MB\t size full: \t %.2f MB \n", sz_rk/1024.0/1024.0, sz_full
            /1024.0/1024.0);
  printf("Coarsen hmatrix\n");
  
  /*Coarsening of the hierarchical matrix B to safe storage */
  coarsen_hmatrix(hm_B, tm, tol_coarsen, true);
  
  /* Compute size of the hierarchical matrix B after coarsening*/
  sz = getsize_hmatrix(hm_B);
  sz_rk = getfarsize_hmatrix(hm_B);
  sz_full = getnearsize_hmatrix(hm_B);
  printf("matrix B:\t \t %.2f MB \t %.2f KB \t %.2f KB/DoF\n",
	   sz/1024.0/1024.0, sz/1024.0, sz/1024.0/ndof);
  printf("size rk: \t %.2f MB\t size full: \t %.2f MB \n", sz_rk/1024.0/1024.0, sz_full
            /1024.0/1024.0);
  /* Compute error after coarseing */  
  error = norm2diff_sparsematrix_hmatrix(hm_B, sp_B);
  printf("error = %g\n", error);
  
  /* Compute decomposition of the hierarchical matrix A */
  if(decomp == 1){
    printf("========================================\n"
	 "  Test lu-decomposition (A)\n");
    /*Compute size of the hierarchical matrix*/
    sz = getsize_hmatrix(hm_A);
    printf("size original matrix:\t \t %.2f MB \t %.2f KB \t %.2f KB/DoF\n",
	   sz/1024.0/1024.0, sz/1024.0, sz/1024.0/ndof);
    /*Compute lu-decomposition of the hierarchical matrix*/
    start_stopwatch(sw);
    lrdecomp_hmatrix(hm_A, 0, tol_decomp); 
    time = stop_stopwatch(sw);
    /*Compute size of the lu-decomposition*/
    sz = getsize_hmatrix(hm_A);
    sz_rk = getfarsize_hmatrix(hm_A);
    sz_full = getnearsize_hmatrix(hm_A);
    printf("size lu-decomposition (lu):\t %.2f MB \t %.2f KB \t %.2f KB/DoF\n", 
	   sz/1024.0/1024.0, sz/1024.0, sz/1024.0/ndof);
    printf("size rk: \t %.2f MB\t size full: \t %.2f MB \n", sz_rk/1024.0/1024.0, sz_full
            /1024.0/1024.0);
    printf("time = %f s\n", time);

    /*Compute error*/
    error = norm2lu_sparsematrix(hm_A, sp_A);
    printf("||I-(lu)^-1 sp||_2 ");
    printf("error = %g\n", error);
  }
  else{ /*decomp == 2*/
    printf("========================================\n"
	 "  Test cholesky-decomposition (A)\n");
    /*Compute size of the hierarchical matrix*/
    sz = getsize_hmatrix(hm_A);
    printf("size original matrix:\t %.2f MB \t %.2f KB \t %.2f KB/DoF\n",
	   sz/1024.0/1024.0, sz/1024.0, sz/1024.0/ndof);
    /* Compute cholesky-decomposition*/
    start_stopwatch(sw);
    choldecomp_hmatrix(hm_A, 0, tol_decomp);
    time = stop_stopwatch(sw);
    /* Compute size of the cholesky-factor*/
    l = clone_lower_hmatrix(false, hm_A);
    sz = getsize_hmatrix(l);
    sz_rk = getfarsize_hmatrix(l);
    sz_full = getnearsize_hmatrix(l);
    printf("size chol-decomposition (l):\t %.2f MB \t %.2f KB \t %.2f KB/DoF\n", 
	   sz/1024.0/1024.0, sz/1024.0, sz/1024.0/ndof);
    printf("size rk: \t %.2f MB\t size full: \t %.2f MB \n", sz_rk/1024.0/1024.0, sz_full
            /1024.0/1024.0);
    printf("time = %f s\n", time);

    /* Compute error */
    error = norm2chol_sparsematrix(hm_A, sp_A);
    printf("||I-(ll*)^-1 sp||_2 ");
    printf("error = %g\n", error);

    del_hmatrix(l);
  }
  
  /*Cleaning up*/
  del_truncmode(tm);
  del_stopwatch(sw);
  del_hmatrix(hm_A); del_hmatrix(hm_B);
  
  
  del_cluster(root_B_cols); del_cluster(root_B_rows);
  del_clustergeometry(cg_B_rows); del_clustergeometry(cg_B_cols);
  del_sparsematrix(sp_A); del_sparsematrix(sp_B);
  freemem(idx_B_rows); freemem(idx_B_cols);
  (void) printf("  %u matrices and\n"
    "  %u vectors still active\n",
    getactives_amatrix(),
    getactives_avector());
  uninit_h2lib();
  printf("The end\n");
  return 0;
}