Commit 49559c48 authored by Kévin Moreau's avatar Kévin Moreau

This commit mainly

 * Implements Gamma_in using the fast marching
 * Adds parameter to activate/desactivate Gamma in
 * Merges Carole work
 * Removes some old stuff not maintained in atomic_test/
 * Defines new parameters in test case infinite_dam_notch
 * Cleans up (unifies) info.dat files in test/
 * Fixes a recent bug due to small refactoring in TLSGeom
 * Takes into account element orientation when enriching
 * Correct an old bug in Util.cc (it had no effect exept recently in Carole's work)
 * Improves superposition procedure using integration by part
 * Improves README
 * Adds energetic dissipation to AsymElastoDam
parent d3cc9703
Pipeline #149 skipped
......@@ -20,7 +20,7 @@ Contents
* Good practices (development advices)
* How to
* Code structure (for developers)
* Other informations
* Other (important) informations
Directory structure
......@@ -345,9 +345,12 @@ Code structure
Other informations
------------------
* Please don't change material parameters directly inside data directory,
data are chosen and used in the reference.py script launched by ctest.
If it is changed then reference results are not the same.
* Please don't change material parameters directly inside data
directory (unless you really want to change the default test case),
data are chosen and used in the reference.py script launched by ctest.
If it is changed then reference results are not the same. Change in
material parameters have to be carefully changed in all data files as
well as in reference.py file.
* xSubMesh is only used inside TLSGeom.cc and MeshGeneration.cc, it
can be changed for anything else that is more optimized.
can be changed for anything else that is more optimized.
......@@ -2,3 +2,4 @@ TODO list !
===========
- 12/02/16: delete nodes and edges and elements remove from comp_mesh.
Valgrind should give you some memory leaks right now.
......@@ -8,20 +8,7 @@ include(devel_common_functions)
enable_testing()
file(GLOB LIST
# hansbo_enrichment
# integration
# levelset_update
# mesh_generation
# mesh_generation_2
mode
# negative
# nonlocal_projection
# patch_test
# plasticity_at_point
# projection_tensor
# reinit
# restart
# valgrind_check
)
create_tests_from_list(${LIST})
enable_testing()
add_test(hansbo_enrichment ${CMAKE_CURRENT_BINARY_DIR}/hansbo_enrichment ${CMAKE_CURRENT_BINARY_DIR}/data/square.msh)
h=0.02;
Point(1) = {0, 0, 0, h};
Point(2) = {1, 0, 0, h};
Point(3) = {1, 1, 0, h};
Point(4) = {0, 1, 0, h};
Line(1) = {1, 2};
Line(2) = {2, 3};
Line(3) = {3, 4};
Line(4) = {4, 1};
Line Loop(5) = {3, 4, 1, 2};
Plane Surface(6) = {5};
This diff is collapsed.
/*
This source code is subject to non-permissive licence,
see the TLSDuctile/LICENSE file for conditions.
*/
#include "Space.h"
#include "Util.h"
#include "xAlgorithm.h"
#include "xAssembler.h"
#include "xLevelSet.h"
#include "xMesh.h"
#include "xPhysSurfByTagging.h"
#include "xRegion.h"
#include "xSimpleGeometry.h"
#include "xSpacePolynomial.h"
#include "xCSRMatrix.h"
#include "xCSRVector.h"
#include "xLinearSystemSolverSuperLU.h"
using namespace xfem;
using Trellis_Util::mPoint;
using AOMD::mEntity;
using lalg::xCSRVector;
using lalg::xCSRMatrix;
struct EvalCustom : public xEval<double> {
void operator()(const xGeomElem* geo_appro, const xGeomElem* geo_integ, double& res) const {
res=-1.;
if(geo_appro->getXYZ()(0)>0.55001) {
res=1.;
}
}
};
template <class UnaryOperator>
class xValOperatorReset {
public:
typedef typename UnaryOperator::result_type result_type;
xValOperatorReset():funct() {}
const UnaryOperator funct;
void eval(femFcts_t* f, xGeomElem* geo_appro, xGeomElem* geo_integ, std::vector<result_type>& vals) const
{
vals.reserve(vals.size()+f->size());
xField::getFF(f->begin(), f->end(), vals, geo_appro, geo_integ, funct, true);
}
};
int main(int argc, char* argv[]) {
xMesh mesh(argv[1]);
xRegion domain(&mesh);
xLevelSet level_set(domain, xPlane(mPoint(0.55,0.55,0.), xVector(1.,0.,0.)));
xPhysSurfByTagging phys_surf(level_set);
xRegion front(phys_surf.getMesh_bnd());
xDoubleManager double_manager;
xSpacePolynomialLagrange space("space", xSpace::SCALAR, 1);
xEntityFilter is_in_pos=std::bind1st(std::mem_fun(&xPhysSurfByTagging::strictOut), &phys_surf);
xSpaceXFEMHansbo space_pos(space, is_in_pos, xValKeyExtend(""), 2);
xEntityFilter is_in_neg=std::bind1st(std::mem_fun(&xPhysSurfByTagging::strictIn), &phys_surf);
xSpaceXFEMHansbo space_neg(space, is_in_neg, xValKeyExtend("_enr"), 1);
xEntityFilter filter=std::bind1st(std::mem_fun(&xPhysSurfByTagging::supportCutStrictlyEltWise), &phys_surf);
xSpaceComposite space_xfem(xSpaceFiltered(space, xAcceptInvert(filter)),
xSpaceFiltered(space_pos, filter));
space_xfem.insert(xSpaceFiltered(space_neg, filter));
xField field(&double_manager, space_xfem);
xValueCreator<xValueDouble> value_creator;
DeclareValueField(field, value_creator, domain.begin(), domain.end());
xStateDofCreator<> state_creator(double_manager, "dofs");
DeclareState(field, state_creator, domain.begin(), domain.end());
const int nb_dofs=double_manager.size("dofs");
std::cout << "nb_dofs " << nb_dofs << std::endl;
xEvalField<xIdentity<double> > eval_field(field);
EvalCustom eval_custom;
xIntegrationRulePartition integration_rule_domain(2);
std::list<xEntityFilter> filter_vec;
filter_vec.push_back(is_in_neg);
filter_vec.push_back(is_in_pos);
xIntegrationRuleFixedPosition integration_rule_fixed(filter_vec, field, 2);
xExportGmshAscii pexport;
// for (int i=0; i<nb_dofs; ++i) {
// int j = 0;
// for (xDoubleManager::vIter it=double_manager.begin("dofs"); it!=double_manager.end("dofs"); ++it, ++j) {
// if (j==(i-1)) (*it)->setVal(0.); // it was one
// if (j==i) (*it)->setVal(1.); // it was zero
// }
// std::ostringstream oss;
// oss << "shape_fct_" << i;
// Export(eval_field, pexport, oss.str(), integration_rule_domain, domain.begin(), domain.end());
// for (xDoubleManager::vIter it=double_manager.begin("dofs"); it!=double_manager.end("dofs"); ++it) {
// (*it)->setVal(0.);
// }
// }
xFormBilinearWithoutLaw<xValOperatorReset<xIdentity<double> >,
xValOperatorReset<xIdentity<double> > > bilinear_form;
xFormLinearWithLoad<xValOperator<xIdentity<double> >,
xEval<double> > linear_form(eval_custom);
xCSRMatrix matrix(nb_dofs);
xCSRVector vector(nb_dofs);
xCSRVector sol(nb_dofs);
xAssemblerBasic<> assembler(matrix, vector);
Assemble(linear_form, assembler, integration_rule_domain, field, domain.begin(), domain.end());
SetXfemDebugFlag(true);
Assemble(bilinear_form, assembler, integration_rule_fixed, field, field, domain.begin(), domain.end());
SetXfemDebugFlag(false);
xIndicatorFunction::activate(0);
// for (int i=0; i<nb_dofs; ++i) {
// int j = 0;
// for (xDoubleManager::vIter it=double_manager.begin("dofs"); it!=double_manager.end("dofs"); ++it, ++j) {
// if (j==(i-1)) (*it)->setVal(0.); // it was one
// if (j==i) (*it)->setVal(1.); // it was zero
// }
// std::ostringstream oss;
// oss << "shape_fct_after_" << i;
// Export(eval_field, pexport, oss.str(), integration_rule_domain, domain.begin(), domain.end());
// }
lalg::xLinearSystemSolverSuperLU<> solver;
solver.connectMatrix(matrix);
solver.solve(vector, sol);
Visit(xWriteSolutionVisitor<>(sol.begin()), double_manager.begin("dofs"), double_manager.end("dofs"));
double_manager.PrintForDebug("dm.txt");
Export(eval_custom, pexport, "custom", integration_rule_domain, domain.begin(), domain.end());
Export(eval_field, pexport, "field", integration_rule_domain, domain.begin(), domain.end());
return 0;
}
enable_testing()
add_test(levelset_update ${CMAKE_CURRENT_BINARY_DIR}/levelset_update ${CMAKE_CURRENT_BINARY_DIR}/data/square.msh)
/*
This source code is subject to non-permissive licence,
see the TLSDuctile/LICENSE file for conditions.
*/
#include "xAlgorithm.h"
#include "xLevelSet.h"
#include "xMesh.h"
#include "xPhysSurfByTagging.h"
#include "xRegion.h"
#include "xSimpleGeometry.h"
#include "TLSSolver2.h"
#include "TLSSolver3.h"
#include "options.h"
using namespace xfem;
using Trellis_Util::mPoint;
using AOMD::mEntity;
struct EvalCustom : public xEval<double> {
void operator()(const xGeomElem* geo_appro, const xGeomElem* geo_integ, double& res) const {
mPoint center(0.5,0.5,0.);
const mPoint& pt=geo_appro->getXYZ();
if(pt(0)>0.3 && pt(0)<0.7) {
res=std::min(1.-pt(0), pt(0))-0.15;
}
else {
res=0.5*std::min(1.-pt(0), pt(0));
// res=0.;
}
}
};
struct EvalCustom2 : public xEval<double> {
void operator()(const xGeomElem* geo_appro, const xGeomElem* geo_integ, double& res) const {
mPoint center(0.45,0.5,0.);
res=1.+cos(xDistance(geo_appro->getXYZ(), center)*2*3.14);
res*=0.1;
}
};
struct EvalCustom3 : public xEval<double> {
void operator()(const xGeomElem* geo_appro, const xGeomElem* geo_integ, double& res) const {
mPoint center(0.5,0.5,0.);
const mPoint& pt=geo_appro->getXYZ();
if(pt(0)>0.3 && pt(0)<0.7) {
res=std::min(1.-pt(0), pt(0))-0.15;
}
else {
res=0.;
}
}
};
struct Max : public std:: binary_function<double, double, double> {
double operator()(double x, double y) const {
return std::max(x,y);
}
};
struct EvalDamageRateWrapper {
boost::shared_ptr<xfem::xEval<double> > operator()(const xfem::xEval<double>& eval_energy_release_rate)
{
return boost::shared_ptr<xfem::xEval<double> >(new xfem::xEvalUnary<xfem::xIdentity<double> >(eval_energy_release_rate));
}
};
int main(int argc, char* argv[])
{
xMesh mesh(argv[1]);
xRegion domain(&mesh);
// xUnion uni(xPlane(mPoint(0.3,0.,0.), xVector(1.,0.,0.)), xPlane(mPoint(0.7,0.,0.), xVector(-1.,0.,0.)));
// xPointToDouble uni=xCompl(xGrownSegment(mPoint(0.3,0.5,0.), mPoint(0.7,0.5,0.), 0.22));
xPointToDouble uni=xPlane(mPoint(-1.,-1.,0.), xVector(-1.,0.,0.));
xLevelSet level_set_gamma(domain, uni);
TLSSolver3 tls_solver(mesh, 0.25, true);
// EvalCustom eval_initial_phi;
xEvalLevelSet<xIdentity<double> > eval_phi(level_set_gamma);
xEvalConstant<double> eval_zero(0.);
xEvalBinary<Max> eval_initial_phi(eval_phi, eval_zero);
tls_solver.registerField("delta_phi");
tls_solver.initiateLevelSetField(level_set_gamma, eval_zero);
xScale<double> scale(0.05);
EvalCustom2 eval_custom;
xEvalUnary<xScale<double> > eval_local(scale, eval_custom);
xEvalConstant<double> eval_profil_derivative(0.1);
xEvalBinary<std::multiplies<double> > eval_local_time_profil_derivative(eval_local, eval_profil_derivative);
xEvalField<xIdentity<double> > eval_delta_phi(tls_solver.getField("delta_phi"));
for(int i=0; i<40; ++i) {
tls_solver.setCnt(i+1);
tls_solver.updateMeanField("delta_phi", eval_profil_derivative, eval_local_time_profil_derivative);
tls_solver.updateLevelSetField(eval_delta_phi);
tls_solver.delocalizeLevelSetField();
if(tls_solver.isDelocalized()) {
tls_solver.updateDomains();
tls_solver.updateLevelSetSpace();
tls_solver.updateMeanSpace();
}
}
return 0;
}
enable_testing()
add_test(hansbo_enrichment ${CMAKE_CURRENT_BINARY_DIR}/hansbo_enrichment ${CMAKE_CURRENT_BINARY_DIR}/data/square.msh)
add_test(mode ${CMAKE_CURRENT_BINARY_DIR}/mode ${CMAKE_CURRENT_BINARY_DIR}/data/square.msh)
......@@ -28,6 +28,7 @@ using namespace lalg;
using namespace xtls;
using Trellis_Util::mPoint;
using AOMD::mEntity;
using AOMD::mVertex;
int main(int argc, char* argv[]) {
......@@ -35,7 +36,7 @@ int main(int argc, char* argv[]) {
// domain creation
xPlane p1(mPoint(0.1,0.1,0.), xVector(1.,0.,0.));
xPlane p2(mPoint(0.9,0.9,0.), xVector(-1.,0.,0.));
xPlane p2(mPoint(0.205,0.205,0.), xVector(-1.,0.,0.));
xLevelSet level_set(&mesh, xUnion(p1, p2));
xPhysSurfByTagging phys_surf(level_set);
xEntityFilter filter=std::bind1st(std::mem_fun(&xPhysSurfByTagging::strictOut), &phys_surf);
......@@ -70,6 +71,12 @@ int main(int argc, char* argv[]) {
xRegion region(&domain);
std::cout<<"region "<<region.size(2)<<std::endl;
std::cout<<"bnd "<<bnd.size(0)<<std::endl;
std::cout<<"interior "<<interior.size(0)<<std::endl;
level_set.load(p1);
// phi field
xDoubleManager double_manager;
xSpacePolynomialLagrange space("space", xSpace::SCALAR, 1);
......@@ -82,7 +89,7 @@ int main(int argc, char* argv[]) {
std::vector<xValue<double>*> vals;
vals.reserve(keys.sizeKey());
double_manager.getValPtr(keys.beginKey(), keys.endKey(), vals);
vals[0]->setVal(level_set(*it));
vals[0]->setVal(1.*level_set(*it));
}
xEvalField<xIdentity<double> > eval_field(field);
......@@ -91,23 +98,47 @@ int main(int argc, char* argv[]) {
Export(eval_field, pexport, "phi_given", integ_rule, region.begin(), region.end());
std::function<double (const AOMD::mVertex&)> f_func=[](const AOMD::mVertex&){ return 1.; };
FastMarchingReinit(field,
region,
bnd.begin(0), bnd.end(0),
interior.begin(0), interior.end(0), f_func, false);
std::vector<const AOMD::mEntity*> bnd_in_vec;
bnd_in_vec.reserve(bnd.size(0));
FastMarchingReinit([&field](mVertex* v){ std::vector<double> vals; field.getVals(v, vals); return vals[0]; },
[&field](mVertex* v, double val){ field.setVal(v, val); },
region,
bnd.begin(0), bnd.end(0),
interior.begin(0), interior.end(0),
std::back_inserter(bnd_in_vec));
Export(eval_field, pexport, "phi", integ_rule, region.begin(), region.end());
xSubMesh bnd_in("bnd_in", mesh);
for(auto v: bnd_in_vec) {
bnd_in.add(const_cast<AOMD::mEntity*>(v));
}
xSubMesh interior_in("interior_in", mesh);
xAcceptInSubMesh is_in_bnd_in(bnd_in);
for(xIter it=domain.begin(0); it!=domain.end(0); ++it) {
if(!is_in_bnd_in(*it)) {
interior_in.add(*it);
}
}
xEvalConstant<double> eval_one(1.);
Export(eval_one, pexport, "bnd_in", integ_rule, bnd_in.begin(), bnd_in.end());
Export(eval_one, pexport, "interior_in", integ_rule, interior_in.begin(), interior_in.end());
// modes creation
xDenseMatrix coeffs;
FastMarchingModeExtension(field,
region,
bnd.begin(0), bnd.end(0),
interior.begin(0), interior.end(0),
coeffs);
xDenseMatrix coeffs(bnd_in.size(0), region.size(0));
FastMarchingModeExtension([&field](mVertex* v){ std::vector<double> vals; field.getVals(v, vals); return vals[0]; },
[&field](mVertex* v, double val){ field.setVal(v, val); },
region,
bnd_in.begin(0), bnd_in.end(0),
interior_in.begin(0), interior_in.end(0),
coeffs);
std::cout<<"nb modes "<<bnd_in.size(0)<<std::endl;
// modes export
for(int i=0; i<bnd.size(0); ++i) {
for(int i=0; i<bnd_in.size(0); ++i) {
int j=0;
for(xIter it=region.begin(0); it!=region.end(0); ++it, ++j) {
xFiniteElementKeysOnly keys;
......@@ -131,7 +162,7 @@ int main(int argc, char* argv[]) {
double_manager.getValPtr(keys.beginKey(), keys.endKey(), vals);
double sum=0.;
for(int i=0; i<bnd.size(0); ++i) {
for(int i=0; i<bnd_in.size(0); ++i) {
sum+=coeffs(i,j);
}
vals[0]->setVal(sum);
......
enable_testing()
add_test(nonlocal_projection ${CMAKE_CURRENT_BINARY_DIR}/nonlocal_projection ${CMAKE_CURRENT_BINARY_DIR}/data/square.msh)
h=0.02;
Point(1) = {0, 0, 0, h};
Point(2) = {1, 0, 0, h};
Point(3) = {1, 1, 0, h};
Point(4) = {0, 1, 0, h};
Line(1) = {1, 2};
Line(2) = {2, 3};
Line(3) = {3, 4};
Line(4) = {4, 1};
Line Loop(5) = {3, 4, 1, 2};
Plane Surface(6) = {5};
This diff is collapsed.
This diff is collapsed.
/*
This source code is subject to non-permissive licence,
see the TLSDuctile/LICENSE file for conditions.
*/
#ifndef _nonlocal_projection_h_
#define _nonlocal_projection_h_
#include "xApproxFunction.h"
#include "xSpace.h"
namespace xfem {
class xApproxFunctionScale : public xApproxFunction {
public:
xApproxFunctionScale(shapeFctPtr fct_, double coeff_);
void getVal(const xGeomElem* geo_appro, const xGeomElem* geo_integ, double&) const;
void getGrad(const xGeomElem* geo_appro, const xGeomElem* geo_integ, xVector&) const;
private:
shapeFctPtr fct;
const double coeff;
};
xApproxFunctionScale::xApproxFunctionScale(shapeFctPtr fct_, double coeff_) :
fct(fct_), coeff(coeff_)
{}
void xApproxFunctionScale::getVal(const xGeomElem* geo_appro, const xGeomElem* geo_integ, double& res) const {
fct->getVal(geo_appro, geo_integ, res);
res*=coeff;
}
void xApproxFunctionScale::getGrad(const xGeomElem* geo_appro, const xGeomElem* geo_integ, xVector& res) const {
fct->getGrad(geo_appro, geo_integ, res);
res*=coeff;
}
class xNonLocalInfoForKeysAndFcts2
{
public:
typedef eXlibris_types::hash_map<xValKey, double , xHashValKey, xEqualValKey> femRelKeys;
private:
class xValKeySub
{
public:
xValKeySub () {}
xValKeySub(AOMD::mEntity *e_,short geom_id_):e(e_),geom_id(geom_id_) {}
AOMD::mEntity *getEnti(void) {return e;}
AOMD::mEntity *getEnti(void) const {return e;}
void setEnti(AOMD::mEntity* in) { e = in; }
short getGeom(void) {return geom_id;}
short getGeom(void) const {return geom_id;}
void setGeom(short in) {geom_id = in;}
private:
AOMD::mEntity *e;
short geom_id;
friend int compkey (const xValKeySub& c1, const xValKeySub& c2){
if(c1.e > c2.e)return 1;
if(c1.e < c2.e)return -1;
if(c1.geom_id > c2.geom_id)return 1;
if(c1.geom_id < c2.geom_id)return -1;
return 0;
}
};
struct xHashValKeySub {
int operator()(const xValKeySub& key) const { return key.getEnti()->getId(); }
};
struct xEqualValKeySub {
bool operator()(const xValKeySub& key1, const xValKeySub& key2) const { return compkey(key1, key2)==0; }
};
typedef eXlibris_types::hash_map<xValKeySub, femRelKeys, xHashValKeySub, xEqualValKeySub> master_container_t;
typedef eXlibris_types::hash_map<xValKeySub, xSpace::femKeys, xHashValKeySub, xEqualValKeySub> slave_container_t;
typedef master_container_t::iterator master_container_iter_t;
typedef slave_container_t::iterator slave_container_iter_t;
typedef master_container_t::const_iterator master_container_const_iter_t;
typedef slave_container_t::const_iterator slave_container_const_iter_t;
master_container_t master;
slave_container_t slave;
public:
xNonLocalInfoForKeysAndFcts2()
{}
void getAllKeysFromSlavesAndFree(xSpace::femKeys* keys)
{
xSpace::femKeys keys_copy;
keys->swap(keys_copy);
std::set<xValKey> masters;
xValKeySub search_key;
xSpace::femKeys::iterator it=keys_copy.begin();
for(; it!=keys_copy.end(); ++it) {
slave_container_iter_t it_find;
search_key.setGeom(it->getGeom());
search_key.setEnti(it->getEnti());
if((it_find=slave.find(search_key))!=slave.end()) {
xSpace::femKeys::iterator it_cur_slave=(it_find->second).begin();
xSpace::femKeys::iterator it_cur_slave_end=(it_find->second).end();
for(; it_cur_slave!=it_cur_slave_end; ++it_cur_slave) {
masters.insert(*it_cur_slave);
}
}
else {
keys->push_back(*it);
}
}
keys->reserve(keys->size()+masters.size());
std::set<xValKey>::iterator itm=masters.begin();
for(; itm!=masters.end(); ++itm) {
if(find(keys->begin(), keys->end(), *itm)==keys->end()) {
keys->push_back(*itm);
}
}
}
void getAllKeysAndFctsFromSlavesAndFree(xSpace::femKeys* keys, xSpace::femFcts* fcts)
{
xSpace::femKeys keys_copy;
xSpace::femFcts fcts_copy;
keys->swap(keys_copy);
fcts->swap(fcts_copy);
// std::cout << "keys size " << keys_copy.size() << std::endl;
// std::cout << "fcts size " << fcts_copy.size() << std::endl;
std::map<xValKey, approxFctPtr_t> slaves;
std::set<xValKey> masters;
xValKeySub search_key;
xSpace::femKeys::iterator it = keys_copy.begin();
xSpace::femFcts::iterator itf = fcts_copy.begin();
for(; it!=keys_copy.end(); ++it, ++itf) {
slave_container_iter_t it_find;
search_key.setGeom(it->getGeom());
search_key.setEnti(it->getEnti());
if((it_find=slave.find(search_key))!=slave.end()) {
xSpace::femKeys::iterator it_cur_slave=(it_find->second).begin();
xSpace::femKeys::iterator it_cur_slave_end=(it_find->second).end();
for(; it_cur_slave!=it_cur_slave_end; ++it_cur_slave) {
masters.insert(*it_cur_slave);
}
slaves.insert(std::make_pair(*it, *itf));
}
else {
keys->push_back(*it);
fcts->push_back(*itf);
}
}
// std::cout << "keys size after " << keys->size() << std::endl;
// std::cout << "fcts size after " << fcts->size() << std::endl;
// std::cout << "masters size " << masters.size() << std::endl;
// std::cout << "slaves size " << slaves.size() << std::endl;
keys->reserve(keys->size()+masters.size());
fcts->reserve(fcts->size()+masters.size());
std::set<xValKey>::iterator itm=masters.begin();
for(; itm!=masters.end(); ++itm) {
master_container_iter_t it_find;
search_key.setGeom(itm->getGeom());
search_key.setEnti(itm->getEnti());
std::vector<xSpace::shapeFctPtr> approx_vec;
if((it_find=master.find(search_key))!=master.end()) {
femRelKeys::iterator it_cur_master=(it_find->second).begin();
femRelKeys::iterator it_cur_master_end=(it_find->second).end();
for(; it_cur_master!=it_cur_master_end; ++it_cur_master) {
xValKey key=it_cur_master->first;
double coeff=it_cur_master->second;
approx_vec.push_back(xSpace::shapeFctPtr(new xApproxFunctionScale(slaves[key], coeff)));
}
}
if(!approx_vec.empty()) {
keys->push_back(*itm);
fcts->push_back(xSpace::shapeFctPtr(new xApproxFunctionSummed(approx_vec)));
}
}
}
void addSlave(xValKey& key, xSpace::femKeys& keys)
{
xValKeySub sub_key(key.getEnti(),key.getGeom());
slave.insert(std::make_pair(sub_key,keys));
}
void addMaster(xValKey& key, xNonLocalInfoForKeysAndFcts::femRelKeys& rel_keys)
{
xValKeySub sub_key(key.getEnti(),key.getGeom());
master.insert(std::make_pair(sub_key,rel_keys));
}
void reserveMaster(int n)
{
#ifdef USE_C11_FEATURE
master.reserve(n);
#endif
}
};
struct xAttachableNonLocalInfoForKeysAndFcts2 : public AOMD::mAttachableData {
virtual ~xAttachableNonLocalInfoForKeysAndFcts2() {}
xNonLocalInfoForKeysAndFcts2* m;
};
inline xNonLocalInfoForKeysAndFcts2* getAttachedNonLocalInfoForKeysAndFcts2(AOMD::mEntity* e, unsigned int tag)
{
xAttachableNonLocalInfoForKeysAndFcts2* ac = (xAttachableNonLocalInfoForKeysAndFcts2*)(e->getData(tag));
if(!ac) {
return NULL;
}
return ac->m;
};
inline void attachNonLocalInfoForKeysAndFcts2(AOMD::mEntity* e, unsigned int tag, xNonLocalInfoForKeysAndFcts2* m)
{
xAttachableNonLocalInfoForKeysAndFcts2 *ac = (xAttachableNonLocalInfoForKeysAndFcts2*)(e->getData(tag));
if(!ac) {
ac = new xAttachableNonLocalInfoForKeysAndFcts2;
e->attachData(tag,ac);
}
ac->m = m;
};
inline void nullifyAttachedNonLocalInfoForKeysAndFcts2(AOMD::mEntity* e, unsigned int tag)
{
xAttachableNonLocalInfoForKeysAndFcts2 *ac = (xAttachableNonLocalInfoForKeysAndFcts2*)(e->getData(tag));
if(ac) {
ac->m=NULL;
}
};
}
#endif
enable_testing()
add_test(patch_test ${CMAKE_CURRENT_BINARY_DIR}/levelset_update ${CMAKE_CURRENT_BINARY_DIR}/data/square.msh data/main.dat)