Example #1
0
// Actual evaluation of surface linear form (calculates integral)
scalar FeProblem::eval_form(WeakForm::VectorFormSurf *vfs, Tuple<Solution *> u_ext, PrecalcShapeset *fv, RefMap *rv, EdgePos* ep)
{
  // eval the form
  Quad2D* quad = fv->get_quad_2d();
  int eo = quad->get_edge_points(ep->edge);
  double3* pt = quad->get_points(eo);
  int np = quad->get_num_points(eo);

  // init geometry and jacobian*weights
  if (cache_e[eo] == NULL)
  {
    cache_e[eo] = init_geom_surf(rv, ep, eo);
    double3* tan = rv->get_tangent(ep->edge);
    cache_jwt[eo] = new double[np];
    for(int i = 0; i < np; i++)
      cache_jwt[eo][i] = pt[i][2] * tan[i][2];
  }
  Geom<double>* e = cache_e[eo];
  double* jwt = cache_jwt[eo];

  // function values and values of external functions
  AUTOLA_OR(Func<scalar>*, prev, wf->neq);
  for (int i = 0; i < wf->neq; i++) prev[i]  = init_fn(u_ext[i], rv, eo);
  Func<double>* v = get_fn(fv, rv, eo);
  ExtData<scalar>* ext = init_ext_fns(vfs->ext, rv, eo);

  scalar res = vfs->fn(np, jwt, prev, v, e, ext);

  for (int i = 0; i < wf->neq; i++) {  prev[i]->free_fn(); delete prev[i]; }
  ext->free(); delete ext;
  return 0.5 * res;
}
Example #2
0
// checks whether the body can source its heads
bool DefaultUnfoundedCheck::isValidSource(const BodyNodeP& n) {
    if (!n.node->extended()) {
        return bodies_[n.id].lower_or_ext == 0;
    }
    ExtData* ext = extended_[bodies_[n.id].lower_or_ext];
    if (ext->lower > 0) {
        // Since n is currently not a source,
        // we here know that no literal with a source can depend on this body.
        // Hence, we can safely add all those literals to WS.

        // We check all internal literals here because there may be atoms
        // that were sourced *after* we established the watch set.
        const uint32 inc = n.node->pred_inc();
        const NodeId* x  = n.node->preds();
        uint32       p   = 0;
        for (; *x != idMax; x += inc, ++p) {
            if (atoms_[*x].hasSource() && !ext->inWs(p) && !solver_->isFalse(graph_->getAtomNode(*x).lit)) {
                ext->addToWs(p, n.node->pred_weight(p, false));
            }
        }
        // We check all external literals here because we do not update
        // the body on backtracking. Therefore some external literals that were false
        // may now be true/free.
        for (++x; *x != idMax; x += inc, ++p) {
            if (!solver_->isFalse(Literal::fromRep(*x)) && !ext->inWs(p)) {
                ext->addToWs(p, n.node->pred_weight(p, true));
            }
        }
    }
    return ext->lower <= 0;
}
double KellyTypeAdapt::eval_boundary_estimator(KellyTypeAdapt::ErrorEstimatorForm* err_est_form, RefMap *rm, SurfPos* surf_pos)
{
  // determine the integration order
  int inc = (this->sln[err_est_form->i]->get_num_components() == 2) ? 1 : 0;
  Func<Ord>** oi = new Func<Ord>* [num];
  for (int i = 0; i < num; i++)
    oi[i] = init_fn_ord(this->sln[i]->get_edge_fn_order(surf_pos->surf_num) + inc);

  // Order of additional external functions.
  ExtData<Ord>* fake_ext = dp.init_ext_fns_ord(err_est_form->ext, surf_pos->surf_num);

  double fake_wt = 1.0;
  Geom<Ord>* fake_e = init_geom_ord();
  Ord o = err_est_form->ord(1, &fake_wt, oi, oi[err_est_form->i], fake_e, fake_ext);
  int order = rm->get_inv_ref_order();
  order += o.get_order();

  limit_order(order);

  // Clean up.
  for (int i = 0; i < this->num; i++)
    if (oi[i] != NULL) { oi[i]->free_ord(); delete oi[i]; }
  delete [] oi;
  delete fake_e;
  delete fake_ext;

  // eval the form
  Quad2D* quad = this->sln[err_est_form->i]->get_quad_2d();
  int eo = quad->get_edge_points(surf_pos->surf_num, order);
  double3* pt = quad->get_points(eo);
  int np = quad->get_num_points(eo);

  // init geometry and jacobian*weights
  Geom<double>* e = init_geom_surf(rm, surf_pos, eo);
  double3* tan = rm->get_tangent(surf_pos->surf_num, eo);
  double* jwt = new double[np];
  for(int i = 0; i < np; i++)
    jwt[i] = pt[i][2] * tan[i][2];

  // function values
  Func<scalar>** ui = new Func<scalar>* [num];
  for (int i = 0; i < num; i++)
    ui[i] = init_fn(this->sln[i], eo);
  ExtData<scalar>* ext = dp.init_ext_fns(err_est_form->ext, rm, eo);

  scalar res = boundary_scaling_const *
                err_est_form->value(np, jwt, ui, ui[err_est_form->i], e, ext);

  for (int i = 0; i < this->num; i++)
    if (ui[i] != NULL) { ui[i]->free_fn(); delete ui[i]; }
  delete [] ui;
  if (ext != NULL) { ext->free(); delete ext; }
  e->free(); delete e;
  delete [] jwt;

  return std::abs(0.5*res);   // Edges are parameterized from 0 to 1 while integration weights
                              // are defined in (-1, 1). Thus multiplying with 0.5 to correct
                              // the weights.
}
double KellyTypeAdapt::eval_volumetric_estimator(KellyTypeAdapt::ErrorEstimatorForm* err_est_form, RefMap *rm)
{
  // determine the integration order
  int inc = (this->sln[err_est_form->i]->get_num_components() == 2) ? 1 : 0;

  Func<Ord>** oi = new Func<Ord>* [num];
  for (int i = 0; i < num; i++)
    oi[i] = init_fn_ord(this->sln[i]->get_fn_order() + inc);

  // Order of additional external functions.
  ExtData<Ord>* fake_ext = dp.init_ext_fns_ord(err_est_form->ext);

  double fake_wt = 1.0;
  Geom<Ord>* fake_e = init_geom_ord();
  Ord o = err_est_form->ord(1, &fake_wt, oi, oi[err_est_form->i], fake_e, fake_ext);
  int order = rm->get_inv_ref_order();
  order += o.get_order();

  limit_order(order);

  // Clean up.
  for (int i = 0; i < this->num; i++)
    if (oi[i] != NULL) { oi[i]->free_ord(); delete oi[i]; }
  delete [] oi;
  delete fake_e;
  delete fake_ext;

  // eval the form
  Quad2D* quad = this->sln[err_est_form->i]->get_quad_2d();
  double3* pt = quad->get_points(order);
  int np = quad->get_num_points(order);

  // init geometry and jacobian*weights
  Geom<double>* e = init_geom_vol(rm, order);
  double* jac = rm->get_jacobian(order);
  double* jwt = new double[np];
  for(int i = 0; i < np; i++)
    jwt[i] = pt[i][2] * jac[i];

  // function values
  Func<scalar>** ui = new Func<scalar>* [num];
  
  for (int i = 0; i < num; i++)
    ui[i] = init_fn(this->sln[i], order);
  
  ExtData<scalar>* ext = dp.init_ext_fns(err_est_form->ext, rm, order);

  scalar res = volumetric_scaling_const *
                err_est_form->value(np, jwt, ui, ui[err_est_form->i], e, ext);

  for (int i = 0; i < this->num; i++)
    if (ui[i] != NULL) { ui[i]->free_fn(); delete ui[i]; }
  delete [] ui;
  if (ext != NULL) { ext->free(); delete ext; }
  e->free(); delete e;
  delete [] jwt;

  return std::abs(res);
}
Example #5
0
// an atom in extended body n has lost its source, check if n is no longer a valid source
void DefaultUnfoundedCheck::RemoveSource::operator()(const BodyNodeP& n, NodeId atomId, uint32 idx) const {
    assert(n.node->extended() && n.node->get_pred(idx) == atomId);
    (void)atomId;
    ExtData* ext = self->extended_[self->bodies_[n.id].lower_or_ext];
    ext->removeFromWs(idx, n.node->pred_weight(idx, false));
    if (ext->lower > 0 && self->bodies_[n.id].watches > 0) {
        // extended bodies don't always become false if a predecessor becomes false
        // eagerly enqueue all successors watching this body
        self->forwardUnsource(n, true);
    }
}
Example #6
0
// Actual evaluation of volume matrix form (calculates integral)
scalar FeProblem::eval_form(WeakForm::MatrixFormVol *mfv, Tuple<Solution *> u_ext, PrecalcShapeset *fu, PrecalcShapeset *fv, RefMap *ru, RefMap *rv)
{
  // determine the integration order
  int inc = (fu->get_num_components() == 2) ? 1 : 0;
  AUTOLA_OR(Func<Ord>*, oi, wf->neq);
  for (int i = 0; i < wf->neq; i++) oi[i] = init_fn_ord(u_ext[i]->get_fn_order() + inc);
  Func<Ord>* ou = init_fn_ord(fu->get_fn_order() + inc);
  Func<Ord>* ov = init_fn_ord(fv->get_fn_order() + inc);
  ExtData<Ord>* fake_ext = init_ext_fns_ord(mfv->ext);

  double fake_wt = 1.0;
  Geom<Ord>* fake_e = init_geom_ord();
  Ord o = mfv->ord(1, &fake_wt, oi, ou, ov, fake_e, fake_ext);
  int order = ru->get_inv_ref_order();
  order += o.get_order();
  limit_order_nowarn(order);

  for (int i = 0; i < wf->neq; i++) {  oi[i]->free_ord(); delete oi[i]; }
  ou->free_ord(); delete ou;
  ov->free_ord(); delete ov;
  delete fake_e;
  fake_ext->free_ord(); delete fake_ext;

  // eval the form
  Quad2D* quad = fu->get_quad_2d();
  double3* pt = quad->get_points(order);
  int np = quad->get_num_points(order);

  // init geometry and jacobian*weights
  if (cache_e[order] == NULL)
  {
    cache_e[order] = init_geom_vol(ru, order);
    double* jac = ru->get_jacobian(order);
    cache_jwt[order] = new double[np];
    for(int i = 0; i < np; i++)
      cache_jwt[order][i] = pt[i][2] * jac[i];
  }
  Geom<double>* e = cache_e[order];
  double* jwt = cache_jwt[order];

  // function values and values of external functions
  AUTOLA_OR(Func<scalar>*, prev, wf->neq);
  for (int i = 0; i < wf->neq; i++) prev[i]  = init_fn(u_ext[i], rv, order);
  Func<double>* u = get_fn(fu, ru, order);
  Func<double>* v = get_fn(fv, rv, order);
  ExtData<scalar>* ext = init_ext_fns(mfv->ext, rv, order);

  scalar res = mfv->fn(np, jwt, prev, u, v, e, ext);

  for (int i = 0; i < wf->neq; i++) {  prev[i]->free_fn(); delete prev[i]; }
  ext->free(); delete ext;
  return res;
}
Example #7
0
// an atom in extended body n has a new source, check if n is now a valid source
void DefaultUnfoundedCheck::AddSource::operator()(const BodyNodeP& n, NodeId atomId, uint32 idx) const {
    assert(n.node->extended() && n.node->get_pred(idx) == atomId);
    (void)atomId;
    ExtData* ext = self->extended_[self->bodies_[n.id].lower_or_ext];
    if (ext->lower > 0 || self->bodies_[n.id].watches == 0) {
        // currently not a source - safely add pred to our watch set
        ext->addToWs(idx, n.node->pred_weight(idx, false));
    }
    if (!self->solver_->isFalse(n.node->lit) && ext->lower <= 0) {
        // valid source - propagate to heads
        self->forwardSource(n);
    }
}
Example #8
0
// check if n is part of the reason for the current unfounded set
void DefaultUnfoundedCheck::addIfReason(const BodyNodeP& n, uint32 uScc) {
    if (solver_->isFalse(n.node->lit)) {
        if (n.node->scc != uScc) {
            addReasonLit(n.node->lit);
        }
        else if (!solver_->seen(n.node->lit)) {
            if (!n.node->extended()) {
                // body is only a reason if it does not depend on the atoms from the unfounded set
                for (const NodeId* x = n.node->preds(); *x != idMax; ++x) {
                    if (atoms_[*x].ufs && !solver_->isFalse(graph_->getAtomNode(*x).lit)) {
                        return;
                    }
                }
                addReasonLit(n.node->lit);
            }
            else if (bodies_[n.id].picked == 0) {
                bodies_[n.id].picked = 1;
                reasonExt_.push_back(n.id);
                // Check if the body depends on the atoms from the unfounded set. I.e.
                // would the body still be false if all but its unfounded literals would be true?
                ExtData* ext     = extended_[bodies_[n.id].lower_or_ext];
                weight_t temp    = ext->lower;
                const NodeId* x  = n.node->preds();
                const uint32 inc = n.node->pred_inc();
                uint32       p   = 0;
                for (; *x != idMax; x += inc, ++p) {
                    if (!ext->inWs(p) && (atoms_[*x].ufs == 0 || solver_->isFalse(graph_->getAtomNode(*x).lit))) {
                        if ( (temp -= n.node->pred_weight(p, false)) <= 0 ) {
                            addReasonLit(n.node->lit);
                            return;
                        }
                    }
                }
                for (++x; *x != idMax; x += inc, ++p) {
                    if (!ext->inWs(p) && (temp -= n.node->pred_weight(p, true)) <= 0) {
                        addReasonLit(n.node->lit);
                        return;
                    }
                }
            }
        }
    }
    else if (n.node->scc == uScc && n.node->extended() && bodies_[n.id].picked == 0) {
        bodies_[n.id].picked = 1;
        reasonExt_.push_back(n.id);
        // body is neither false nor a valid source - add all false lits to reason set
        AddReasonLit addFalseLits = { this };
        graph_->visitBodyLiterals(n, addFalseLits);
    }
}
Example #9
0
/////////////////////////////////////////////////////////////////////////////////////////
// DefaultUnfoundedCheck - Finding & propagating unfounded sets
/////////////////////////////////////////////////////////////////////////////////////////
bool DefaultUnfoundedCheck::findUnfoundedSet() {
    // first: remove all sources that were recently falsified
    VarVec::size_type unpick = invalid_.size();
    for (VarVec::size_type i = 0; i != invalidExt_.size(); ++i) {
        uint32        id = invalidExt_[i] >> 1;
        ExtWatch::Type t = static_cast<ExtWatch::Type>(invalidExt_[i] & 1u);
        if (t == ExtWatch::watch_choice_false) {
            if (atoms_[id].hasSource() && !solver_->isFalse(graph_->getBodyNode(atoms_[id].watch()).lit)) {
                atoms_[id].markSourceInvalid();
                sourceQ_.push_back(id);
                propagateSource(true);
            }
        }
        else if (t == ExtWatch::watch_body_goal_false) {
            typedef DependencyGraph::BodyNode BodyNode;
            const ExtWatch& w = watches_[id];
            BodyData&       b = bodies_[w.bodyId];
            ExtData*      ext = extended_[b.lower_or_ext];
            const BodyNode& B = graph_->getBodyNode(w.bodyId);
            NodeId       pred = w.data >> 1;
            ext->removeFromWs(pred, B.pred_weight(pred, test_bit(w.data, 0) != 0));
            if (ext->lower > 0 && b.watches && b.picked == 0 && !solver_->isFalse(B.lit)) {
                invalid_.push_back(w.bodyId);
                b.picked = 1;
            }
        }
    }
    for (VarVec::size_type i = 0; i != invalid_.size(); ++i) {
        removeSource(invalid_[i]);
    }
    for (VarVec::size_type i = unpick; i != invalid_.size(); ++i) {
        bodies_[invalid_[i]].picked = 0;
    }
    invalid_.clear();
    invalidExt_.clear();
    assert(sourceQ_.empty() && unfounded_.empty());
    // second: try to re-establish sources.
    while (!todo_.empty()) {
        NodeId head = dequeueTodo();
        if (!atoms_[head].hasSource() && !solver_->isFalse(graph_->getAtomNode(head).lit) && !findSource(head)) {
            return true;  // found an unfounded set - contained in unfounded_
        }
        assert(sourceQ_.empty());
    }
    todo_.clear();
    return false;     // no unfounded sets
}
Example #10
0
double KellyTypeAdapt::eval_interface_estimator(KellyTypeAdapt::ErrorEstimatorForm* err_est_form,
                                                RefMap *rm, SurfPos* surf_pos,
                                                LightArray<NeighborSearch*>& neighbor_searches, int neighbor_index)
{
  NeighborSearch* nbs = neighbor_searches.get(neighbor_index);
  Hermes::vector<MeshFunction*> slns;
  for (int i = 0; i < num; i++)
    slns.push_back(this->sln[i]);
  
  // Determine integration order.
  ExtData<Ord>* fake_ui = dp.init_ext_fns_ord(slns, neighbor_searches);
  
  // Order of additional external functions.
  // ExtData<Ord>* fake_ext = dp.init_ext_fns_ord(err_est_form->ext, nbs);

  // Order of geometric attributes (eg. for multiplication of a solution with coordinates, normals, etc.).
  Geom<Ord>* fake_e = new InterfaceGeom<Ord>(init_geom_ord(), nbs->neighb_el->marker, nbs->neighb_el->id, nbs->neighb_el->get_diameter());
  double fake_wt = 1.0;
  Ord o = err_est_form->ord(1, &fake_wt, fake_ui->fn, fake_ui->fn[err_est_form->i], fake_e, NULL);

  int order = rm->get_inv_ref_order();
  order += o.get_order();

  limit_order(order);

  // Clean up.
  if (fake_ui != NULL)
  {
    for (int i = 0; i < num; i++)
      delete fake_ui->fn[i];
    fake_ui->free_ord();
    delete fake_ui;
  }
  
  delete fake_e;
  
  //delete fake_ext;
  
  Quad2D* quad = this->sln[err_est_form->i]->get_quad_2d();
  int eo = quad->get_edge_points(surf_pos->surf_num, order);
  int np = quad->get_num_points(eo);
  double3* pt = quad->get_points(eo);
  
  // Init geometry and jacobian*weights (do not use the NeighborSearch caching mechanism).
  double3* tan = rm->get_tangent(surf_pos->surf_num, eo);
  double* jwt = new double[np];
  for(int i = 0; i < np; i++)
    jwt[i] = pt[i][2] * tan[i][2];
  
  Geom<double>* e = new InterfaceGeom<double>(init_geom_surf(rm, surf_pos, eo), 
                                              nbs->neighb_el->marker, 
                                              nbs->neighb_el->id, 
                                              nbs->neighb_el->get_diameter());
    
  // function values
  ExtData<scalar>* ui = dp.init_ext_fns(slns, neighbor_searches, order);
  //ExtData<scalar>* ext = dp.init_ext_fns(err_est_form->ext, nbs);

  scalar res = interface_scaling_const *
                err_est_form->value(np, jwt, ui->fn, ui->fn[err_est_form->i], e, NULL);

  if (ui != NULL) { ui->free(); delete ui; }
  //if (ext != NULL) { ext->free(); delete ext; }
  e->free(); delete e;
  delete [] jwt;

  return std::abs(0.5*res);   // Edges are parameterized from 0 to 1 while integration weights
                              // are defined in (-1, 1). Thus multiplying with 0.5 to correct
                              // the weights.
}