Elastic mesh tie example with a tie-aware partitioned mesh loader.
for (
int d = 0;
d < max_dim; ++
d) {
CHKERR moab.get_adjacencies(ents, d,
false, adj, moab::Interface::UNION);
closure.merge(adj);
}
CHKERR moab.create_meshset(MESHSET_SET, meshset);
CHKERR moab.add_entities(meshset, closure);
}
Range physical_ents = ents.subset_by_type(MBTET);
physical_ents.merge(ents.subset_by_type(MBHEX));
return physical_ents;
}
triangle_faces.clear();
const auto prisms = ents.subset_by_type(MBPRISM);
if (!prisms.empty()) {
CHKERR moab.get_adjacencies(prisms, 2,
false, triangle_faces,
moab::Interface::UNION);
triangle_faces = triangle_faces.subset_by_type(MBTRI);
}
}
}
boost::shared_ptr<ElasticTie::CommonData>
tieData =
nullptr;
private:
};
CHKERR moab.load_file(file_name, 0,
"PARALLEL=BCAST;PARTITION=PARALLEL_PARTITION;");
if (pcomm == nullptr)
pcomm =
new ParallelComm(&moab, mf.
get_comm());
const auto rank = pcomm->rank();
Tag part_tag = pcomm->part_tag();
Range all_ents, tagged_sets, proc_ents, off_proc_ents;
CHKERR moab.get_entities_by_handle(0, all_ents,
false);
CHKERR moab.get_entities_by_type_and_tag(
0, MBENTITYSET, &part_tag, NULL, 1, tagged_sets,
moab::Interface::UNION);
for (auto meshset : tagged_sets) {
int part = -1;
CHKERR moab.tag_get_data(part_tag, &meshset, 1, &part);
CHKERR moab.get_entities_by_handle(meshset, meshset_ents,
true);
if (part == rank)
proc_ents.merge(meshset_ents);
else
off_proc_ents.merge(meshset_ents);
CHKERR moab.tag_clear_data(part_tag, meshset_ents, &part);
}
const auto all_volume_ents = all_ents.subset_by_dimension(3);
const auto proc_volume_ents = proc_ents.subset_by_dimension(3);
std::array<Range, 4> proc_ents_skin;
Skinner skin(&moab);
Range all_skin, proc_skin;
CHKERR skin.find_skin(0, all_volume_ents,
false, all_skin);
CHKERR skin.find_skin(0, proc_volume_ents,
false, proc_skin);
proc_ents_skin[2] = subtract(proc_skin, all_skin);
Range all_phys_skin, local_phys_faces, physical_boundary_faces;
CHKERR skin.find_skin(0, all_phys_ents.subset_by_dimension(3),
false,
all_phys_skin);
CHKERR moab.get_adjacencies(proc_phys_ents, 2,
false, local_phys_faces,
moab::Interface::UNION);
physical_boundary_faces = intersect(all_phys_skin, local_phys_faces);
if (!physical_boundary_faces.empty()) {
CHKERR moab.tag_clear_data(pcomm->partition_tag(), physical_boundary_faces,
&rank);
}
proc_ents_skin[2].merge(physical_boundary_faces);
Range prism_triangle_faces;
proc_ents_skin[2].merge(prism_triangle_faces);
CHKERR moab.get_adjacencies(proc_ents_skin[2], 1,
false,
proc_ents_skin[1],
moab::Interface::UNION);
CHKERR moab.get_connectivity(proc_ents_skin[2], proc_ents_skin[0],
false);
auto to_remove = off_proc_ents;
for (
int d = 2;
d >= 0; --
d)
to_remove = subtract(to_remove, proc_ents_skin[d]);
CHKERR moab.get_entities_by_type(0, MBENTITYSET, all_meshsets,
true);
for (auto meshset : all_meshsets)
CHKERR moab.remove_entities(meshset, to_remove);
for (
int d = 3;
d > 0; --
d) {
Range ents = to_remove.subset_by_dimension(d);
if (!ents.empty())
CHKERR moab.delete_entities(ents);
}
CHKERR pcomm->resolve_shared_ents(0, proc_ents, 3, -1,
proc_ents_skin.data());
};
} else {
}
}
CHKERR meshset_mng->setMeshsetFromFile();
}
enum bases { AINSWORTH, DEMKOWICZ, LASBASETOPT };
const char *list_bases[LASBASETOPT] = {"ainsworth", "demkowicz"};
PetscInt choice_base_value = AINSWORTH;
LASBASETOPT, &choice_base_value, PETSC_NULLPTR);
switch (choice_base_value) {
case AINSWORTH:
break;
case DEMKOWICZ:
break;
default:
break;
}
domain_ents, true);
if (!tet_hex_ents.empty()) {
domain_meshset);
simple->getMeshset() = domain_meshset;
CHKERR skin.find_skin(0, tet_hex_ents,
false, local_skin);
} else {
CHKERR skin.find_skin(0, tet_hex_ents,
false, boundary_faces);
}
simple->getBoundaryMeshSet() = boundary_meshset;
}
}
}
}
}
auto norm_fe = boost::make_shared<DomainEle>(
mField);
};
norm_fe->getOpPtrVector(), {H1}, "GEOMETRY");
auto common_ptr = HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEle>(
mField, norm_fe->getOpPtrVector(),
"U",
"MAT_ELASTIC", Sev::verbose);
auto exact_stress_ptr = boost::make_shared<MatrixDouble>();
constexpr double uniaxial_stress_xx = 1e3 * 0.3 / 3.0;
stress.clear();
t_stress(0, 0) = uniaxial_stress_xx;
return stress;
};
lame_solution(0.5, 1.0, 2.0, 1.0, 1e3, 0.3);
auto lame_stress = [&lame_solution](const double x, const double y,
const double z) {
return lame_solution.stress(x, y, z);
};
norm_fe->getOpPtrVector().push_back(
exact_stress_ptr, stress_func));
enum Norms { STRESS_ERROR_L2 = 0, STRESS_EXACT_L2, LAST_NORM };
auto norms_vec =
LAST_NORM);
CHKERR VecZeroEntries(norms_vec);
norm_fe->getOpPtrVector().push_back(
exact_stress_ptr, norms_vec, STRESS_EXACT_L2));
norm_fe->getOpPtrVector().push_back(
common_ptr->getMatCauchyStress(), norms_vec, STRESS_ERROR_L2,
exact_stress_ptr));
norm_fe);
CHKERR VecAssemblyBegin(norms_vec);
CHKERR VecAssemblyEnd(norms_vec);
const double *norms;
CHKERR VecGetArrayRead(norms_vec, &norms);
const double error_l2 = std::sqrt(norms[STRESS_ERROR_L2]);
const double exact_l2 = std::sqrt(norms[STRESS_EXACT_L2]);
MOFEM_LOG_C(
"WORLD", Sev::inform,
"STRESS_ERROR_L2 = %.16e\n", error_l2);
MOFEM_LOG_C(
"WORLD", Sev::inform,
"STRESS_EXACT_L2 = %.16e\n", exact_l2);
CHKERR VecRestoreArrayRead(norms_vec, &norms);
double max_error_l2 = 1e-2;
&max_error_l2, PETSC_NULLPTR);
if (error_l2 >= max_error_l2) {
"Stress L2 error %.16e exceeds tolerance %.16e", error_l2,
max_error_l2);
}
}
}
int test = 0;
if (test == 10 || test == 11)
}
static char help[] =
"...\n\n";
int main(
int argc,
char *argv[]) {
const char param_file[] = "param_file.petsc";
MeshsetsManager::broadcastMeshsetsOn = false;
auto core_log = logging::core::get();
core_log->add_sink(
LogManager::createSink(LogManager::getStrmWorld(), "TIMER"));
core_log->add_sink(
LogManager::createSink(LogManager::getStrmSync(), "FieldEvaluator"));
LogManager::setLog("FieldEvaluator");
try {
DMType dm_name = "DMMOFEM";
DMType dm_name_mg = "DMMOFEM_MG";
moab::Core mb_instance;
moab::Interface &moab = mb_instance;
}
}
Implementation of elastic example class.
TIE constraint support for the elastic tutorial.
#define MOFEM_LOG_C(channel, severity, format,...)
void simple(double P1[], double P2[], double P3[], double c[], const int N)
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
#define CATCH_ERRORS
Catch errors.
FieldApproximationBase
approximation base
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
#define MYPCOMM_INDEX
default communicator number PCOMM
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
MoFEMErrorCode DMRegister_MGViaApproxOrders(const char sname[])
Register DM for Multi-Grid via approximation orders.
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
Range getPhysicalVolumeEntities(const Range &ents)
MoFEMErrorCode initializeTieConstraints(MoFEM::Interface &mField, boost::shared_ptr< CommonData > &tie_data, const std::string &field_name, FieldApproximationBase base, int order)
MoFEMErrorCode getPrismTriangleFaces(moab::Interface &moab, const Range &ents, Range &triangle_faces)
MoFEMErrorCode logTieDisplacementNorms(MoFEM::Interface &mField, const boost::shared_ptr< CommonData > &tie_data, const std::string &field_name)
MoFEMErrorCode makeClosureMeshset(moab::Interface &moab, const Range &ents, const int max_dim, EntityHandle &meshset)
MoFEMErrorCode setupTieSolver(MoFEM::Interface &mField, boost::shared_ptr< CommonData > tie_data, SmartPetscObj< KSP > solver)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
UBlasMatrix< double > MatrixDouble
implementation of Data Operators for Forces and Sources
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
PetscErrorCode PetscOptionsGetReal(PetscOptions *, const char pre[], const char name[], PetscReal *dval, PetscBool *set)
static auto getFTensor2SymmetricFromMat(M &data)
Get symmetric tensor rank 2 (matrix) form data matrix.
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
boost::function< MatrixDouble(const double, const double, const double)> MatrixFunc
PetscErrorCode PetscOptionsGetEList(PetscOptions *, const char pre[], const char name[], const char *const *list, PetscInt next, PetscInt *value, PetscBool *set)
constexpr IntegrationType I
static constexpr int approx_order
Lamé analytical solution for a hollow cylinder under radial pressure with a linear isotropic Hooke ma...
Boundary conditions marker.
virtual MoFEMErrorCode setupProblem()
[Read mesh]
virtual MoFEMErrorCode kspSetUpAndSolve(SmartPetscObj< KSP > solver)
MoFEM::Interface & mField
ElasticExample(MoFEM::Interface &m_field)
MoFEMErrorCode readMesh() override
[Run problem]
MoFEMErrorCode setupProblem() override
[Read mesh]
boost::shared_ptr< ElasticTie::CommonData > tieData
MoFEMErrorCode checkStressError(const int test)
MoFEMErrorCode checkResults() override
[Postprocess results]
MoFEMErrorCode setUpSolver(SmartPetscObj< KSP > solver) override
[Push operators to pipeline]
Range physicalBoundaryFaces
MoFEMErrorCode kspSetUpAndSolve(SmartPetscObj< KSP > solver) override
virtual int get_comm_size() const =0
virtual moab::Interface & get_moab()=0
virtual MPI_Comm & get_comm() const =0
virtual int get_comm_rank() const =0
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Deprecated interface functions.
Data on single entity (This is passed as argument to DataOperator::doWork)
Interface for managing meshsets containing materials and boundary conditions.
Get norm of input MatrixDouble for symmetric Tensor2.
Get values from matrix function in symmetric tensor storage at integration points and save them to Ma...
Template struct for dimension-specific finite element types.
Simple interface for fast problem set-up.
intrusive_ptr for managing petsc objects
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
NaturalBC< BoundaryEleOp >::Assembly< AT >::BiLinearForm< IT > BoundaryLhsBCs
NaturalBC< BoundaryEleOp >::Assembly< AT >::LinearForm< IT > BoundaryRhsBCs
#define EXECUTABLE_DIMENSION
BoundaryLhsBCs::OpFlux< PlasticOps::BoundaryBCs, 1, SPACE_DIM > OpBoundaryLhsBCs
NaturalBC< DomainEleOp >::Assembly< AT >::LinearForm< IT > DomainRhsBCs
DomainRhsBCs::OpFlux< PlasticOps::DomainBCs, 1, SPACE_DIM > OpDomainRhsBCs
BoundaryRhsBCs::OpFlux< PlasticOps::BoundaryBCs, 1, SPACE_DIM > OpBoundaryRhsBCs
ElementsAndOps< SPACE_DIM >::SideEle SideEle