Complete example for identifying cell forces from measured displacements.
#include <HookeOps.hpp>
static char help[] =
"-my_block_config set block data\n"
"\n";
};
using VolumeElementForcesAndSourcesCore::VolumeElementForcesAndSourcesCore;
};
struct OpElasticEnergy
OpElasticEnergy(boost::shared_ptr<MatrixDouble> strain_ptr,
boost::shared_ptr<MatrixDouble> stress_ptr,
double &
energy)
NOSPACE, UserDataOperator::OPSPACE),
const size_t nb_gauss_pts = getGaussPts().size2();
auto get_strain =
auto get_stress =
auto t_strain = get_strain();
auto t_stress = get_stress();
for (size_t gg = 0; gg != nb_gauss_pts; ++gg) {
const double alpha = getMeasure() * getGaussPts()(
SPACE_DIM, gg);
energy += 0.5 * alpha * t_strain(
i,
j) * t_stress(
i,
j);
++t_strain;
++t_stress;
}
}
private:
};
}
using namespace boost::numeric;
#include <boost/program_options.hpp>
namespace po = boost::program_options;
int main(
int argc,
char *argv[]) {
try {
moab::Core mb_instance;
moab::Interface &moab = mb_instance;
PetscBool flg_block_config, flg_file;
char mesh_file_name[255];
char block_config_file[255];
PetscBool flg_order_force;
PetscInt order_force = 2;
PetscBool flg_eps_u, flg_eps_rho, flg_eps_l;
double eps_u = 1e-6;
double eps_rho = 1e-3;
double eps_l = 0;
PetscBool is_curl = PETSC_TRUE;
PetscOptionsBegin(PETSC_COMM_WORLD, "", "Elastic Config", "none");
CHKERR PetscOptionsString(
"-my_file",
"mesh file name",
"",
"mesh.h5m",
mesh_file_name, 255, &flg_file);
CHKERR PetscOptionsInt(
"-my_order",
"default approximation order",
"",
"-my_order_force",
"default approximation order for force approximation", "", order_force,
&order_force, &flg_order_force);
CHKERR PetscOptionsString(
"-my_block_config",
"elastic configure file name",
"", "block_conf.in", block_config_file, 255,
&flg_block_config);
CHKERR PetscOptionsReal(
"-my_eps_rho",
"foce optimality parameter ",
"",
eps_rho, &eps_rho, &flg_eps_rho);
CHKERR PetscOptionsReal(
"-my_eps_u",
"displacement optimality parameter ",
"", eps_u, &eps_u, &flg_eps_u);
CHKERR PetscOptionsReal(
"-my_eps_l",
"displacement optimality parameter ",
"", eps_l, &eps_l, &flg_eps_l);
CHKERR PetscOptionsBool(
"-my_curl",
"use Hcurl space to approximate forces",
"", is_curl, &is_curl, PETSC_NULLPTR);
PetscOptionsEnd();
if (flg_file != PETSC_TRUE) {
"*** ERROR -my_file (MESH FILE NEEDED)");
}
ParallelComm *pcomm = ParallelComm::get_pcomm(&moab,
MYPCOMM_INDEX);
if (pcomm == nullptr)
pcomm = new ParallelComm(&moab, PETSC_COMM_WORLD);
const char *option;
option = "PARALLEL=READ_PART;"
"PARALLEL_RESOLVE_SHARED_ENTS;"
"PARTITION=PARALLEL_PARTITION;";
CHKERR moab.load_file(mesh_file_name, 0, option);
CHKERR mmanager_ptr->printDisplacementSet();
CHKERR mmanager_ptr->printForceSet();
CHKERR mmanager_ptr->printMaterialsSet();
bit_level0.set(0);
{
CHKERR moab.get_entities_by_dimension(0, 3, ents3d);
ents3d, bit_level0, false);
}
std::vector<Range> setOrderToEnts(10);
std::map<int, BlockOptionData> block_data;
if (flg_block_config) {
double read_eps_u, read_eps_rho, read_eps_l;
try {
ifstream ini_file(block_config_file);
if (!ini_file.is_open()) {
SETERRQ(PETSC_COMM_SELF, 1,
"*** -my_block_config does not exist ***");
}
po::variables_map vm;
po::options_description config_file_options;
config_file_options.add_options()(
"eps_u", po::value<double>(&read_eps_u)->default_value(-1))(
"eps_rho", po::value<double>(&read_eps_rho)->default_value(-1))(
"eps_l", po::value<double>(&read_eps_l)->default_value(-1));
std::ostringstream str_order;
str_order << "block_" << it->getMeshsetId() << ".displacement_order";
config_file_options.add_options()(
str_order.str().c_str(),
po::value<int>(&block_data[it->getMeshsetId()].oRder)
std::ostringstream str_cond;
str_cond << "block_" << it->getMeshsetId() << ".young_modulus";
config_file_options.add_options()(
str_cond.str().c_str(),
po::value<double>(&block_data[it->getMeshsetId()].yOung)
->default_value(-1));
std::ostringstream str_capa;
str_capa << "block_" << it->getMeshsetId() << ".poisson_ratio";
config_file_options.add_options()(
str_capa.str().c_str(),
po::value<double>(&block_data[it->getMeshsetId()].pOisson)
->default_value(-2));
}
po::parsed_options parsed =
parse_config_file(ini_file, config_file_options, true);
store(parsed, vm);
po::notify(vm);
if (block_data[it->getMeshsetId()].oRder == -1)
continue;
if (block_data[it->getMeshsetId()].oRder ==
order)
continue;
PetscPrintf(PETSC_COMM_WORLD, "Set block %d order to %d\n",
it->getMeshsetId(), block_data[it->getMeshsetId()].oRder);
CHKERR moab.get_entities_by_handle(it->getMeshset(), block_ents,
true);
CHKERR moab.get_connectivity(block_ents, nodes,
true);
Range ents_to_set_order, ents3d;
CHKERR moab.get_adjacencies(nodes, 3,
false, ents3d,
moab::Interface::UNION);
CHKERR moab.get_adjacencies(ents3d, 2,
false, ents_to_set_order,
moab::Interface::UNION);
CHKERR moab.get_adjacencies(ents3d, 1,
false, ents_to_set_order,
moab::Interface::UNION);
ents_to_set_order = subtract(
ents_to_set_order, ents_to_set_order.subset_by_type(MBQUAD));
ents_to_set_order = subtract(
ents_to_set_order, ents_to_set_order.subset_by_type(MBPRISM));
set_order_ents.merge(ents3d);
set_order_ents.merge(ents_to_set_order);
setOrderToEnts[block_data[it->getMeshsetId()].oRder].merge(
set_order_ents);
}
CHKERR comm_interface_ptr->synchroniseEntities(set_order_ents, 0);
std::vector<std::string> additional_parameters;
additional_parameters =
collect_unrecognized(parsed.options, po::include_positional);
for (std::vector<std::string>::iterator vit =
additional_parameters.begin();
vit != additional_parameters.end(); vit++) {
CHKERR PetscPrintf(PETSC_COMM_WORLD,
"** WARNING Unrecognized option %s\n",
vit->c_str());
}
} catch (const std::exception &ex) {
std::ostringstream ss;
ss << ex.what() << std::endl;
}
if (read_eps_u > 0) {
eps_u = read_eps_u;
};
if (read_eps_rho > 0) {
eps_rho = read_eps_rho;
}
if (read_eps_l > 0) {
eps_l = read_eps_l;
}
}
PetscPrintf(PETSC_COMM_WORLD, "epsU = %6.4e epsRho = %6.4e\n", eps_u,
eps_rho);
if (is_curl) {
} else {
}
CHKERR comm_interface_ptr->synchroniseFieldEntities(
"U");
CHKERR comm_interface_ptr->synchroniseFieldEntities(
"UPSILON");
CHKERR comm_interface_ptr->synchroniseFieldEntities(
"RHO");
if (mmanager_ptr->checkMeshset(202,
SIDESET)) {
ents_1st_layer, true);
vertex_to_fix, false);
CHKERR mmanager_ptr->getEntitiesByDimension(202,
SIDESET, 1, edges_to_fix,
false);
if (vertex_to_fix.size() != 1 && !vertex_to_fix.empty()) {
"Should be one vertex only, but is %zu", vertex_to_fix.size());
}
}
CHKERR comm_interface_ptr->synchroniseEntities(ents_1st_layer, 0);
ents_1st_layer.subset_by_type(MBTRI), MBTRI, "RHO");
if (mmanager_ptr->checkMeshset(101,
SIDESET)) {
ents_2nd_layer, true);
}
CHKERR comm_interface_ptr->synchroniseEntities(ents_2nd_layer, 0);
for (int oo = 2; oo != setOrderToEnts.size(); oo++) {
if (setOrderToEnts[oo].size() > 0) {
CHKERR comm_interface_ptr->synchroniseEntities(setOrderToEnts[oo], 0);
}
}
const int through_thickness_order = 2;
{
CHKERR moab.get_entities_by_dimension(0, 3, ents3d);
CHKERR moab.get_adjacencies(ents3d, 2,
false, ents,
moab::Interface::UNION);
CHKERR moab.get_adjacencies(ents3d, 1,
false, ents,
moab::Interface::UNION);
CHKERR moab.get_entities_by_type(0, MBPRISM, prisms);
{
CHKERR moab.get_adjacencies(prisms, 2,
false, quads,
moab::Interface::UNION);
prism_tris = quads.subset_by_type(MBTRI);
quads = subtract(quads, prism_tris);
CHKERR moab.get_adjacencies(quads, 1,
false, quads_edges,
moab::Interface::UNION);
CHKERR moab.get_adjacencies(prism_tris, 1,
false, prism_tris_edges,
moab::Interface::UNION);
quads_edges = subtract(quads_edges, prism_tris_edges);
prisms.merge(quads);
prisms.merge(quads_edges);
}
ents.merge(ents3d);
ents = subtract(ents, set_order_ents);
ents = subtract(ents, prisms);
CHKERR comm_interface_ptr->synchroniseEntities(ents, 0);
CHKERR comm_interface_ptr->synchroniseEntities(prisms, 0);
through_thickness_order);
}
if (is_curl) {
} else {
}
int default_block_id = -1;
CHKERR moab.tag_get_handle(
"BLOCK_ID", 1, MB_TYPE_INTEGER, block_id_tag,
MB_TAG_CREAT | MB_TAG_SPARSE, &default_block_id);
CHKERR it->getAttributeDataStructure(material);
const int block_id = it->getMeshsetId();
CHKERR moab.get_entities_by_handle(it->getMeshset(),
elastic_blocks[block_id], true);
const auto block_elements =
elastic_blocks[block_id].subset_by_type(MBTET);
CHKERR moab.tag_clear_data(block_id_tag, block_elements, &block_id);
const auto options_it = block_data.find(block_id);
if (options_it != block_data.end() && options_it->second.yOung > 0) {
material.
data.Young = options_it->second.yOung;
CHKERR PetscPrintf(PETSC_COMM_WORLD,
"Block %d set Young modulus %3.4g\n", block_id,
}
if (options_it != block_data.end() && options_it->second.pOisson >= -1) {
material.
data.Poisson = options_it->second.pOisson;
CHKERR PetscPrintf(PETSC_COMM_WORLD,
"Block %d set Poisson ratio %3.4g\n", block_id,
}
material);
}
for (const auto &[id, entities] : elastic_blocks)
CHKERR m_field.add_ents_to_finite_element_by_type(entities, MBTET,
"ELASTIC");
double elastic_energy = 0;
auto elastic_rhs_common =
HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
m_field, elastic_rhs.getOpPtrVector(), "U", "MAT_ELASTIC",
Sev::verbose);
CHKERR HookeOps::opFactoryDomainRhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
m_field, elastic_rhs.getOpPtrVector(), "U", elastic_rhs_common,
Sev::verbose, true);
auto elastic_lhs_common =
HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
m_field, elastic_lhs.getOpPtrVector(), "U", "MAT_ELASTIC",
Sev::verbose);
CHKERR HookeOps::opFactoryDomainLhs<SPACE_DIM, PETSC, GAUSS, DomainEleOp>(
m_field, elastic_lhs.getOpPtrVector(), "U", elastic_lhs_common,
Sev::verbose);
auto elastic_energy_common =
HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
m_field, elastic_energy_fe.getOpPtrVector(), "U", "MAT_ELASTIC",
Sev::verbose);
elastic_energy_common->getMatStrain(),
elastic_energy_common->getMatCauchyStress(), elastic_energy));
{
auto block_it = elastic_blocks.find(2);
if (block_it == elastic_blocks.end()) {
"Elastic material block 2 is required for prism elements");
}
block_it->second);
block_it->second, MBPRISM, "ELASTIC_PRISM");
auto inv_jac_ptr = boost::make_shared<MatrixDouble>();
fat_prism_rhs.getOpPtrVector().push_back(
fat_prism_rhs.getOpPtrVector().push_back(
auto prism_rhs_common =
HookeOps::commonDataFactory<SPACE_DIM, GAUSS, FatPrismOp>(
m_field, fat_prism_rhs.getOpPtrVector(), "U", "MAT_ELASTIC",
Sev::verbose);
CHKERR HookeOps::opFactoryDomainRhs<SPACE_DIM, PETSC, GAUSS, FatPrismOp>(
m_field, fat_prism_rhs.getOpPtrVector(), "U", prism_rhs_common,
Sev::verbose, true);
fat_prism_lhs.getOpPtrVector().push_back(
fat_prism_lhs.getOpPtrVector().push_back(
auto prism_lhs_common =
HookeOps::commonDataFactory<SPACE_DIM, GAUSS, FatPrismOp>(
m_field, fat_prism_lhs.getOpPtrVector(), "U", "MAT_ELASTIC",
Sev::verbose);
CHKERR HookeOps::opFactoryDomainLhs<SPACE_DIM, PETSC, GAUSS, FatPrismOp>(
m_field, fat_prism_lhs.getOpPtrVector(), "U", prism_lhs_common,
Sev::verbose);
}
"UPSILON");
"U");
"UPSILON");
"U");
"DISP_X");
"DISP_Y");
"DISPLACEMENTS_PENALTY");
"BT");
"B");
"D");
DMType dm_name = "MOFEM";
DM dm_control;
{
CHKERR DMCreate(PETSC_COMM_WORLD, &dm_control);
CHKERR DMSetType(dm_control, dm_name);
bit_level0);
CHKERR DMSetFromOptions(dm_control);
}
ublas::matrix<Mat> nested_matrices(2, 2);
ublas::vector<IS> nested_is_rows(2);
ublas::vector<IS> nested_is_cols(2);
for (
int i = 0;
i != 2;
i++) {
nested_is_rows[
i] = PETSC_NULLPTR;
nested_is_cols[
i] = PETSC_NULLPTR;
for (
int j = 0;
j != 2;
j++) {
nested_matrices(
i,
j) = PETSC_NULLPTR;
}
}
ublas::matrix<Mat> sub_nested_matrices(2, 2);
ublas::vector<IS> sub_nested_is_rows(2);
ublas::vector<IS> sub_nested_is_cols(2);
for (
int i = 0;
i != 2;
i++) {
sub_nested_is_rows[
i] = PETSC_NULLPTR;
sub_nested_is_cols[
i] = PETSC_NULLPTR;
for (
int j = 0;
j != 2;
j++) {
sub_nested_matrices(
i,
j) = PETSC_NULLPTR;
}
}
DM dm_sub_volume_control;
{
CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_volume_control);
CHKERR DMSetType(dm_sub_volume_control, dm_name);
"SUB_CONTROL_PROB");
CHKERR DMSetUp(dm_sub_volume_control);
boost::shared_ptr<Problem::SubProblemData> sub_data =
CHKERR sub_data->getRowIs(&nested_is_rows[0]);
CHKERR sub_data->getColIs(&nested_is_cols[0]);
nested_matrices(0, 0) = PETSC_NULLPTR;
}
{
DM dm_sub_sub_elastic;
CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_sub_elastic);
CHKERR DMSetType(dm_sub_sub_elastic, dm_name);
"ELASTIC_PROB");
CHKERR DMSetUp(dm_sub_sub_elastic);
->pushMarkDOFsOnEntities<DisplacementCubitBcData>("ELASTIC_PROB",
"U");
Mat Kuu;
CHKERR DMCreateMatrix(dm_sub_sub_elastic, &Kuu);
CHKERR DMCreateGlobalVector(dm_sub_sub_elastic, &Du);
CHKERR DMCreateGlobalVector(dm_sub_sub_elastic, &Fu);
SCATTER_REVERSE);
auto dirichlet_bc_ptr = boost::make_shared<FEMethod>();
dirichlet_bc_ptr->vecAssembleSwitch =
boost::movelib::make_unique<bool>(false);
dirichlet_bc_ptr->matAssembleSwitch =
boost::movelib::make_unique<bool>(false);
dirichlet_bc_ptr->preProcessHook =
m_field, dirichlet_bc_ptr,
std::vector<boost::shared_ptr<ScalingMethod>>{}, false);
dirichlet_bc_ptr->postProcessHook = [&]() {
CHKERR VecGhostUpdateBegin(Fu, ADD_VALUES, SCATTER_REVERSE);
CHKERR VecGhostUpdateEnd(Fu, ADD_VALUES, SCATTER_REVERSE);
CHKERR MatAssemblyBegin(Kuu, MAT_FINAL_ASSEMBLY);
CHKERR MatAssemblyEnd(Kuu, MAT_FINAL_ASSEMBLY);
};
dirichlet_bc_ptr->snes_ctx = FEMethod::CTX_SNESNONE;
dirichlet_bc_ptr->ts_ctx = FEMethod::CTX_TSNONE;
dirichlet_bc_ptr.get());
SCATTER_REVERSE);
elastic_rhs.snes_f = Fu;
fat_prism_rhs.snes_f = Fu;
&elastic_rhs);
&fat_prism_rhs);
elastic_lhs.snes_B = Kuu;
fat_prism_lhs.snes_B = Kuu;
&elastic_lhs);
&fat_prism_lhs);
dirichlet_bc_ptr.get());
CHKERR VecGhostUpdateBegin(Fu, ADD_VALUES, SCATTER_REVERSE);
CHKERR VecGhostUpdateEnd(Fu, ADD_VALUES, SCATTER_REVERSE);
boost::shared_ptr<Problem::SubProblemData> sub_data =
CHKERR sub_data->getRowIs(&sub_nested_is_rows[0]);
CHKERR sub_data->getColIs(&sub_nested_is_cols[0]);
sub_nested_matrices(0, 0) = Kuu;
IS isUpsilon;
->isCreateFromProblemFieldToOtherProblemField(
"ELASTIC_PROB",
"U",
ROW,
"SUB_CONTROL_PROB",
"UPSILON",
ROW,
PETSC_NULLPTR, &isUpsilon);
sub_nested_is_rows[1] = isUpsilon;
sub_nested_is_cols[1] = isUpsilon;
sub_nested_matrices(1, 1) = Kuu;
PetscObjectReference((PetscObject)Kuu);
PetscObjectReference((PetscObject)isUpsilon);
cerr << "Kuu" << endl;
MatView(Kuu, PETSC_VIEWER_DRAW_WORLD);
std::string wait;
std::cin >> wait;
}
CHKERR DMDestroy(&dm_sub_sub_elastic);
}
{
DM dm_sub_disp_penalty;
CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_disp_penalty);
CHKERR DMSetType(dm_sub_disp_penalty, dm_name);
"S_PROB");
CHKERR DMSetUp(dm_sub_disp_penalty);
Mat S;
CHKERR DMCreateMatrix(dm_sub_disp_penalty, &S);
face_element.getOpPtrVector().push_back(
new OpCellS(S, eps_u));
"DISPLACEMENTS_PENALTY", &face_element);
CHKERR MatAssemblyBegin(S, MAT_FLUSH_ASSEMBLY);
CHKERR MatAssemblyEnd(S, MAT_FLUSH_ASSEMBLY);
cerr << "S" << endl;
MatView(S, PETSC_VIEWER_DRAW_WORLD);
std::string wait;
std::cin >> wait;
}
boost::shared_ptr<Problem::SubProblemData> sub_data =
sub_nested_matrices(1, 0) = S;
CHKERR DMDestroy(&dm_sub_disp_penalty);
}
{
DM dm_sub_force_penalty;
CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_force_penalty);
CHKERR DMSetType(dm_sub_force_penalty, dm_name);
CHKERR DMSetUp(dm_sub_force_penalty);
CHKERR DMCreateMatrix(dm_sub_force_penalty, &
D);
{
if (is_curl) {
{HCURL});
face_d_matrix.getOpPtrVector().push_back(
} else {
face_d_matrix.getOpPtrVector().push_back(
}
&face_d_matrix);
}
CHKERR MatAssemblyBegin(
D, MAT_FINAL_ASSEMBLY);
CHKERR MatAssemblyEnd(
D, MAT_FINAL_ASSEMBLY);
if (is_curl == PETSC_FALSE) {
int nb_dofs_to_fix = 0;
int index_to_fix = 0;
if (!vertex_to_fix.empty()) {
boost::shared_ptr<NumeredDofEntity> dof_ptr;
dof_ptr);
if (dof_ptr) {
nb_dofs_to_fix = 1;
index_to_fix = dof_ptr->getPetscGlobalDofIdx();
cerr << *dof_ptr << endl;
}
}
}
CHKERR MatZeroRowsColumns(
D, nb_dofs_to_fix, &index_to_fix,
eps_rho / eps_u, PETSC_NULLPTR,
PETSC_NULLPTR);
} else {
std::vector<int> dofs_to_fix;
for (auto p_eit = edges_to_fix.pair_begin();
p_eit != edges_to_fix.pair_end(); ++p_eit) {
auto lo = row_dofs->lower_bound(
FieldEntity::getLoLocalEntityBitNumber(bit_number, p_eit->first));
auto hi =
row_dofs->upper_bound(FieldEntity::getHiLocalEntityBitNumber(
bit_number, p_eit->second));
for (; lo != hi; ++lo)
dofs_to_fix.push_back((*lo)->getPetscGlobalDofIdx());
}
CHKERR MatZeroRowsColumns(
D, dofs_to_fix.size(), &*dofs_to_fix.begin(),
eps_rho / eps_u, PETSC_NULLPTR,
PETSC_NULLPTR);
}
cerr << "D" << endl;
MatView(
D, PETSC_VIEWER_DRAW_WORLD);
std::string wait;
std::cin >> wait;
}
boost::shared_ptr<Problem::SubProblemData> sub_data =
CHKERR sub_data->getRowIs(&nested_is_rows[1]);
CHKERR sub_data->getColIs(&nested_is_cols[1]);
nested_matrices(1, 1) =
D;
CHKERR DMDestroy(&dm_sub_force_penalty);
}
{
DM dm_sub_force;
CHKERR DMCreate(PETSC_COMM_WORLD, &dm_sub_force);
CHKERR DMSetType(dm_sub_force, dm_name);
Mat UB, UPSILONB;
CHKERR DMCreateMatrix(dm_sub_force, &UB);
CHKERR DMCreateMatrix(dm_sub_force, &UPSILONB);
CHKERR MatZeroEntries(UPSILONB);
{
if (is_curl) {
{H1, HCURL});
face_b_matrices.getOpPtrVector().push_back(
new OpCellCurlB(UB,
"U"));
face_b_matrices.getOpPtrVector().push_back(
} else {
{H1});
face_b_matrices.getOpPtrVector().push_back(
face_b_matrices.getOpPtrVector().push_back(
}
}
CHKERR MatAssemblyBegin(UB, MAT_FINAL_ASSEMBLY);
CHKERR MatAssemblyBegin(UPSILONB, MAT_FINAL_ASSEMBLY);
CHKERR MatAssemblyEnd(UB, MAT_FINAL_ASSEMBLY);
CHKERR MatAssemblyEnd(UPSILONB, MAT_FINAL_ASSEMBLY);
if (is_curl == PETSC_FALSE) {
int nb_dofs_to_fix = 0;
int index_to_fix = 0;
if (!vertex_to_fix.empty()) {
boost::shared_ptr<NumeredDofEntity> dof_ptr;
dof_ptr);
if (dof_ptr) {
nb_dofs_to_fix = 1;
index_to_fix = dof_ptr->getPetscGlobalDofIdx();
cerr << *dof_ptr << endl;
}
}
}
CHKERR MatZeroRows(UB, nb_dofs_to_fix, &index_to_fix, 0, PETSC_NULLPTR,
PETSC_NULLPTR);
CHKERR MatZeroRows(UPSILONB, nb_dofs_to_fix, &index_to_fix, 0,
PETSC_NULLPTR, PETSC_NULLPTR);
} else {
std::vector<int> dofs_to_fix;
for (auto p_eit = edges_to_fix.pair_begin();
p_eit != edges_to_fix.pair_end(); ++p_eit) {
auto lo = row_dofs->lower_bound(
FieldEntity::getLoLocalEntityBitNumber(bit_number, p_eit->first));
auto hi =
row_dofs->upper_bound(FieldEntity::getHiLocalEntityBitNumber(
bit_number, p_eit->second));
for (; lo != hi; ++lo)
dofs_to_fix.push_back((*lo)->getPetscGlobalDofIdx());
}
CHKERR MatZeroRows(UB, dofs_to_fix.size(), &*dofs_to_fix.begin(), 0,
PETSC_NULLPTR, PETSC_NULLPTR);
CHKERR MatZeroRows(UPSILONB, dofs_to_fix.size(), &*dofs_to_fix.begin(),
0, PETSC_NULLPTR, PETSC_NULLPTR);
}
Mat UBT;
CHKERR MatTranspose(UB, MAT_INITIAL_MATRIX, &UBT);
cerr << "UBT" << endl;
MatView(UBT, PETSC_VIEWER_DRAW_WORLD);
std::string wait;
std::cin >> wait;
}
boost::shared_ptr<Problem::SubProblemData> sub_data =
nested_matrices(0, 1) = UBT;
cerr << "UPSILONB" << endl;
MatView(UPSILONB, PETSC_VIEWER_DRAW_WORLD);
std::string wait;
std::cin >> wait;
}
nested_matrices(1, 0) = UPSILONB;
CHKERR DMDestroy(&dm_sub_force);
}
Mat SubA;
CHKERR MatCreateNest(PETSC_COMM_WORLD, 2, &sub_nested_is_rows[0], 2,
&sub_nested_is_cols[0], &sub_nested_matrices(0, 0),
&SubA);
nested_matrices(0, 0) = SubA;
CHKERR MatAssemblyBegin(SubA, MAT_FINAL_ASSEMBLY);
CHKERR MatAssemblyEnd(SubA, MAT_FINAL_ASSEMBLY);
cerr << "Nested SubA" << endl;
MatView(SubA, PETSC_VIEWER_STDOUT_WORLD);
}
CHKERR MatCreateNest(PETSC_COMM_WORLD, 2, &nested_is_rows[0], 2,
&nested_is_cols[0], &nested_matrices(0, 0), &
A);
CHKERR MatAssemblyBegin(
A, MAT_FINAL_ASSEMBLY);
CHKERR MatAssemblyEnd(
A, MAT_FINAL_ASSEMBLY);
cerr << "Nested A" << endl;
MatView(
A, PETSC_VIEWER_STDOUT_WORLD);
}
CHKERR DMCreateGlobalVector(dm_control, &
D);
CHKERR DMCreateGlobalVector(dm_control, &
F);
{
face_element.getOpPtrVector().push_back(
new OpGetDispX(common_data));
face_element.getOpPtrVector().push_back(
new OpGetDispY(common_data));
face_element.getOpPtrVector().push_back(
&face_element);
CHKERR VecGhostUpdateBegin(
F, ADD_VALUES, SCATTER_REVERSE);
CHKERR VecGhostUpdateEnd(
F, ADD_VALUES, SCATTER_REVERSE);
}
KSP solver;
{
CHKERR KSPCreate(PETSC_COMM_WORLD, &solver);
CHKERR KSPSetDM(solver, dm_control);
CHKERR KSPSetFromOptions(solver);
CHKERR KSPSetDMActive(solver, PETSC_FALSE);
CHKERR KSPSetInitialGuessKnoll(solver, PETSC_FALSE);
CHKERR KSPSetInitialGuessNonzero(solver, PETSC_FALSE);
PC pc;
CHKERR PCSetType(pc, PCFIELDSPLIT);
PetscBool is_pcfs = PETSC_FALSE;
PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
if (is_pcfs) {
CHKERR PCFieldSplitSetIS(pc, NULL, nested_is_rows[0]);
CHKERR PCFieldSplitSetIS(pc, NULL, nested_is_rows[1]);
CHKERR PCFieldSplitSetType(pc, PC_COMPOSITE_SCHUR);
KSP *sub_ksp;
CHKERR PCFieldSplitGetSubKSP(pc, &
n, &sub_ksp);
{
PC sub_pc_0;
CHKERR KSPGetPC(sub_ksp[0], &sub_pc_0);
CHKERR PCSetOperators(sub_pc_0, SubA, SubA);
CHKERR PCSetType(sub_pc_0, PCFIELDSPLIT);
CHKERR PCFieldSplitSetIS(sub_pc_0, NULL, sub_nested_is_rows[0]);
CHKERR PCFieldSplitSetIS(sub_pc_0, NULL, sub_nested_is_rows[1]);
CHKERR PCFieldSplitSetType(sub_pc_0, PC_COMPOSITE_MULTIPLICATIVE);
}
} else {
"Only works with pre-conditioner PCFIELDSPLIT");
}
}
CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
SCATTER_REVERSE);
CHKERR VecView(
D, PETSC_VIEWER_DRAW_WORLD);
std::string wait;
std::cin >> wait;
}
for (
int i = 0;
i != 2;
i++) {
if (sub_nested_is_rows[
i]) {
CHKERR ISDestroy(&sub_nested_is_rows[
i]);
}
if (sub_nested_is_cols[
i]) {
CHKERR ISDestroy(&sub_nested_is_cols[
i]);
}
for (
int j = 0;
j != 2;
j++) {
if (sub_nested_matrices(
i,
j)) {
CHKERR MatDestroy(&sub_nested_matrices(
i,
j));
}
}
}
for (
int i = 0;
i != 2;
i++) {
CHKERR ISDestroy(&nested_is_rows[
i]);
}
CHKERR ISDestroy(&nested_is_cols[
i]);
}
for (
int j = 0;
j != 2;
j++) {
if (nested_matrices(
i,
j)) {
CHKERR MatDestroy(&nested_matrices(
i,
j));
}
}
}
CHKERR DMDestroy(&dm_sub_volume_control);
using PostProcVolume =
PostProcVolume post_proc(m_field, "my");
{
auto u_ptr = boost::make_shared<MatrixDouble>();
post_proc.getOpPtrVector().push_back(
auto hooke_common =
HookeOps::commonDataFactory<SPACE_DIM, GAUSS, DomainEleOp>(
m_field, post_proc.getOpPtrVector(), "U", "MAT_ELASTIC",
Sev::verbose);
post_proc.getOpPtrVector().push_back(new OpPPVolume(
post_proc.getPostProcMesh(), post_proc.getMapGaussPts(),
OpPPVolume::DataMapVec{}, OpPPVolume::DataMapMat{{"U", u_ptr}},
OpPPVolume::DataMapMat{{"U_GRAD", hooke_common->matGradPtr}},
OpPPVolume::DataMapMat{
{"STRESS", hooke_common->getMatCauchyStress()}}));
CHKERR post_proc.setTagsToTransfer({block_id_tag});
CHKERR post_proc.writeFile(
"out.h5m");
elastic_energy = 0;
&elastic_energy_fe);
double global_elastic_energy = 0;
CHKERR MPI_Allreduce(&elastic_energy, &global_elastic_energy, 1,
MPI_DOUBLE, MPI_SUM, m_field.
get_comm());
PetscPrintf(PETSC_COMM_WORLD, "Elastic energy %6.4e\n",
global_elastic_energy);
}
{
if (is_curl) {
{HCURL});
post_proc_face.getOpPtrVector().push_back(
} else {
post_proc_face.getOpPtrVector().push_back(
}
post_proc_face.getOpPtrVector().push_back(
post_proc_face.getMapGaussPts(), common_data));
CHKERR post_proc_face.writeFile(
"out_tractions.h5m");
}
CHKERR DMDestroy(&dm_control);
}
return 0;
}
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
@ HCURL
field with continuous tangents
#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 ...
@ MAT_ELASTICSET
block name is "MAT_ELASTIC"
@ MOFEM_STD_EXCEPTION_THROW
@ 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 DMMoFEMSetIsPartitioned(DM dm, PetscBool is_partitioned)
PetscErrorCode DMMoFEMCreateSubDM(DM subdm, DM dm, const char problem_name[])
Must be called by user to set Sub DM MoFEM data structures.
PetscErrorCode DMMoFEMAddElement(DM dm, std::string fe_name)
add element to dm
PetscErrorCode DMMoFEMSetSquareProblem(DM dm, PetscBool square_problem)
set squared problem
PetscErrorCode DMMoFEMCreateMoFEM(DM dm, MoFEM::Interface *m_field_ptr, const char problem_name[], const MoFEM::BitRefLevel bit_level, const MoFEM::BitRefLevel bit_mask=MoFEM::BitRefLevel().set())
Must be called by user to set MoFEM data structures.
PetscErrorCode DMoFEMPostProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
PetscErrorCode DMMoFEMAddSubFieldRow(DM dm, const char field_name[])
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode, RowColData rc=RowColData::COL)
set local (or ghosted) vector values on mesh for partition only
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
PetscErrorCode DMMoFEMAddSubFieldCol(DM dm, const char field_name[])
PetscErrorCode DMoFEMPreProcessFiniteElements(DM dm, MoFEM::FEMethod *method)
execute finite element method for each element in dm (problem)
virtual const Problem * get_problem(const std::string problem_name) const =0
Get the problem object.
virtual MoFEMErrorCode add_finite_element(const std::string &fe_name, enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
add finite element
virtual MoFEMErrorCode build_finite_elements(int verb=DEFAULT_VERBOSITY)=0
Build finite elements.
virtual MoFEMErrorCode modify_finite_element_add_field_col(const std::string &fe_name, const std::string name_row)=0
set field col which finite element use
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 modify_finite_element_add_field_row(const std::string &fe_name, const std::string name_row)=0
set field row which finite element use
virtual MoFEMErrorCode modify_finite_element_add_field_data(const std::string &fe_name, const std::string name_field)=0
set finite element field data
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 _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_BY_SET_TYPE_FOR_LOOP_(MESHSET_MANAGER, CUBITBCTYPE, IT)
Iterator that loops over a specific Cubit MeshSet having a particular BC meshset in a moFEM field.
FTensor::Index< 'i', SPACE_DIM > i
const double n
refractive index of diffusive medium
FTensor::Index< 'j', 3 > j
std::map< int, Range > ElasticBlockMap
const FTensor::Tensor2< T, Dim, Dim > Vec
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
decltype(GetFTensor2SymmetricFromMatImpl< Tensor_Dim, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor2SymmetricFromMatType
int getRule(int order) override
Calculate and assemble Z matrix.
Calculate and assemble Z matrix.
Calculate and assemble B matrix.
Calculate and assemble D matrix.
Calculate and assemble S matrix.
Calculate and assemble g vector.
boost::shared_ptr< MatrixDouble > stressPtr
boost::shared_ptr< MatrixDouble > strainPtr
MoFEMErrorCode doWork(int, EntityType, EntitiesFieldData::EntData &) override
Shave results on mesh tags for post-processing.
Boundary condition manager for finite element problem setup.
virtual FieldBitNumber get_field_bit_number(const std::string name) const =0
get field bit number
virtual MoFEMErrorCode build_adjacencies(const Range &ents, int verb=DEFAULT_VERBOSITY)=0
build adjacencies
virtual MoFEMErrorCode add_field(const std::string name, const FieldSpace space, const FieldApproximationBase base, const FieldCoefficientsNumber nb_of_coefficients, const TagType tag_type=MB_TAG_SPARSE, const enum MoFEMTypes bh=MF_EXCL, int verb=DEFAULT_VERBOSITY)=0
Add field.
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)
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.
default operator for Flat Prism element
Section manager is used to create indexes and sections.
Elastic material data structure.
Interface for managing meshsets containing materials and boundary conditions.
Calculate inverse of jacobian for face element.
Specialization for MatrixDouble vector field values calculation.
Post post-proc data at points from hash maps.
Transform local reference derivatives of shape functions to global derivatives.
keeps basic data about problem
MoFEMErrorCode getDofByNameEntAndEntDofIdx(const int field_bit_number, const EntityHandle ent, const int ent_dof_idx, const RowColData row_or_col, boost::shared_ptr< NumeredDofEntity > &dof_ptr) const
get DOFs from problem
boost::shared_ptr< SubProblemData > & getSubData() const
Get main problem of sub-problem is.
boost::shared_ptr< NumeredDofEntity_multiIndex > numeredRowDofsPtr
store DOFs on rows for this problem
intrusive_ptr for managing petsc objects
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
Volume finite element base.