Page MenuHomec4science

filter_threshold.cc
No OneTemporary

File Metadata

Created
Wed, Jul 17, 08:10

filter_threshold.cc

/**
* @file filter_threshold.cc
*
* @author Guillaume Anciaux <guillaume.anciaux@epfl.ch>
* @author Till Junge <till.junge@epfl.ch>
*
* @date Wed Jul 09 21:59:47 2014
*
* @brief This filter allows to select DOFs based on a threhold criterion
*
* @section LICENSE
*
* Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* LibMultiScale is free software: you can redistribute it and/or modify it
* under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* LibMultiScale is distributed in the hope that it will be useful, but
* WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with LibMultiScale. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "filter_threshold.hh"
#include "compute_interface.hh"
#include "factory_multiscale.hh"
#include "lib_continuum.hh"
#include "lib_dd.hh"
#include "lib_md.hh"
#include "lm_common.hh"
#include "ref_point_data.hh"
/* -------------------------------------------------------------------------- */
#include <limits>
#include <sstream>
/* -------------------------------------------------------------------------- */
__BEGIN_LIBMULTISCALE__
LMID sillyID(
"You forgot to set the parameter 'COMPUTE' which is a mandatory field");
/* -------------------------------------------------------------------------- */
FilterThreshold::FilterThreshold(const std::string &name)
: LMObject(name), min(std::numeric_limits<Real>::max()),
max(-std::numeric_limits<Real>::max()), compute(sillyID) {
this->createInput("input");
this->createOutput("references");
this->createArrayOutput("compute");
}
/* -------------------------------------------------------------------------- */
FilterThreshold::~FilterThreshold() {}
/* -------------------------------------------------------------------------- */
void FilterThreshold::init() {
if (this->compute == sillyID) {
LM_FATAL("You did not specify an input compute for the FilterThreshold '"
<< this->getID() << "'. the parameter COMPUTE is mandatory");
}
bool has_min = this->min != std::numeric_limits<Real>::max();
bool has_max = -this->max != std::numeric_limits<Real>::max();
if (has_min && has_max) {
if (this->min > this->max) {
LM_FATAL("The mininum threshold you specified is larger than the maximum "
<< "for FilterThreshold '" << this->getID() << "'.");
}
} else if (!has_min && !has_max) {
LM_FATAL("You forgot to specify a threshold value for FilterThreshold '"
<< this->getID() << "'. You have to specify at least a min or a "
<< "max value.");
}
}
/* -------------------------------------------------------------------------- */
template <typename _Input> void FilterThreshold::build(_Input &cont) {
// choose the right builder
const bool has_min = this->min != std::numeric_limits<Real>::max();
const bool has_max = -this->max != std::numeric_limits<Real>::max();
if (has_min && has_max) {
this->template buildMinMax<true, true>(cont);
} else if (has_min && !has_max) {
this->template buildMinMax<true, false>(cont);
} else if (!has_min && has_max) {
this->template buildMinMax<false, true>(cont);
}
}
/* -------------------------------------------------------------------------- */
template <bool has_min, bool has_max, typename _Input>
void FilterThreshold::buildMinMax(_Input &cont) {
auto &output = allocOutput<typename _Input::ContainerSubset>("references");
auto &out_compute = getOutputAsArray("compute");
output.clear();
out_compute.clear();
auto &in_comp = FilterManager::getManager().getCastedObject<ComputeInterface>(
this->compute);
// check size and dimension of the input compute
LM_ASSERT(in_comp.evalArrayOutput().getDim() == 1,
"The compute '"
<< this->compute
<< "', which is used as input for the FilterThreshold '"
<< this->getID() << "' is not scalar (but should be).");
// this forces the in_compute to compute itself if it isn't done yet
in_comp.compute();
auto it_points = cont.begin();
auto it_comp_vals = in_comp.evalArrayOutput().begin();
auto end_points = cont.end();
// auto end_comp_vals = in_comp.end();
UInt counter = 0;
for (auto &&[point, val] : zip(cont, in_comp.evalArrayOutput())) {
bool add_this = true;
if (has_min) {
add_this &= this->min <= val;
}
if (has_max) {
add_this &= this->max >= val;
}
if (add_this) {
output.push_back(point);
out_compute.push_back(val);
counter++;
}
}
DUMP("nb_points after threshold = " << counter, DBG_INFO);
}
/* -------------------------------------------------------------------------- */
/* LMDESC THRESHOLD
Given an input and a compute, this filter will return a filtered version of
the input, and create a compute with the name "<compute\_name>:<filter\_name>
which allows to make filters based on compute results without repaying the
price of the compute for the filtered points/elements. The keyword COMPUTE
is mandatory.
*/
/* LMEXAMPLE FILTER clownorama THRESHOLD INPUT md COMPUTE centrosymmetry MIN 12
MAX 24 */
void FilterThreshold::declareParams() {
FilterInterface::declareParams();
/* LMKEYWORD COMPUTE
specify which compute should be used to filter
*/
this->parseKeyword("COMPUTE", compute);
/* LMKEYWORD MAX
specify a maximum threshold
*/
this->parseKeyword("MAX", max, -lm_real_max);
/* LMKEYWORD MIN
specify a minimum threshold
*/
this->parseKeyword("MIN", min, lm_real_max);
}
/* -------------------------------------------------------------------------- */
DECLARE_COMPUTE_MAKE_CALL(FilterThreshold)
__END_LIBMULTISCALE__

Event Timeline