v0.15.0
Loading...
Searching...
No Matches
SolutionMapping.hpp
/** \file SolutionMapping.hpp
* \example SolutionMapping.hpp
*/
SetEnrichedIntegration(boost::shared_ptr<Range> new_els);
MoFEMErrorCode operator()(ForcesAndSourcesCore *fe_raw_ptr, int order_row,
int order_col, int order_data);
private:
struct Fe : public ForcesAndSourcesCore {
using ForcesAndSourcesCore::dataOnElement;
private:
using ForcesAndSourcesCore::ForcesAndSourcesCore;
};
boost::shared_ptr<Range> newEls;
static inline std::map<long int, MatrixDouble> mapRefCoords;
};
MoFEMErrorCode mapFields(SmartPetscObj<DM> &intermediateDM,
Range elsToFlip = Range(), PetscInt numVecs = 1,
Vec vecsToMapFrom[] = PETSC_NULLPTR,
Vec vecsToMapTo[] = PETSC_NULLPTR);
MoFEMErrorCode reSetUp(std::vector<std::string> fIelds,
std::vector<int> oRders, BitRefLevel bIt);
private:
SmartPetscObj<DM> subDM, intermediateDM;
boost::shared_ptr<DomainEle> feRhs;
boost::shared_ptr<DomainEle> feLhs;
MoFEMErrorCode setUp(SmartPetscObj<DM> &subDM,
SmartPetscObj<DM> &intermediateDM, Range elsToAdd,
Vec vecIn = PETSC_NULLPTR);
MoFEMErrorCode solveMap(SmartPetscObj<DM> &subDM,
SmartPetscObj<DM> &intermediateDM, PetscInt numVecs,
Vec vecsToMapFrom[], Vec vecsToMapTo[]);
MoFEMErrorCode postProcess();
};
SolutionMapping::SolutionMapping(MoFEM::Interface &m_field) : m_field(m_field) {
feRhs = boost::make_shared<DomainEle>(m_field);
feLhs = boost::make_shared<DomainEle>(m_field);
}
MoFEMErrorCode SolutionMapping::mapFields(SmartPetscObj<DM> &intermediate_dm,
Range els_to_remove, Range els_to_add,
Range els_to_flip, PetscInt num_vecs,
Vec vecs_to_map_from[],
Vec vecs_to_map_to[]) {
CHKERR pushOperators(els_to_flip, els_to_add);
CHKERR setUp(subDM, intermediate_dm, els_to_add, els_to_flip);
CHKERR solveMap(subDM, intermediate_dm, num_vecs, vecs_to_map_from,
vecs_to_map_to);
};
MoFEMErrorCode SolutionMapping::setUp(SmartPetscObj<DM> &sub_dm,
SmartPetscObj<DM> &intermediate_dm,
Range els_to_add, Range els_to_flip) {
MOFEM_LOG("REMESHING", Sev::inform) << "Set up sub DM for mapping";
Simple *simple = m_field.getInterface<Simple>();
Range sub_dm_elems;
auto create_sub_dm = [&]() {
sub_dm = createDM(m_field.get_comm(), "DMMOFEM");
auto create_impl = [&]() {
CHKERR DMSetType(sub_dm, "DMMOFEM");
CHKERR DMMoFEMCreateSubDM(sub_dm, intermediate_dm, "SUB_MAPPING");
CHKERR DMMoFEMAddElement(sub_dm, simple->getDomainFEName());
CHKERR DMMoFEMSetSquareProblem(sub_dm, PETSC_TRUE);
CHKERR DMMoFEMSetDestroyProblem(sub_dm, PETSC_TRUE);
MOFEM_LOG("REMESHING", Sev::inform) << "Created sub DM";
for (auto f : {"T", "TAU", "EP"}) {
boost::make_shared<Range>(els_to_add));
boost::make_shared<Range>(els_to_add));
}
auto bit = BitRefLevel().set();
};
CHKERR create_impl();
};
CHK_THROW_MESSAGE(create_sub_dm(), "failed to create sub dm");
MOFEM_LOG("REMESHING", Sev::inform) << "Set up sub DM for mapping <= done";
};
MoFEMErrorCode SolutionMapping::reSetUp(std::vector<std::string> fields,
std::vector<int> orders,
BitRefLevel bit) {
Simple *simple = m_field.getInterface<Simple>();
auto add_ents_order_to_field =
const std::initializer_list<std::string> &f,
const std::initializer_list<EntityType> &t, int _order) {
for (auto _f : f) {
for (auto _t : t) {
CHKERR m_field.set_field_order(0, _t, _f, _order);
}
}
};
for (size_t i = 0; i < fields.size(); ++i) {
CHKERR add_ents_order_to_field(m_field, {fields[i]}, {MBTRI}, orders[i]);
}
simple->getDomainFEName());
};
Range els_to_add) {
const Problem *prb_ptr;
CHKERR m_field.get_problem("SUB_MAPPING", &prb_ptr);
int nb_init_row_dofs = prb_ptr->getNbDofsRow();
MOFEM_LOG("REMESHING", Sev::verbose)
<< "Number of initial row dofs: " << nb_init_row_dofs;
if (is_distributed_mesh == PETSC_FALSE)
CHKERR m_field.getInterface<CommInterface>()->synchroniseEntities(
els_to_remove);
auto prb_mng = m_field.getInterface<ProblemsManager>();
auto remove_dofs_on_ents = [&](std::string field, const Range &ents) {
if (is_distributed_mesh == PETSC_TRUE)
return prb_mng->removeDofsOnEntities("SUB_MAPPING", field, ents);
else
return prb_mng->removeDofsOnEntitiesNotDistributed("SUB_MAPPING", field,
ents);
};
for (std::string field : {"EP", "TAU", "T"}) {
remove_dofs_on_ents(field, els_to_remove);
nb_init_row_dofs = prb_ptr->getNbDofsRow();
MOFEM_LOG("REMESHING", Sev::verbose)
<< "Number of row dofs after removing " << field
<< " field: " << nb_init_row_dofs;
}
};
Range els_to_add, Vec vec_in) {
SmartPetscObj<Vec> smart_vec_in;
if (vec_in)
smart_vec_in = SmartPetscObj<Vec>(vec_in, true);
MOFEM_LOG("REMESHING", Sev::inform) << "Got past smart vector";
feRhs->getOpPtrVector().clear();
MOFEM_LOG("REMESHING", Sev::inform) << "Cleared RHS FE";
Simple *simple = m_field.getInterface<Simple>();
auto vol_rule = [](int, int, int ao) { return 2 * ao + geom_order; };
// feRhs->getRuleHook = vol_rule;
// feLhs->getRuleHook = vol_rule;
feRhs->getRuleHook = [](int, int, int) { return -1; };
feRhs->setRuleHook =
SetEnrichedIntegration(boost::make_shared<Range>(els_to_add));
feLhs->getRuleHook = [](int, int, int) { return -1; };
feLhs->setRuleHook =
SetEnrichedIntegration(boost::make_shared<Range>(els_to_add));
auto T_ptr = boost::make_shared<VectorDouble>();
auto TAU_ptr = boost::make_shared<VectorDouble>();
auto EP_ptr = boost::make_shared<MatrixDouble>();
auto set_domain_rhs = [&](auto &pip) {
auto old_T_ptr = boost::make_shared<VectorDouble>();
auto old_TAU_ptr = boost::make_shared<VectorDouble>();
auto old_EP_ptr = boost::make_shared<MatrixDouble>();
auto old_el_ops = [&](auto &pip) {
// get old solution
if (vec_in) {
pip.push_back(
new OpCalculateScalarFieldValues("T", old_T_ptr, smart_vec_in));
pip.push_back(
new OpCalculateScalarFieldValues("TAU", old_TAU_ptr, smart_vec_in));
pip.push_back(new OpCalculateTensor2SymmetricFieldValues<SPACE_DIM>(
"EP", old_EP_ptr, smart_vec_in));
} else {
pip.push_back(new OpCalculateScalarFieldValues("T", old_T_ptr));
pip.push_back(new OpCalculateScalarFieldValues("TAU", old_TAU_ptr));
pip.push_back(new OpCalculateTensor2SymmetricFieldValues<SPACE_DIM>(
"EP", old_EP_ptr));
}
// pip.push_back(new EdgeFlippingOps::filterScalarSolution<AT, IT>(
// "T", old_T_ptr, nullptr, nullptr, nullptr));
// pip.push_back(new EdgeFlippingOps::filterScalarSolution<AT, IT>(
// "TAU", old_TAU_ptr, nullptr, nullptr, nullptr));
// pip.push_back(new EdgeFlippingOps::filterSymTensorSolution<AT, IT,
// SPACE_DIM>("EP", old_EP_ptr, nullptr, nullptr, nullptr));
};
auto new_el_ops = [&](auto &pp_fe, auto &&p) {
auto new_T_ptr = boost::make_shared<VectorDouble>();
auto new_TAU_ptr = boost::make_shared<VectorDouble>();
auto new_EP_ptr = boost::make_shared<MatrixDouble>();
if (vec_in) {
pip.push_back(
new OpCalculateScalarFieldValues("T", new_T_ptr, smart_vec_in));
pip.push_back(
new OpCalculateScalarFieldValues("TAU", new_TAU_ptr, smart_vec_in));
pip.push_back(new OpCalculateTensor2SymmetricFieldValues<SPACE_DIM>(
"EP", new_EP_ptr, smart_vec_in));
} else {
MOFEM_LOG("REMESHING", Sev::inform) << "In other branch of child ops";
pip.push_back(new OpCalculateScalarFieldValues("T", new_T_ptr));
pip.push_back(new OpCalculateScalarFieldValues("TAU", new_TAU_ptr));
pip.push_back(new OpCalculateTensor2SymmetricFieldValues<SPACE_DIM>(
"EP", new_EP_ptr));
}
pip.push_back(
"T", old_T_ptr, nullptr, new_T_ptr, nullptr, m_field));
pip.push_back(
"TAU", old_TAU_ptr, nullptr, new_TAU_ptr, nullptr, m_field));
pip.push_back(
"EP", old_EP_ptr, nullptr, new_EP_ptr, nullptr, m_field));
};
// create an OpLoopRange object
auto op_range = new OpLoopRange<DomainEleOnRange>(
m_field, simple->getDomainFEName(),
boost::make_shared<Range>(els_to_flip), Sev::noisy);
op_range->getRangeFEPtr()->getRuleHook = [](int, int, int) { return -1; };
// push operator
pip.push_back(op_range);
// call the parent ops from each child pipeline
CHK_MOAB_THROW(new_el_ops(pip, old_el_ops(op_range->getOpPtrVector())),
"failed to loop over child ops");
};
auto set_domain_lhs = [&](auto &pip) {
using OpLhsScalarLeastSquaresProj = FormsIntegrators<DomainEleOp>::Assembly<
pip.push_back(new OpLhsScalarLeastSquaresProj("T", "T"));
pip.push_back(new OpLhsScalarLeastSquaresProj("TAU", "TAU"));
pip.push_back(
"EP", "EP"));
};
CHKERR set_domain_rhs(feRhs->getOpPtrVector());
CHKERR set_domain_lhs(feLhs->getOpPtrVector());
};
MoFEMErrorCode SolutionMapping::solveMap(SmartPetscObj<DM> &sub_dm,
SmartPetscObj<DM> &intermediate_dm,
PetscInt num_vecs,
Vec vecs_to_map_from[],
Vec vecs_to_map_to[]) {
auto simple = m_field.getInterface<Simple>();
auto is_mgr = m_field.getInterface<ISManager>();
auto post_proc = [&](auto dm, std::string file_name) {
auto T_ptr = boost::make_shared<VectorDouble>();
auto TAU_ptr = boost::make_shared<VectorDouble>();
auto EP_ptr = boost::make_shared<MatrixDouble>();
auto post_proc_fe = boost::make_shared<PostProcEle>(m_field);
using OpPPMap = OpPostProcMapInMoab<SPACE_DIM, SPACE_DIM>;
post_proc_fe->getOpPtrVector().push_back(
new OpCalculateScalarFieldValues("T", T_ptr));
post_proc_fe->getOpPtrVector().push_back(
new OpCalculateScalarFieldValues("TAU", TAU_ptr));
post_proc_fe->getOpPtrVector().push_back(
new OpCalculateTensor2SymmetricFieldValues<SPACE_DIM>("EP", EP_ptr));
// post_proc_fe->getOpPtrVector().push_back(
// new OpCalculateVectorFieldValues<SPACE_DIM>("U", u_ptr));
post_proc_fe->getOpPtrVector().push_back(
new OpPPMap(post_proc_fe->getPostProcMesh(),
post_proc_fe->getMapGaussPts(),
{{"T", T_ptr}, {"TAU", TAU_ptr}},
{},
{},
{{"EP", EP_ptr}}
)
);
CHKERR DMoFEMLoopFiniteElements(dm, simple->getDomainFEName(),
post_proc_fe);
CHKERR post_proc_fe->writeFile(file_name);
};
auto null_fe = boost::shared_ptr<FEMethod>();
CHKERR DMMoFEMKSPSetComputeOperators(sub_dm, simple->getDomainFEName(), feLhs,
null_fe, null_fe);
// CHKERR DMMoFEMKSPSetComputeRHS(sub_dm, simple->getDomainFEName(), feRhs,
// null_fe, null_fe);
auto ksp = MoFEM::createKSP(m_field.get_comm());
CHKERR KSPSetDM(ksp, sub_dm);
CHKERR KSPSetFromOptions(ksp);
// We create a temp_D to store current state of the mesh. We doing to preserve
// whatever is currently stored on entities, we will restore it to keep it as
// it was before.
auto tmp_D = createDMVector(intermediate_dm);
CHKERR DMoFEMMeshToLocalVector(intermediate_dm, tmp_D, INSERT_VALUES,
SCATTER_FORWARD);
CHKERR VecGhostUpdateBegin(tmp_D, INSERT_VALUES, SCATTER_FORWARD);
CHKERR VecGhostUpdateEnd(tmp_D, INSERT_VALUES, SCATTER_FORWARD);
auto D = createDMVector(sub_dm);
auto F = vectorDuplicate(D);
for (int i = 0; i < num_vecs; ++i) {
CHKERR VecGhostUpdateBegin(vecs_to_map_from[i], INSERT_VALUES,
SCATTER_FORWARD);
CHKERR VecGhostUpdateEnd(vecs_to_map_from[i], INSERT_VALUES,
SCATTER_FORWARD);
CHKERR DMoFEMMeshToLocalVector(intermediate_dm, vecs_to_map_from[i],
INSERT_VALUES, SCATTER_REVERSE);
// map
CHKERR VecZeroEntries(F);
CHKERR VecGhostUpdateBegin(F, INSERT_VALUES, SCATTER_FORWARD);
CHKERR VecGhostUpdateEnd(F, INSERT_VALUES, SCATTER_FORWARD);
feRhs->ksp_f = F;
CHKERR DMoFEMLoopFiniteElements(sub_dm, simple->getDomainFEName(), feRhs);
CHKERR VecGhostUpdateBegin(F, ADD_VALUES, SCATTER_REVERSE);
CHKERR VecGhostUpdateEnd(F, ADD_VALUES, SCATTER_REVERSE);
CHKERR VecAssemblyBegin(F);
CHKERR VecAssemblyEnd(F);
CHKERR KSPSolve(ksp, F, D);
// update data
CHKERR DMoFEMMeshToLocalVector(sub_dm, D, INSERT_VALUES, SCATTER_REVERSE);
CHKERR DMoFEMMeshToLocalVector(intermediate_dm, vecs_to_map_to[i],
INSERT_VALUES, SCATTER_FORWARD);
CHKERR VecGhostUpdateBegin(vecs_to_map_to[i], INSERT_VALUES,
SCATTER_FORWARD);
CHKERR VecGhostUpdateEnd(vecs_to_map_to[i], INSERT_VALUES, SCATTER_FORWARD);
CHKERR post_proc(intermediate_dm, "out_map_" + std::to_string(i) + ".h5m");
}
CHKERR DMoFEMMeshToLocalVector(intermediate_dm, tmp_D, INSERT_VALUES,
SCATTER_REVERSE);
MOFEM_LOG("REMESHING", Sev::inform) << "Mapped thermoplastic state variables";
};
// Use example
// CHKERR SolutionMapping(m_field).mapFields();
void simple(double P1[], double P2[], double P3[], double c[], const int N)
Definition acoustic.cpp:69
constexpr int SPACE_DIM
[Define dimension]
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
@ L2
field with C-1 continuity
Definition definitions.h:88
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
@ F
PetscErrorCode DMMoFEMSetIsPartitioned(DM dm, PetscBool is_partitioned)
Definition DMMoFEM.cpp:1113
PetscErrorCode DMMoFEMCreateSubDM(DM subdm, DM dm, const char problem_name[])
Must be called by user to set Sub DM MoFEM data structures.
Definition DMMoFEM.cpp:215
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
Definition DMMoFEM.cpp:488
PetscErrorCode DMMoFEMSetSquareProblem(DM dm, PetscBool square_problem)
set squared problem
Definition DMMoFEM.cpp:450
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode)
set local (or ghosted) vector values on mesh for partition only
Definition DMMoFEM.cpp:514
PetscErrorCode DMMoFEMAddSubFieldRow(DM dm, const char field_name[])
Definition DMMoFEM.cpp:238
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
Definition DMMoFEM.cpp:576
auto createDMVector(DM dm)
Get smart vector from DM.
Definition DMMoFEM.hpp:1234
PetscErrorCode DMMoFEMAddSubFieldCol(DM dm, const char field_name[])
Definition DMMoFEM.cpp:280
PetscErrorCode DMSubDMSetUp_MoFEM(DM subdm)
Definition DMMoFEM.cpp:1344
PetscErrorCode DMMoFEMKSPSetComputeOperators(DM dm, const char fe_name[], MoFEM::FEMethod *method, MoFEM::BasicMethod *pre_only, MoFEM::BasicMethod *post_only)
Set KSP operators and push mofem finite element methods.
Definition DMMoFEM.cpp:668
virtual const Problem * get_problem(const std::string problem_name) const =0
Get the problem object.
virtual MoFEMErrorCode build_finite_elements(int verb=DEFAULT_VERBOSITY)=0
Build finite elements.
virtual MoFEMErrorCode add_ents_to_finite_element_by_type(const EntityHandle entities, const EntityType type, const std::string name, const bool recursive=true)=0
add entities to finite element
virtual MoFEMErrorCode build_fields(int verb=DEFAULT_VERBOSITY)=0
virtual MoFEMErrorCode set_field_order(const EntityHandle meshset, const EntityType type, const std::string &name, const ApproximationOrder order, int verb=DEFAULT_VERBOSITY)=0
Set order approximation of the entities in the field.
virtual MoFEMErrorCode add_ents_to_field_by_type(const Range &ents, const EntityType type, const std::string &name, int verb=DEFAULT_VERBOSITY)=0
Add entities to field meshset.
#define MOFEM_LOG(channel, severity)
Log.
virtual MoFEMErrorCode modify_problem_mask_ref_level_set_bit(const std::string &name_problem, const BitRefLevel &bit)=0
set dof mask ref level for problem
virtual MoFEMErrorCode modify_problem_ref_level_set_bit(const std::string &name_problem, const BitRefLevel &bit)=0
set ref level for problem
auto bit
set bit
FTensor::Index< 'i', SPACE_DIM > i
double D
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
Definition Types.hpp:40
auto createKSP(MPI_Comm comm)
PetscErrorCode DMMoFEMSetDestroyProblem(DM dm, PetscBool destroy_problem)
Definition DMMoFEM.cpp:434
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
auto createDM(MPI_Comm comm, const std::string dm_type_name)
Creates smart DM object.
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
constexpr double t
plate stiffness
Definition plate.cpp:58
Rhs for mapping scalar fields with least squares.
Rhs for mapping symmetric tensor fields with least squares.
virtual MoFEMErrorCode build_adjacencies(const Range &ents, int verb=DEFAULT_VERBOSITY)=0
build adjacencies
virtual MPI_Comm & get_comm() const =0
Deprecated interface functions.
DofIdx getNbDofsRow() const
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
boost::shared_ptr< Range > newEls
MoFEMErrorCode operator()(ForcesAndSourcesCore *fe_raw_ptr, int order_row, int order_col, int order_data)
static std::map< long int, MatrixDouble > mapRefCoords
MoFEMErrorCode postProcess()
SmartPetscObj< DM > intermediateDM
MoFEMErrorCode removeDofs(Range elsToRemove, Range elsToAdd)
MoFEMErrorCode solveMap(SmartPetscObj< DM > &subDM, SmartPetscObj< DM > &intermediateDM, PetscInt numVecs, Vec vecsToMapFrom[], Vec vecsToMapTo[])
SolutionMapping(MoFEM::Interface &m_field)
boost::shared_ptr< DomainEle > feRhs
MoFEMErrorCode reSetUp(std::vector< std::string > fIelds, std::vector< int > oRders, BitRefLevel bIt)
MoFEMErrorCode setUp(SmartPetscObj< DM > &subDM, SmartPetscObj< DM > &intermediateDM, Range elsToAdd, Range elsToFlip)
MoFEM::Interface & m_field
boost::shared_ptr< DomainEle > feLhs
MoFEMErrorCode mapFields(SmartPetscObj< DM > &intermediateDM, Range elsToRemove=Range(), Range elsToAdd=Range(), Range elsToFlip=Range(), PetscInt numVecs=1, Vec vecsToMapFrom[]=PETSC_NULLPTR, Vec vecsToMapTo[]=PETSC_NULLPTR)
MoFEMErrorCode pushOperators(Range elsToFlip, Range elsToAdd, Vec vecIn=PETSC_NULLPTR)
SmartPetscObj< DM > subDM
constexpr AssemblyType AT
constexpr IntegrationType IT
PetscBool is_distributed_mesh
int geom_order
Order if fixed.
Definition plastic.cpp:141