#include <algorithm>
#include <limits>
#include <ArcLengthTools.hpp>
#include <HookeOps.hpp>
using namespace boost::numeric;
-my_file mesh file name\n\
-my_sr reduction of step size\n\
-my_its_d desired number of steps\n\
-my_ms maximal number of steps\n\
-gamma arc-length step adaptation exponent\n\
-min_arc_length_step minimum arc-length step\n\
-max_arc_length_step maximum arc-length step\n\
-field_eval_coords x,y,z coordinates where displacement and stress are evaluated\n\n";
struct AssembleRhsVectors :
public FEMethod {
boost::shared_ptr<ArcLengthCtx>
arcPtr;
AssembleRhsVectors(boost::shared_ptr<ArcLengthCtx> &arc_ptr)
} break;
CHKERR VecGhostUpdateBegin(
snes_f, INSERT_VALUES, SCATTER_FORWARD);
CHKERR VecGhostUpdateEnd(
snes_f, INSERT_VALUES, SCATTER_FORWARD);
} break;
default:
}
}
} break;
CHKERR VecGhostUpdateBegin(
snes_f, ADD_VALUES, SCATTER_REVERSE);
CHKERR VecGhostUpdateEnd(
snes_f, ADD_VALUES, SCATTER_REVERSE);
MOFEM_LOG_C(
"ARC_LENGTH", Sev::inform,
"\tlambda = %6.4e",
double fnorm;
MOFEM_LOG_C(
"ARC_LENGTH", Sev::inform,
"\tpre-essential fnorm = %6.4e",
fnorm);
}
} break;
default:
}
}
};
}
protected:
boost::shared_ptr<MoFEM::Core>
corePtr;
boost::ptr_vector<CohesiveInterfaceElement::PhysicalEquation>
boost::shared_ptr<ArcLengthCtx>
arcCtx;
boost::scoped_ptr<ArcLengthMatShell>
matCtx;
boost::scoped_ptr<PCArcLengthCtx>
pcCtx;
boost::shared_ptr<FieldEvaluatorInterface::SetPtsData>
fieldEvalData;
};
}
CHKERR JsonConfigManager::setMeshFileFromJson();
PetscBool flg = PETSC_TRUE;
char mesh_file_name[PETSC_MAX_PATH_LEN] = "";
mesh_file_name, sizeof(mesh_file_name), &flg);
if (flg != PETSC_TRUE) {
mesh_file_name, sizeof(mesh_file_name), &flg);
if (flg != PETSC_TRUE)
"*** ERROR -my_file or -file_name (MESH FILE NEEDED)");
}
const char *option;
option = "";
Tag th_step_size, th_step;
double def_step_size = 1;
rval =
mOab.tag_get_handle(
"_STEPSIZE", 1, MB_TYPE_DOUBLE, th_step_size,
MB_TAG_CREAT | MB_TAG_MESH, &def_step_size);
if (
rval == MB_ALREADY_ALLOCATED)
int def_step = 1;
rval =
mOab.tag_get_handle(
"_STEP", 1, MB_TYPE_INTEGER, th_step,
MB_TAG_CREAT | MB_TAG_MESH, &def_step);
if (
rval == MB_ALREADY_ALLOCATED)
const void *tag_data_step_size[1];
EntityHandle root = 0;
CHKERR mOab.tag_get_by_ptr(th_step_size, &root, 1, tag_data_step_size);
double &step_size = *(double *)tag_data_step_size[0];
const void *tag_data_step[1];
CHKERR mOab.tag_get_by_ptr(th_step, &root, 1, tag_data_step);
int &step = *(int *)tag_data_step[0];
MOFEM_LOG_C(
"ARC_LENGTH", Sev::inform,
"Start step %d and step_size = %6.4e",
step, step_size);
}
PetscBool flg = PETSC_FALSE;
if (flg != PETSC_TRUE) {
}
&flg);
if (flg != PETSC_TRUE) {
}
&flg);
if (flg != PETSC_TRUE) {
}
&flg);
if (flg != PETSC_TRUE) {
}
CHKERR m_field.get_moab().tag_get_handle(
"_MY_REFINEMENT_LEVEL",
sizeof(
BitRefLevel), MB_TYPE_OPAQUE,
th_my_ref_level, MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_BYTES,
&def_bit_level);
const EntityHandle root_meshset = m_field.get_moab().get_root_set();
CHKERR m_field.get_moab().tag_get_by_ptr(th_my_ref_level, &root_meshset, 1,
(const void **)&ptr_bit_level0);
if (step == 1) {
std::vector<BitRefLevel> bit_levels;
int ll = 1;
auto split_interface = [&](const EntityHandle cubit_meshset,
MOFEM_LOG_C(
"ARC_LENGTH", Sev::inform,
"Insert Interface %d", meshset_id);
{
EntityHandle ref_level_meshset = 0;
CHKERR mOab.create_meshset(MESHSET_SET, ref_level_meshset);
->getEntitiesByTypeAndRefLevel(bit_levels.back(),
ref_level_meshset);
->getEntitiesByTypeAndRefLevel(bit_levels.back(),
ref_level_meshset);
CHKERR mOab.get_entities_by_handle(ref_level_meshset, ref_level_tets,
true);
CHKERR interface_ptr->
getSides(cubit_meshset, bit_levels.back(),
true,
0);
cubit_meshset, true, true, 0);
CHKERR mOab.delete_entities(&ref_level_meshset, 1);
}
EntityHandle cubit_meshset = ciit->meshset;
->updateMeshsetByEntitiesChildren(cubit_meshset, bit_levels.back(),
cubit_meshset, MBMAXTYPE, true);
}
};
std::set<int> split_interface_ids;
bool split_from_sideset = false;
if (split_interface_ids.insert(cit->getMeshsetId()).second) {
CHKERR split_interface(cit->getMeshset(), cit->getMeshsetId());
split_from_sideset = true;
}
}
if (!split_from_sideset) {
const std::string block_name = "MAT_INTERF";
std::regex((boost::format(
"%s(.*)") % block_name).str()))) {
if (split_interface_ids.insert(
m->getMeshsetId()).second)
CHKERR split_interface(
m->getMeshset(),
m->getMeshsetId());
}
}
bit_level0 = bit_levels.back();
problem_bit_level = bit_level0;
CHKERR m_field.add_finite_element(
"ELASTIC");
CHKERR m_field.modify_finite_element_add_field_row(
"ELASTIC",
"DISPLACEMENT");
CHKERR m_field.modify_finite_element_add_field_col(
"ELASTIC",
"DISPLACEMENT");
CHKERR m_field.modify_finite_element_add_field_data(
"ELASTIC",
"DISPLACEMENT");
m_field.modify_finite_element_add_field_data("ELASTIC", "GEOMETRY");
CHKERR m_field.modify_finite_element_add_field_row(
"ELASTIC",
"LAMBDA");
CHKERR m_field.modify_finite_element_add_field_col(
"ELASTIC",
"LAMBDA");
CHKERR m_field.modify_finite_element_add_field_data(
"ELASTIC",
"LAMBDA");
CHKERR m_field.add_finite_element(
"INTERFACE");
CHKERR m_field.modify_finite_element_add_field_row(
"INTERFACE",
"DISPLACEMENT");
CHKERR m_field.modify_finite_element_add_field_col(
"INTERFACE",
"DISPLACEMENT");
CHKERR m_field.modify_finite_element_add_field_data(
"INTERFACE",
"DISPLACEMENT");
m_field.modify_finite_element_add_field_data("INTERFACE", "GEOMETRY");
CHKERR m_field.add_finite_element(
"ARC_LENGTH");
CHKERR m_field.modify_finite_element_add_field_row(
"ARC_LENGTH",
"LAMBDA");
CHKERR m_field.modify_finite_element_add_field_col(
"ARC_LENGTH",
"LAMBDA");
m_field.modify_finite_element_add_field_data("ARC_LENGTH", "LAMBDA");
CHKERR m_field.add_problem(
"ELASTIC_MECHANICS");
CHKERR m_field.modify_problem_add_finite_element(
"ELASTIC_MECHANICS",
"ELASTIC");
CHKERR m_field.modify_problem_add_finite_element(
"ELASTIC_MECHANICS",
"INTERFACE");
CHKERR m_field.modify_problem_add_finite_element(
"ELASTIC_MECHANICS",
"ARC_LENGTH");
CHKERR m_field.modify_problem_ref_level_add_bit(
"ELASTIC_MECHANICS",
problem_bit_level);
CHKERR m_field.add_ents_to_field_by_type(0, MBTET,
"DISPLACEMENT");
CHKERR m_field.add_ents_to_field_by_type(0, MBTET,
"X0_DISPLACEMENT");
CHKERR m_field.add_ents_to_field_by_type(0, MBTET,
"GEOMETRY");
CHKERR m_field.add_ents_to_finite_element_by_bit_ref(
problem_bit_level,
BitRefLevel().set(),
"ELASTIC", MBTET);
CHKERR m_field.add_ents_to_finite_element_by_bit_ref(
problem_bit_level,
BitRefLevel().set(),
"INTERFACE", MBPRISM);
{
EntityHandle no_field_vertex;
{
const double coords[] = {0, 0, 0};
CHKERR m_field.get_moab().create_vertex(coords, no_field_vertex);
Range range_no_field_vertex;
range_no_field_vertex.insert(no_field_vertex);
EntityHandle lambda_meshset = m_field.get_field_meshset("LAMBDA");
CHKERR m_field.get_moab().add_entities(lambda_meshset,
range_no_field_vertex);
}
EntityHandle meshset_fe_arc_length;
{
CHKERR mOab.create_meshset(MESHSET_SET, meshset_fe_arc_length);
CHKERR mOab.add_entities(meshset_fe_arc_length, &no_field_vertex, 1);
}
CHKERR m_field.add_ents_to_finite_element_by_MESHSET(
meshset_fe_arc_length, "ARC_LENGTH", false);
}
CHKERR m_field.set_field_order(0, MBTET,
"DISPLACEMENT",
order);
CHKERR m_field.set_field_order(0, MBTRI,
"DISPLACEMENT",
order);
CHKERR m_field.set_field_order(0, MBEDGE,
"DISPLACEMENT",
order);
CHKERR m_field.set_field_order(0, MBVERTEX,
"DISPLACEMENT", 1);
CHKERR m_field.set_field_order(0, MBTET,
"X0_DISPLACEMENT",
order);
CHKERR m_field.set_field_order(0, MBTRI,
"X0_DISPLACEMENT",
order);
CHKERR m_field.set_field_order(0, MBEDGE,
"X0_DISPLACEMENT",
order);
CHKERR m_field.set_field_order(0, MBVERTEX,
"X0_DISPLACEMENT", 1);
CHKERR m_field.set_field_order(0, MBTET,
"GEOMETRY", 2);
CHKERR m_field.set_field_order(0, MBTRI,
"GEOMETRY", 2);
CHKERR m_field.set_field_order(0, MBEDGE,
"GEOMETRY", 2);
CHKERR m_field.set_field_order(0, MBVERTEX,
"GEOMETRY", 1);
}
"DISPLACEMENT");
"DISPLACEMENT");
"DISPLACEMENT");
"GEOMETRY");
CHKERR m_field.modify_problem_add_finite_element(
"ELASTIC_MECHANICS",
CHKERR mOab.get_entities_by_type(
m->getMeshset(), MBTRI, natural_bc_faces,
true);
}
CHKERR mOab.get_entities_by_type(
m->getMeshset(), MBTRI, natural_bc_faces,
true);
}
for (
auto m : meshsets_manager->getCubitMeshsetPtr(
std::regex(
"(FORCE|PRESSURE)(.*)"))) {
CHKERR mOab.get_entities_by_type(
m->getMeshset(), MBTRI, natural_bc_faces,
true);
}
CHKERR m_field.add_ents_to_finite_element_by_type(natural_bc_faces, MBTRI,
}
CHKERR m_field.build_fields();
CHKERR m_field.loop_dofs(
"GEOMETRY", ent_method_material);
CHKERR m_field.build_finite_elements();
CHKERR m_field.build_adjacencies(problem_bit_level);
m_field.get_comm_size());
}
"ELASTIC_MECHANICS", "DISPLACEMENT");
CHKERR mmanager_ptr->printDisplacementSet();
CHKERR mmanager_ptr->printForceSet();
CHKERR mmanager_ptr->printMaterialsSet();
}
->createMPIAIJWithArrays<PetscGlobalIdx_mi_tag>(
"ELASTIC_MECHANICS",
aij);
const std::string interface_block_name = "MAT_INTERF";
for (
auto m : meshsets_manager->getCubitMeshsetPtr(
std::regex(
(boost::format("%s(.*)") % interface_block_name).str()))) {
CHKERR m->getAttributeDataStructure(mydata);
MOFEM_LOG(
"ARC_LENGTH", Sev::inform) << mydata;
EntityHandle meshset =
m->getMeshset();
CHKERR mOab.get_entities_by_type(meshset, MBTRI, tris,
true);
CHKERR mOab.get_adjacencies(tris, 3,
false, ents3d, moab::Interface::UNION);
}
arcCtx = boost::make_shared<ArcLengthCtx>(m_field,
"ELASTIC_MECHANICS");
boost::make_shared<ArcLengthIntElemFEMethod>(m_field.get_moab(),
arcCtx);
snesCtxPtr = boost::make_shared<ArcLengthSnesCtx>(
m_field,
"ELASTIC_MECHANICS",
arcCtx);
auto essential_pre_proc_zero_rhs = boost::make_shared<FEMethod>();
auto essential_pre_proc_lhs = boost::make_shared<FEMethod>();
auto essential_post_proc_rhs = boost::make_shared<FEMethod>();
auto essential_post_proc_lhs = boost::make_shared<FEMethod>();
boost::shared_ptr<ArcLengthCtx> arcCtx;
ArcScale(boost::shared_ptr<ArcLengthCtx> arc_ctx) : arcCtx(arc_ctx) {}
double getScale(const double time) override {
return arcCtx->getFieldData();
}
};
auto arc_scale = boost::make_shared<ArcScale>(
arcCtx);
double getScale(const double time) override {
return 0.0;
}
};
auto arc_zero = boost::make_shared<ArcZero>();
auto get_essential_pre_proc_zero =
[&m_field, essential_pre_proc_zero_rhs, arc_zero]() {
m_field, essential_pre_proc_zero_rhs, {arc_zero});
};
essential_pre_proc_zero_rhs->preProcessHook =
get_essential_pre_proc_zero();
auto get_essential_pre_proc_lhs =
[&m_field, essential_pre_proc_lhs, arc_scale]() {
m_field, essential_pre_proc_lhs, {arc_scale});
};
essential_pre_proc_lhs->preProcessHook = get_essential_pre_proc_lhs();
essential_post_proc_rhs->postProcessHook =
[&m_field, essential_post_proc_rhs, arc_scale]() {
m_field, essential_post_proc_rhs, {arc_scale})();
m_field, essential_post_proc_rhs, 1.)();
};
essential_post_proc_lhs->postProcessHook =
m_field, essential_post_proc_lhs, 1.);
};
CHKERR HookeOps::opFactoryDomainRhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
m_field,
elasticRhsFe->getOpPtrVector(),
"DISPLACEMENT",
"MAT_ELASTIC",
Sev::verbose, true);
CHKERR HookeOps::opFactoryDomainLhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
m_field,
elasticLhsFe->getOpPtrVector(),
"DISPLACEMENT",
"MAT_ELASTIC",
Sev::verbose);
Mat shell_aij;
&shell_aij);
naturalBcFe = boost::make_shared<BoundaryEle>(m_field);
};
"GEOMETRY");
CHKERR BoundaryRhsBCs::AddFluxToPipeline<OpBoundaryRhsBCs>::add(
naturalBcFe->getOpPtrVector(), m_field,
"DISPLACEMENT", Sev::inform);
CHKERR SNESSetApplicationContext(
snes, &snes_ctx);
KSP ksp;
PC pc;
CHKERR PCSetType(pc, PCSHELL);
snes_ctx.getPreProcComputeRhs().push_back(essential_pre_proc_zero_rhs);
snes_ctx.getPreProcComputeRhs().push_back(&pre_post_proc_fe);
loops_to_do_Rhs.push_back(
loops_to_do_Rhs.push_back(
loops_to_do_Rhs.push_back(
snes_ctx.getPostProcComputeRhs().push_back(&pre_post_proc_fe);
snes_ctx.getPostProcComputeRhs().push_back(essential_post_proc_rhs);
snes_ctx.getPreProcSetOperators().push_back(essential_pre_proc_lhs);
loops_to_do_Mat.push_back(
loops_to_do_Mat.push_back(
loops_to_do_Mat.push_back(
snes_ctx.getPostProcSetOperators().push_back(essential_post_proc_lhs);
if (step == 1) {
} else {
step++;
}
auto f_lambda_on_essential_bc = boost::make_shared<FEMethod>();
f_lambda_on_essential_bc->preProcessHook =
m_field, f_lambda_on_essential_bc, {}, false);
f_lambda_on_essential_bc->postProcessHook =
m_field, f_lambda_on_essential_bc, -1.,
arcCtx->F_lambda);
CHKERR VecGhostUpdateBegin(
arcCtx->F_lambda, INSERT_VALUES, SCATTER_FORWARD);
CHKERR VecGhostUpdateEnd(
arcCtx->F_lambda, INSERT_VALUES, SCATTER_FORWARD);
CHKERR m_field.problem_basic_method_preProcess(
"ELASTIC_MECHANICS",
*f_lambda_on_essential_bc);
CHKERR m_field.loop_finite_elements(
"ELASTIC_MECHANICS",
"ELASTIC",
CHKERR m_field.problem_basic_method_postProcess(
"ELASTIC_MECHANICS",
*f_lambda_on_essential_bc);
CHKERR VecGhostUpdateBegin(
arcCtx->F_lambda, ADD_VALUES, SCATTER_REVERSE);
CHKERR VecGhostUpdateEnd(
arcCtx->F_lambda, ADD_VALUES, SCATTER_REVERSE);
MOFEM_LOG_C(
"ARC_LENGTH", Sev::inform,
"\tFlambda2 = %6.4e",
if (step > 1) {
"ELASTIC_MECHANICS",
COL,
d, INSERT_VALUES, SCATTER_FORWARD);
"ELASTIC_MECHANICS",
"DISPLACEMENT",
"X0_DISPLACEMENT",
COL,
arcCtx->x0,
INSERT_VALUES, SCATTER_FORWARD);
double x0_nrm;
"\tRead x0_nrm = %6.4e dlambda = %6.4e", x0_nrm,
} else {
}
postProcPtr = boost::make_shared<PostProcEle>(m_field);
auto disp_ptr = boost::make_shared<MatrixDouble>();
post_proc.getOpPtrVector(), {H1}, "GEOMETRY");
auto hooke_common_ptr =
HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
m_field, post_proc.getOpPtrVector(), "DISPLACEMENT", "MAT_ELASTIC",
Sev::verbose);
post_proc.getOpPtrVector().push_back(
post_proc.getOpPtrVector().push_back(
new OpPPMap(post_proc.getPostProcMesh(), post_proc.getMapGaussPts(), {},
{{"DISPLACEMENT", disp_ptr}},
{{"DISPLACEMENT_GRAD", hooke_common_ptr->matGradPtr}},
{{"STRAIN", hooke_common_ptr->getMatStrain()},
{"STRESS", hooke_common_ptr->getMatCauchyStress()}}));
"-field_eval_coords", fieldEvalCoords.data(),
"-field_eval_coords requires exactly three coordinates");
fieldEvalData =
->buildTree<SPACE_DIM>(fieldEvalData, "ELASTIC");
fieldEvalData->setEvalPoints(fieldEvalCoords.data(), 1);
auto field_eval_fe = fieldEvalData->feMethodPtr;
field_eval_fe->getRuleHook = [](
int,
int,
int) {
return -1; };
field_eval_fe->getOpPtrVector(), {H1}, "GEOMETRY");
auto field_eval_hooke_common_ptr =
HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
m_field, field_eval_fe->getOpPtrVector(), "DISPLACEMENT",
"MAT_ELASTIC", Sev::verbose);
fieldEvalStressPtr = field_eval_hooke_common_ptr->getMatCauchyStress();
fieldEvalDispPtr = boost::make_shared<MatrixDouble>();
field_eval_fe->getOpPtrVector().push_back(
fieldEvalDispPtr));
}
}
->evalFEAtThePoint<SPACE_DIM>(
int global_point_found = 0;
MPI_Allreduce(&point_found, &global_point_found, 1, MPI_INT, MPI_SUM,
m_field.get_comm());
if (point_found) {
"FieldEvaluator step %d lambda %6.4e point [%6.4e, %6.4e, "
"%6.4e]",
"FieldEvaluator displacement [Ux, Uy, Uz] = [%6.4e, "
"%6.4e, %6.4e]",
t_disp(0), t_disp(1), t_disp(2));
"FieldEvaluator Cauchy stress [Sxx, Syy, Szz, Sxy, Syz, Sxz] "
"= [%6.4e, %6.4e, %6.4e, %6.4e, %6.4e, %6.4e]",
t_stress(0, 0), t_stress(1, 1), t_stress(2, 2), t_stress(0, 1),
t_stress(1, 2), t_stress(0, 2));
} else if (!global_point_found && !m_field.get_comm_rank()) {
"FieldEvaluator did not find point [%6.4e, %6.4e, %6.4e] in "
"the ELASTIC domain",
}
}
double min_arc_length_step = std::numeric_limits<double>::epsilon();
double max_arc_length_step = std::numeric_limits<double>::max();
PETSC_NULLPTR);
"-min_arc_length_step", &min_arc_length_step,
PETSC_NULLPTR);
"-max_arc_length_step", &max_arc_length_step,
PETSC_NULLPTR);
if (min_arc_length_step <= 0.)
"-min_arc_length_step must be positive");
if (max_arc_length_step <= 0.)
"-max_arc_length_step must be positive");
if (min_arc_length_step > max_arc_length_step)
"-min_arc_length_step must not exceed -max_arc_length_step");
bool converged_state = false;
if (step == 1) {
MOFEM_LOG_C(
"ARC_LENGTH", Sev::inform,
"Load Step %d step_size = %6.4e",
step, step_size);
double dlambda;
} else if (step == 2) {
double dlambda =
arcCtx->dLambda;
double dx_nrm;
"Load Step %d step_size = %6.4e dlambda0 = %6.4e "
"dx_nrm = %6.4e dx2 = %6.4e",
step, step_size, dlambda, dx_nrm,
arcCtx->dx2);
} else {
double dx_nrm;
"Load Step %d step_size = %6.4e dlambda0 = %6.4e "
"dx_nrm = %6.4e dx2 = %6.4e",
step, step_size, dlambda, dx_nrm,
arcCtx->dx2);
}
"ELASTIC_MECHANICS",
COL,
d, INSERT_VALUES, SCATTER_REVERSE);
CHKERR m_field.loop_finite_elements(
"ELASTIC_MECHANICS",
"INTERFACE",
cohesive_elements.getFeHistory(), 0,
m_field.get_comm_size());
int its;
MOFEM_LOG_C(
"ARC_LENGTH", Sev::inform,
"number of Newton iterations = %d",
its);
SNESConvergedReason reason;
if (reason < 0) {
converged_state = false;
continue;
} else {
if (step > 1 && converged_state) {
std::clamp(
reduction, min_arc_length_step / std::abs(step_size),
max_arc_length_step / std::abs(step_size));
MOFEM_LOG_C(
"ARC_LENGTH", Sev::inform,
"reduction step_size = %6.4e",
}
"ELASTIC_MECHANICS",
COL,
d, INSERT_VALUES, SCATTER_REVERSE);
"ELASTIC_MECHANICS",
"DISPLACEMENT",
"X0_DISPLACEMENT",
COL,
arcCtx->x0, INSERT_VALUES, SCATTER_REVERSE);
converged_state = true;
}
if (reason > 0) {
}
if (step % 1 == 0) {
CHKERR m_field.loop_finite_elements(
"ELASTIC_MECHANICS",
"ELASTIC",
post_proc);
std::ostringstream ss;
ss << "out_values_" << step << ".h5m";
CHKERR post_proc.writeFile(ss.str().c_str());
}
}
}
}
}
int main(
int argc,
char *argv[]) {
const string default_options = "-ksp_type fgmres \n"
"-pc_type lu \n"
"-pc_factor_mat_solver_type mumps\n"
"-mat_mumps_icntl_20 0\n"
"-ksp_monitor \n"
"-ksp_atol 1e-10 \n"
"-ksp_rtol 1e-10 \n"
"-snes_monitor \n"
"-snes_type newtonls \n"
"-snes_linesearch_type l2 \n"
"-snes_linesearch_monitor \n"
"-snes_max_it 16 \n"
"-snes_atol 1e-8 \n"
"-snes_rtol 1e-8 \n"
"-snes_converged_reason \n";
string param_file = "param_file.petsc";
if (!static_cast<bool>(ifstream(param_file))) {
std::ofstream
file(param_file.c_str(), std::ios::ate);
}
}
auto core_log = logging::core::get();
core_log->add_sink(
LogManager::createSink(LogManager::getStrmWorld(), "ARC_LENGTH"));
LogManager::setLog("ARC_LENGTH");
try {
moab::Core mb_instance;
moab::Interface &moab = mb_instance;
}
return 0;
}
Implementation of linear interface element.
Natural force and pressure boundary conditions.
Implementation of arc-length control for cohesive elements.
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
#define MOFEM_LOG_C(channel, severity, format,...)
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ NOFIELD
scalar or vector of scalars describe (no true field)
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
#define _IT_CUBITMESHSETS_BY_BCDATA_TYPE_FOR_LOOP_(MESHSET_MANAGER, CUBITBCTYPE, IT)
Iterator that loops over a specific Cubit MeshSet in a moFEM field.
#define _IT_CUBITMESHSETS_FOR_LOOP_(MESHSET_MANAGER, IT)
Iterator that loops over all the Cubit MeshSets in a moFEM field.
MoFEMErrorCode partitionGhostDofs(const std::string name, int verb=VERBOSE)
determine ghost nodes
MoFEMErrorCode buildProblem(const std::string name, const bool square_matrix, int verb=VERBOSE)
build problem data structures
MoFEMErrorCode partitionProblem(const std::string name, int verb=VERBOSE)
partition problem dofs (collective)
MoFEMErrorCode partitionFiniteElements(const std::string name, bool part_from_moab=false, int low_proc=-1, int hi_proc=-1, int verb=VERBOSE)
partition finite elements
MoFEMErrorCode pushMarkDOFsOnEntities(const std::string problem_name, const std::string block_name, const std::string field_name, int lo, int hi, bool get_low_dim_ents=true)
Mark DOFs on block entities for boundary conditions.
const double n
refractive index of diffusive medium
const FTensor::Tensor2< T, Dim, Dim > Vec
static MoFEMErrorCodeGeneric< moab::ErrorCode > rval
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
std::bitset< BITREFLEVEL_SIZE > BitRefLevel
Bit structure attached to each entity identifying to what mesh entity is attached.
implementation of Data Operators for Forces and Sources
auto createSNES(MPI_Comm comm)
PetscErrorCode SnesMat(SNES snes, Vec x, Mat A, Mat B, void *ctx)
This is MoFEM implementation for the left hand side (tangent matrix) evaluation in SNES solver.
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)
PetscErrorCode SnesRhs(SNES snes, Vec x, Vec f, void *ctx)
This is MoFEM implementation for the right hand side (residual vector) evaluation in SNES solver.
SmartPetscObj< Vec > vectorDuplicate(Vec vec)
Create duplicate vector of smart vector.
PetscErrorCode PetscOptionsGetRealArray(PetscOptions *, const char pre[], const char name[], PetscReal dval[], PetscInt *nmax, PetscBool *set)
PetscErrorCode PetscOptionsGetString(PetscOptions *, const char pre[], const char name[], char str[], size_t size, PetscBool *set)
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
static constexpr int approx_order
FTensor::Index< 'm', 3 > m
MoFEMErrorCode boundaryCondition()
[Set up problem]
boost::shared_ptr< ArcLengthIntElemFEMethod > arcMethodPtr
MoFEM::Interface * mField
MoFEMErrorCode checkResults()
[Postprocess results]
MoFEMErrorCode readMesh()
[Run problem]
boost::shared_ptr< MatrixDouble > fieldEvalStressPtr
boost::ptr_vector< CohesiveInterfaceElement::PhysicalEquation > interfaceMaterials
boost::scoped_ptr< PCArcLengthCtx > pcCtx
SmartPetscObj< Mat > shellAij
boost::shared_ptr< MoFEM::Core > corePtr
boost::shared_ptr< PostProcEle > postProcPtr
PetscScalar stepSizeReduction
boost::shared_ptr< CohesiveInterfaceElement > cohesiveElementsPtr
const std::string naturalBcFeName
SmartPetscObj< SNES > snes
MoFEMErrorCode setupProblem()
[Read mesh]
MoFEMErrorCode assembleSystem()
[Boundary condition]
MoFEMErrorCode solveSystem()
[Solve]
MoFEMErrorCode outputResults()
[Solve]
boost::shared_ptr< AssembleRhsVectors > prePostProcFePtr
MoFEMErrorCode runProblem()
[Run problem]
boost::shared_ptr< ArcLengthCtx > arcCtx
boost::shared_ptr< MatrixDouble > fieldEvalDispPtr
MoFEMErrorCode evaluateFieldAtPoint(const int load_step)
[Assemble system]
boost::shared_ptr< FieldEvaluatorInterface::SetPtsData > fieldEvalData
boost::scoped_ptr< ArcLengthMatShell > matCtx
std::array< double, SPACE_DIM > fieldEvalCoords
boost::shared_ptr< ArcLengthSnesCtx > snesCtxPtr
boost::shared_ptr< DomainEle > elasticLhsFe
boost::shared_ptr< BoundaryEle > naturalBcFe
boost::shared_ptr< DomainEle > elasticRhsFe
shell matrix for arc-length method
Boundary conditions marker.
MoFEMErrorCode postProcess()
Post-processing function executed at loop completion.
boost::shared_ptr< ArcLengthCtx > arcPtr
MoFEMErrorCode preProcess()
Pre-processing function executed at loop initialization.
Constitutive (physical) equation for interface.
Boundary condition manager for finite element problem setup.
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.
Definition of the displacement bc data structure.
Class (Function) to enforce essential constrains on the left hand side diagonal.
Class (Function) to enforce essential constrains on the right hand side diagonal.
Class (Function) to enforce essential constrains.
Field evaluator interface.
Linear interface data structure.
Matrix manager is used to build and partition problems.
Interface for managing meshsets containing materials and boundary conditions.
MoFEMErrorCode setMeshsetFromFile(const string file_name, const bool clean_file_options=true)
add blocksets reading config file
Specialization for MatrixDouble vector field values calculation.
Post post-proc data at points from hash maps.
Template struct for dimension-specific finite element types.
Create interface from given surface and insert flat prisms in-between.
MoFEMErrorCode getSides(const int msId, const CubitBCType cubit_bc_type, const BitRefLevel mesh_bit_level, const bool recursive, int verb=QUIET)
Store tetrahedra from each side of the interface separately in two child meshsets of the parent meshs...
MoFEMErrorCode splitSides(const EntityHandle meshset, const BitRefLevel &bit, const int msId, const CubitBCType cubit_bc_type, const bool add_interface_entities, const bool recursive=false, int verb=QUIET)
Split nodes and other entities of tetrahedra on both sides of the interface and insert flat prisms in...
Problem manager is used to build and partition problems.
Projection of edge entities with one mid-node on hierarchical basis.
intrusive_ptr for managing petsc objects
MoFEM::FEMethodsSequence FEMethodsSequence
@ CTX_SNESSETFUNCTION
Setting up nonlinear function evaluation.
@ CTX_SNESNONE
No specific SNES context.
Vec & snes_f
Reference to residual vector.
SNESContext snes_ctx
Current SNES computation context.
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Vector manager is used to create vectors \mofem_vectors.
structure for Arc Length pre-conditioner
NaturalBC< BoundaryEleOp >::Assembly< AT >::LinearForm< IT > BoundaryRhsBCs
BoundaryRhsBCs::OpFlux< PlasticOps::BoundaryBCs, 1, SPACE_DIM > OpBoundaryRhsBCs
struct CohesiveInterfaceElement {
ublas::vector<MatrixDouble>
R;
};
:
MoFEM::FlatPrismElementForcesAndSourcesCore(m_field) {
}
};
struct PhysicalEquation {
double def_damaged = 0;
MB_TAG_CREAT | MB_TAG_SPARSE, &def_damaged);
const int def_len = 0;
"_KAPPA", def_len, MB_TYPE_DOUBLE,
thKappa,
MB_TAG_CREAT | MB_TAG_SPARSE | MB_TAG_VARLEN, nullptr);
}
double calcG(
int gg, MatrixDouble gap_loc) {
return sqrt(pow(gap_loc(gg, 0), 2) +
beta * (pow(gap_loc(gg, 1), 2) + pow(gap_loc(gg, 2), 2)));
}
EntityHandle ent = fe_method->numeredEntFiniteElementPtr->getEnt();
if (rval != MB_SUCCESS ||
kappaSize != nb_gauss_pts) {
kappa.resize(nb_gauss_pts);
int tag_size[1];
tag_size[0] = nb_gauss_pts;
void const *tag_data[] = {&
kappa[0]};
tag_size);
}
}
}
}
}
const VectorDouble &gap_loc,
double domega =
Dloc(0, 0) = (1 -
omega) *
E0 - domega *
E0 * gap_loc[0] * gap_loc[0] /
g;
Dloc(0, 1) = -domega *
E0 * gap_loc[0] *
beta * gap_loc[1] /
g;
Dloc(0, 2) = -domega *
E0 * gap_loc[0] *
beta * gap_loc[2] /
g;
Dloc(1, 0) = -domega *
E0 * gap_loc[1] * gap_loc[0] /
g;
Dloc(1, 2) = -domega *
E0 * gap_loc[1] *
beta * gap_loc[2] /
g;
Dloc(2, 0) = -domega *
E0 * gap_loc[2] * gap_loc[0] /
g;
Dloc(2, 1) = -domega *
E0 * gap_loc[2] *
beta * gap_loc[1] /
g;
}
}
if (gg == 0) {
}
double g =
calcG(gg, common_data.gapLoc);
traction.resize(3);
ublas::matrix_row<MatrixDouble> gap_glob(common_data.gapGlob, gg);
noalias(traction) = prod(
Dglob, gap_glob);
}
try {
}
if (gg == 0) {
}
double g =
calcG(gg, common_data.gapLoc);
int iter;
CHKERR SNESGetIterationNumber(fe_method->snes, &iter);
} else {
ublas::matrix_row<MatrixDouble> g_loc(common_data.gapLoc, gg);
}
tangent_matrix.resize(3, 3);
noalias(tangent_matrix) =
Dglob;
} catch (const std::exception &ex) {
std::ostringstream ss;
ss << "throw in method: " << ex.what() << std::endl;
SETERRQ(PETSC_COMM_SELF, 1, ss.str().c_str());
}
}
}
bool all_gauss_pts_damaged = true;
for (unsigned int gg = 0; gg < common_data.gapGlob.size1(); gg++) {
double g =
calcG(gg, common_data.gapLoc);
all_gauss_pts_damaged = false;
}
if (all_gauss_pts_damaged) {
EntityHandle ent = fe_method->numeredEntFiniteElementPtr->getEnt();
int set_prism_as_demaged = 1;
&set_prism_as_demaged);
}
}
};
struct OpSetSignToShapeFunctions
: public FlatPrismElementForcesAndSourcesCore::UserDataOperator {
EntitiesFieldData::EntData &data) {
if (data.getN().size1() == 0)
if (data.getN().size2() == 0)
case MBVERTEX:
for (unsigned int gg = 0; gg < data.getN().size1(); gg++) {
for (int nn = 3; nn < 6; nn++) {
data.getN()(gg, nn) *= -1;
}
}
break;
case MBEDGE:
if (side < 3)
data.getN() *= -1;
break;
case MBTRI:
if (side == 3)
data.getN() *= -1;
break;
default:
SETERRQ(PETSC_COMM_SELF, 1, "data inconsitency");
}
}
};
struct OpCalculateGapGlobal
: public FlatPrismElementForcesAndSourcesCore::UserDataOperator {
EntitiesFieldData::EntData &data) {
try {
int nb_dofs = data.getIndices().size();
if (nb_dofs == 0)
int nb_gauss_pts = data.getN().size1();
for (int gg = 0; gg < nb_gauss_pts; gg++) {
double nrm2_normal = 0;
double nrm2_tangent1 = 0;
double nrm2_tangent2 = 0;
for (
int dd = 0;
dd < 3;
dd++) {
nrm2_normal += pow(getNormalsAtGaussPtsF3()(gg, dd), 2);
nrm2_tangent1 += pow(getTangent1AtGaussPtF3()(gg, dd), 2);
nrm2_tangent2 += pow(getTangent2AtGaussPtF3()(gg, dd), 2);
}
nrm2_normal = sqrt(nrm2_normal);
nrm2_tangent1 = sqrt(nrm2_tangent1);
nrm2_tangent2 = sqrt(nrm2_tangent2);
for (
int dd = 0;
dd < 3;
dd++) {
getNormalsAtGaussPtsF3()(gg,
dd) / nrm2_normal;
getTangent1AtGaussPtF3()(gg,
dd) / nrm2_tangent1;
getTangent2AtGaussPtF3()(gg,
dd) / nrm2_tangent2;
}
}
}
}
for (int gg = 0; gg < nb_gauss_pts; gg++) {
for (
int dd = 0;
dd < 3;
dd++) {
nb_dofs / 3, &data.getN(gg)[0], 1, &data.getFieldData()[dd], 3);
}
}
} catch (const std::exception &ex) {
std::ostringstream ss;
ss << "throw in method: " << ex.what() << std::endl;
SETERRQ(PETSC_COMM_SELF, 1, ss.str().c_str());
}
}
};
struct OpCalculateGapLocal
: public FlatPrismElementForcesAndSourcesCore::UserDataOperator {
EntitiesFieldData::EntData &data) {
try {
int nb_gauss_pts = data.getN().size1();
for (int gg = 0; gg < nb_gauss_pts; gg++) {
}
}
} catch (const std::exception &ex) {
std::ostringstream ss;
ss << "throw in method: " << ex.what() << std::endl;
SETERRQ(PETSC_COMM_SELF, 1, ss.str().c_str());
}
}
};
struct OpRhs :
public FlatPrismElementForcesAndSourcesCore::UserDataOperator {
PhysicalEquation &physical_eqations)
EntitiesFieldData::EntData &data) {
try {
int nb_dofs = data.getIndices().size();
if (nb_dofs == 0)
getNumeredEntFiniteElementPtr()->getEnt()) ==
}
int nb_gauss_pts = data.getN().size1();
for (int gg = 0; gg < nb_gauss_pts; gg++) {
getFEMethod());
double w = getGaussPts()(2, gg) *
cblas_dnrm2(3, &getNormalsAtGaussPtsF3()(gg, 0), 1) * 0.5;
for (int nn = 0; nn < nb_dofs / 3; nn++) {
for (
int dd = 0;
dd < 3;
dd++) {
}
}
}
&data.getIndices()[0], &
Nf[0], ADD_VALUES);
} catch (const std::exception &ex) {
std::ostringstream ss;
ss << "throw in method: " << ex.what() << std::endl;
SETERRQ(PETSC_COMM_SELF, 1, ss.str().c_str());
}
}
};
struct OpLhs :
public FlatPrismElementForcesAndSourcesCore::UserDataOperator {
PhysicalEquation &physical_eqations)
sYmm = false;
}
EntityType col_type,
EntitiesFieldData::EntData &row_data,
EntitiesFieldData::EntData &col_data) {
try {
int nb_row = row_data.getIndices().size();
if (nb_row == 0)
int nb_col = col_data.getIndices().size();
if (nb_col == 0)
getNumeredEntFiniteElementPtr()->getEnt()) ==
}
K.resize(nb_row, nb_col);
int nb_gauss_pts = row_data.getN().size1();
for (int gg = 0; gg < nb_gauss_pts; gg++) {
getFEMethod());
double w = getGaussPts()(2, gg) *
cblas_dnrm2(3, &getNormalsAtGaussPtsF3()(gg, 0), 1) * 0.5;
for (int nn = 0; nn < nb_row / 3; nn++) {
for (
int dd = 0;
dd < 3;
dd++) {
for (int DD = 0; DD < 3; DD++) {
ND(3 * nn + dd, DD) += row_data.getN(gg)[nn] *
D(dd, DD);
}
}
}
for (int nn = 0; nn < nb_row / 3; nn++) {
for (
int dd = 0;
dd < 3;
dd++) {
for (int NN = 0; NN < nb_col / 3; NN++) {
for (int DD = 0; DD < 3; DD++) {
K(3 * nn + dd, 3 * NN + DD) +=
w *
ND(3 * nn + dd, DD) * col_data.getN(gg)[NN];
}
}
}
}
}
&row_data.getIndices()[0], nb_col,
&col_data.getIndices()[0], &
K(0, 0), ADD_VALUES);
} catch (const std::exception &ex) {
std::ostringstream ss;
ss << "throw in method: " << ex.what() << std::endl;
SETERRQ(PETSC_COMM_SELF, 1, ss.str().c_str());
}
}
};
struct OpHistory
: public FlatPrismElementForcesAndSourcesCore::UserDataOperator {
PhysicalEquation &physical_eqations)
EntitiesFieldData::EntData &data) {
getNumeredEntFiniteElementPtr()->getEnt()) ==
}
}
};
boost::ptr_vector<CohesiveInterfaceElement::PhysicalEquation>
&interfaces) {
boost::ptr_vector<CohesiveInterfaceElement::PhysicalEquation>::iterator pit;
for (pit = interfaces.begin(); pit != interfaces.end(); pit++) {
}
}
};
}
ForcesAndSourcesCore::UserDataOperator UserDataOperator
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
constexpr double omega
Save field DOFS on vertices/tags.
const Tensor2_symmetric_Expr< const ddTensor0< T, Dim, i, j >, typename promote< T, double >::V, Dim, i, j > dd(const Tensor0< T * > &a, const Index< i, Dim > index1, const Index< j, Dim > index2, const Tensor1< int, Dim > &d_ijk, const Tensor1< double, Dim > &d_xyz)
UBlasMatrix< double > MatrixDouble
UBlasVector< double > VectorDouble
MoFEMErrorCode MatSetValues(Mat M, const EntitiesFieldData::EntData &row_data, const EntitiesFieldData::EntData &col_data, const double *ptr, InsertMode iora)
Assemble PETSc matrix.
MoFEMErrorCode VecSetValues(Vec V, const EntitiesFieldData::EntData &data, const double *ptr, InsertMode iora)
Assemble PETSc vector.
constexpr auto field_name
ublas::vector< MatrixDouble > R
OpCalculateGapGlobal(const std::string field_name, CommonData &common_data)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
OpCalculateGapLocal(const std::string field_name, CommonData &common_data)
PhysicalEquation & physicalEqations
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
OpHistory(const std::string field_name, CommonData &common_data, PhysicalEquation &physical_eqations)
MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type, EntityType col_type, EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
PhysicalEquation & physicalEqations
PhysicalEquation & physicalEqations
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
OpSetSignToShapeFunctions(const std::string field_name)
MoFEMErrorCode doWork(int side, EntityType type, EntitiesFieldData::EntData &data)
MoFEM::Interface & mField
double calcG(int gg, MatrixDouble gap_loc)
Calculate gap opening.
virtual MoFEMErrorCode calculateTangentStiffeness(MatrixDouble &tangent_matrix, int gg, CommonData &common_data, const FEMethod *fe_method)
Calculate tangent stiffness.
MoFEMErrorCode iNitailise(const FEMethod *fe_method)
Initialize history variable data.
PhysicalEquation(MoFEM::Interface &m_field)
virtual ~PhysicalEquation()
MoFEMErrorCode calcOmega(const double kappa, double &omega)
Calculate damage.
MoFEMErrorCode calcTangetDglob(const double omega, double g, const VectorDouble &gap_loc, MatrixDouble &R)
Calculate tangent material stiffness.
MoFEMErrorCode calcDglob(const double omega, MatrixDouble &R)
Calculate stiffness material matrix.
virtual MoFEMErrorCode updateHistory(CommonData &common_data, const FEMethod *fe_method)
Update history variables when converged.
MoFEMErrorCode getKappa(int nb_gauss_pts, const FEMethod *fe_method)
Get pointer from the mesh to histoy variables .
virtual MoFEMErrorCode calculateTraction(VectorDouble &traction, int gg, CommonData &common_data, const FEMethod *fe_method)
Calculate tractions.
virtual ~CohesiveInterfaceElement()
MoFEMErrorCode addOps(const std::string field_name, boost::ptr_vector< CohesiveInterfaceElement::PhysicalEquation > &interfaces)
Driver function settting all operators needed for interface element.
CohesiveInterfaceElement(MoFEM::Interface &m_field)
virtual moab::Interface & get_moab()=0
FlatPrism finite element.
std::string meshPositionsFieldName
boost::ptr_deque< UserDataOperator > & getOpPtrVector()
Use to push back operator for row operator.
struct ArcLengthIntElemFEMethod :
public FEMethod {
boost::shared_ptr<ArcLengthCtx>
arcPtr;
ArcLengthIntElemFEMethod(moab::Interface &moab,
boost::shared_ptr<ArcLengthCtx> arcptr)
PetscInt ghosts[1] = {0};
if (pcomm->rank() == 0) {
CHKERRABORT(PETSC_COMM_WORLD, VecCreateGhost(PETSC_COMM_WORLD, 1, 1, 0,
} else {
CHKERRABORT(PETSC_COMM_WORLD, VecCreateGhost(PETSC_COMM_WORLD, 0, 1, 1,
}
CHKERRABORT(PETSC_COMM_WORLD,
mOab.get_entities_by_type(0, MBPRISM, prisms,
false));
for (Range::iterator pit = prisms.begin(); pit != prisms.end(); pit++) {
EntityHandle f3, f4;
CHKERRABORT(PETSC_COMM_WORLD,
mOab.side_element(*pit, 2, 3, f3));
CHKERRABORT(PETSC_COMM_WORLD,
mOab.side_element(*pit, 2, 4, f4));
}
CHKERRABORT(PETSC_COMM_WORLD,
CHKERRABORT(PETSC_COMM_WORLD,
double def_damaged = 0;
CHKERRABORT(
PETSC_COMM_WORLD,
MB_TAG_CREAT | MB_TAG_SPARSE, &def_damaged));
}
}
CHKERR mOab.get_entities_by_type(0, MBPRISM, prisms,
false);
std::vector<int> is_prism_damaged(prisms.size());
&*is_prism_damaged.begin());
Range::iterator pit = prisms.begin();
std::vector<int>::iterator vit = is_prism_damaged.begin();
for (; pit != prisms.end(); pit++, vit++) {
if (*vit > 0) {
CHKERR mOab.get_connectivity(&*pit, 1, nodes,
true);
for (Range::iterator nit = nodes.begin(); nit != nodes.end(); nit++) {
}
}
}
}
switch (snes_ctx) {
case CTX_SNESSETFUNCTION: {
} break;
default:
break;
}
}
NumeredDofEntityByLocalIdx::iterator dit, hi_dit;
dit = problemPtr->getNumeredRowDofsPtr()
->get<PetscLocalIdx_mi_tag>()
.lower_bound(0);
hi_dit = problemPtr->getNumeredRowDofsPtr()
->get<PetscLocalIdx_mi_tag>()
.upper_bound(problemPtr->getNbLocalDofsRow());
double *array;
double *array_int_lambda;
array_int_lambda[0] = 0;
for (; dit != hi_dit; dit++) {
if (dit->get()->getEntType() != MBVERTEX)
continue;
if (pcomm->rank() != dit->get()->getPart())
continue;
array_int_lambda[0] += array[dit->get()->getPetscLocalDofIdx()];
}
array_int_lambda[0] -= array[dit->get()->getPetscLocalDofIdx()];
}
}
_lambda_int_ =
arcPtr->alpha * array_int_lambda[0] +
}
CHKERR VecGhostUpdateBegin(
arcPtr->db, INSERT_VALUES, SCATTER_FORWARD);
CHKERR VecGhostUpdateEnd(
arcPtr->db, INSERT_VALUES, SCATTER_FORWARD);
NumeredDofEntityByLocalIdx::iterator dit, hi_dit;
dit = problemPtr->getNumeredRowDofsPtr()
->get<PetscLocalIdx_mi_tag>()
.lower_bound(0);
hi_dit = problemPtr->getNumeredRowDofsPtr()
->get<PetscLocalIdx_mi_tag>()
.upper_bound(problemPtr->getNbLocalDofsRow() +
problemPtr->getNbGhostDofsRow());
double *array;
for (; dit != hi_dit; dit++) {
if (dit->get()->getEntType() != MBVERTEX) {
array[dit->get()->getPetscLocalDofIdx()] = 0;
continue;
}
array[dit->get()->getPetscLocalDofIdx()] = +
arcPtr->alpha;
}
else if (
Nodes4.find(dit->get()->getEnt()) !=
Nodes4.end()) {
array[dit->get()->getPetscLocalDofIdx()] = -
arcPtr->alpha;
} else
array[dit->get()->getPetscLocalDofIdx()] = 0;
}
}
switch (snes_ctx) {
case CTX_SNESSETFUNCTION: {
arcPtr->res_lambda, ADD_VALUES);
"ARC_LENGTH", Sev::inform,
"\tres_lambda = %6.4e lambda_int = %6.4e s = %6.4e",
} break;
case CTX_SNESSETJACOBIAN: {
arcPtr->getPetscGlobalDofIdx(), 1, ADD_VALUES);
} break;
default:
break;
}
}
switch (snes_ctx) {
case CTX_SNESSETJACOBIAN: {
CHKERR VecGhostUpdateBegin(
arcPtr->ghostDiag, INSERT_VALUES,
SCATTER_FORWARD);
SCATTER_FORWARD);
CHKERR MatAssemblyBegin(snes_B, MAT_FLUSH_ASSEMBLY);
CHKERR MatAssemblyEnd(snes_B, MAT_FLUSH_ASSEMBLY);
} break;
default:
break;
}
}
if (
arcPtr->getPetscLocalDofIdx() != -1) {
double *array;
array[
arcPtr->getPetscLocalDofIdx()] = 0;
}
CHKERR VecGhostUpdateBegin(
arcPtr->ghosTdLambda, INSERT_VALUES,
SCATTER_FORWARD);
CHKERR VecGhostUpdateEnd(
arcPtr->ghosTdLambda, INSERT_VALUES,
SCATTER_FORWARD);
"\tdlambda = %6.4e dx2 = %6.4e",
arcPtr->dLambda,
}
"ARC_LENGTH", Sev::inform,
"\tInit dlambda = %6.4e s = %6.4e beta = %6.4e F_lambda2 = %6.4e",
std::ostringstream sss;
SETERRQ(PETSC_COMM_SELF, 1, sss.str().c_str());
}
}
if (
arcPtr->getPetscLocalDofIdx() != -1) {
double *array;
CHKERR VecGetArray(x, &array);
double lambda_old = array[
arcPtr->getPetscLocalDofIdx()];
if (!(dlambda == dlambda)) {
std::ostringstream sss;
SETERRQ(PETSC_COMM_SELF, 1, sss.str().c_str());
}
array[
arcPtr->getPetscLocalDofIdx()] = lambda_old + dlambda;
"\tlambda = %6.4e, %6.4e (%6.4e)", lambda_old,
array[
arcPtr->getPetscLocalDofIdx()], dlambda);
CHKERR VecRestoreArray(x, &array);
}
}
};
}
#define MYPCOMM_INDEX
default communicator number PCOMM
MoFEMErrorCode remove_damaged_prisms_nodes()
remove nodes of prims which are fully damaged
MoFEMErrorCode calculate_lambda_int(double &_lambda_int_)
MoFEMErrorCode calculate_init_dlambda(double *dlambda)
MoFEMErrorCode operator()()
MoFEMErrorCode calculate_dx_and_dlambda(Vec &x)
MoFEMErrorCode postProcess()
~ArcLengthIntElemFEMethod()
MoFEMErrorCode set_dlambda_to_x(Vec &x, double dlambda)
virtual MoFEMErrorCode calculate_db()
MoFEMErrorCode preProcess()
boost::shared_ptr< ArcLengthCtx > arcPtr