#ifndef EXECUTABLE_DIMENSION
#define EXECUTABLE_DIMENSION 3
#endif
#ifndef FINITE_DEFORMATION_FLAG
#define FINITE_DEFORMATION_FLAG true
#endif
IntegrationType::GAUSS;
GAUSS>::OpEssentialRhs<HeatFluxCubitBcData, 3, SPACE_DIM>;
GAUSS>::OpEssentialLhs<HeatFluxCubitBcData, 3, SPACE_DIM>;
1;
auto save_range = [](moab::Interface &moab,
const std::string name,
auto out_meshset = get_temp_meshset_ptr(moab);
CHKERR moab.add_entities(*out_meshset, r);
CHKERR moab.write_file(name.c_str(),
"VTK",
"", out_meshset->get_ptr(), 1);
};
private:
boost::shared_ptr<FieldEvaluatorInterface::SetPtsData>
fieldEvalData;
struct BlockedThermalParameters
: public boost::enable_shared_from_this<BlockedThermalParameters> {
}
return boost::shared_ptr<double>(shared_from_this(), &
heatCapacity);
}
};
struct BlockedThermoElasticParameters
: public boost::enable_shared_from_this<BlockedThermoElasticParameters> {
return boost::shared_ptr<VectorDouble>(shared_from_this(),
}
return boost::shared_ptr<double>(shared_from_this(), &
refTemp);
}
};
boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
std::string block_name,
boost::shared_ptr<BlockedThermalParameters> blockedParamsPtr, Sev sev);
boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
std::string block_name,
boost::shared_ptr<BlockedThermoElasticParameters> blockedParamsPtr,
Sev sev);
template <int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp>
boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
boost::shared_ptr<HenckyOps::CommonData> elastic_common_ptr,
boost::shared_ptr<ThermoElasticProblem::BlockedThermalParameters>
thermal_common_ptr,
boost::shared_ptr<ThermoElasticProblem::BlockedThermoElasticParameters>
thermoelastic_common_ptr,
Sev sev) {
auto vec_temp_ptr = boost::make_shared<VectorDouble>();
auto coeff_expansion_ptr = thermoelastic_common_ptr->getCoeffExpansionPtr();
auto ref_temp_ptr = thermoelastic_common_ptr->getRefTempPtr();
pip.push_back(
new typename H::template OpCalculateHenckyThermalStress<DIM, I, 0>(
"U", vec_temp_ptr, elastic_common_ptr, coeff_expansion_ptr,
ref_temp_ptr));
"U", elastic_common_ptr->getMatFirstPiolaStress()));
}
template <int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp>
boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
std::string
field_name, std::string elastic_block_name,
std::string thermal_block_name, std::string thermoelastic_block_name,
Sev sev,
double scale = 1) {
auto thermal_common_ptr = boost::make_shared<BlockedThermalParameters>();
Sev::inform);
auto thermoelastic_common_ptr =
boost::make_shared<BlockedThermoElasticParameters>();
thermoelastic_common_ptr, Sev::inform);
m_field, pip,
field_name, elastic_common_ptr, thermal_common_ptr,
thermoelastic_common_ptr, sev);
}
template <int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp>
boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
std::string
field_name, std::string coupled_field_name,
boost::shared_ptr<HenckyOps::CommonData> elastic_common_ptr,
boost::shared_ptr<ThermoElasticProblem::BlockedThermalParameters>
thermal_common_ptr,
boost::shared_ptr<ThermoElasticProblem::BlockedThermoElasticParameters>
thermoelastic_common_ptr,
Sev sev) {
using OpKPiola =
typename B::template OpGradTensorGrad<1, DIM, DIM, 1>;
auto vec_temp_ptr = boost::make_shared<VectorDouble>();
auto coeff_expansion_ptr = thermoelastic_common_ptr->getCoeffExpansionPtr();
auto ref_temp_ptr = thermoelastic_common_ptr->getRefTempPtr();
pip.push_back(
new typename H::template OpCalculateHenckyThermalStress<DIM, I, 0>(
"U", vec_temp_ptr, elastic_common_ptr, coeff_expansion_ptr,
ref_temp_ptr));
pip.push_back(new typename H::template OpHenckyTangent<DIM, I, 0>(
elastic_common_ptr->getMatTangent()));
pip.push_back(new typename H::template OpCalculateHenckyThermalStressdT<
field_name, coupled_field_name, elastic_common_ptr,
coeff_expansion_ptr));
}
template <int DIM, AssemblyType A, IntegrationType I, typename DomainEleOp>
boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pip,
std::string
field_name, std::string coupled_field_name,
std::string elastic_block_name, std::string thermal_block_name,
std::string thermoelastic_block_name, Sev sev,
double scale = 1) {
auto thermal_common_ptr = boost::make_shared<BlockedThermalParameters>();
Sev::inform);
auto thermoelastic_common_ptr =
boost::make_shared<BlockedThermoElasticParameters>();
thermoelastic_common_ptr, Sev::inform);
m_field, pip,
field_name, coupled_field_name, elastic_common_ptr,
thermal_common_ptr, thermoelastic_common_ptr, sev);
}
};
boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
std::string block_name,
boost::shared_ptr<BlockedThermalParameters> blockedParamsPtr, Sev sev) {
OpMatThermalBlocks(boost::shared_ptr<double> conductivity_ptr,
boost::shared_ptr<double> capacity_ptr,
std::vector<const CubitMeshSets *> meshset_vec_ptr)
conductivityPtr(conductivity_ptr), capacityPtr(capacity_ptr) {
"Cannot get data from thermal block");
}
for (auto &b : blockData) {
if (b.blockEnts.find(getFEEntityHandle()) != b.blockEnts.end()) {
*conductivityPtr = b.conductivity;
*capacityPtr = b.capacity;
}
}
}
private:
double conductivity;
double capacity;
};
std::vector<BlockData> blockData;
std::vector<const CubitMeshSets *> meshset_vec_ptr,
Sev sev) {
for (
auto m : meshset_vec_ptr) {
std::vector<double> block_data;
CHKERR m->getAttributes(block_data);
if (block_data.size() < 2) {
"Expected that block has at least two attributes");
}
auto get_block_ents = [&]() {
m_field.
get_moab().get_entities_by_handle(
m->meshset, ents,
true);
return ents;
};
<<
m->getName() <<
": conductivity = " << block_data[0]
<< " capacity = " << block_data[1];
blockData.push_back({block_data[0], block_data[1], get_block_ents()});
}
}
boost::shared_ptr<double> conductivityPtr;
boost::shared_ptr<double> capacityPtr;
};
pipeline.push_back(new OpMatThermalBlocks(
blockedParamsPtr->getHeatConductivityPtr(),
blockedParamsPtr->getHeatCapacityPtr(),
mField, sev,
(boost::format("%s(.*)") % block_name).str()
))
));
}
boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
std::string block_name,
boost::shared_ptr<BlockedThermoElasticParameters> blockedParamsPtr,
Sev sev) {
OpMatThermoElasticBlocks(boost::shared_ptr<VectorDouble> expansion_ptr,
boost::shared_ptr<double> ref_temp_ptr,
std::vector<const CubitMeshSets *> meshset_vec_ptr)
expansionPtr(expansion_ptr), refTempPtr(ref_temp_ptr) {
extractThermoElasticBlockData(m_field, meshset_vec_ptr, sev),
"Cannot get data from thermoelastic block");
}
for (auto &b : blockData) {
if (b.blockEnts.find(getFEEntityHandle()) != b.blockEnts.end()) {
*expansionPtr = b.expansion;
*refTempPtr = b.ref_temp;
}
}
}
private:
double ref_temp;
VectorDouble expansion;
};
std::vector<BlockData> blockData;
std::vector<const CubitMeshSets *> meshset_vec_ptr, Sev sev) {
for (
auto m : meshset_vec_ptr) {
std::vector<double> block_data;
CHKERR m->getAttributes(block_data);
if (block_data.size() < 2) {
"Expected that block has at least two attributes");
}
auto get_block_ents = [&]() {
m_field.
get_moab().get_entities_by_handle(
m->meshset, ents,
true);
return ents;
};
auto get_expansion = [&]() {
VectorDouble expansion(
SPACE_DIM, block_data[1]);
if (block_data.size() > 2) {
expansion[1] = block_data[2];
}
if (
SPACE_DIM == 3 && block_data.size() > 3) {
expansion[2] = block_data[3];
}
return expansion;
};
auto coeff_exp_vec = get_expansion();
<< " ref_temp = " << block_data[0]
<< " expansion = " << coeff_exp_vec;
blockData.push_back({block_data[0], coeff_exp_vec, get_block_ents()});
}
}
boost::shared_ptr<VectorDouble> expansionPtr;
boost::shared_ptr<double> refTempPtr;
};
pipeline.push_back(new OpMatThermoElasticBlocks(
blockedParamsPtr->getCoeffExpansionPtr(),
blockedParamsPtr->getRefTempPtr(),
mField, sev,
(boost::format("%s(.*)") % block_name).str()
))
));
}
}
auto get_command_line_parameters = [&]() {
PETSC_NULLPTR);
PETSC_NULLPTR);
PETSC_NULLPTR);
PETSC_NULLPTR);
PETSC_NULLPTR);
PETSC_NULLPTR);
PETSC_NULLPTR);
} else {
}
PETSC_NULLPTR);
};
CHKERR get_command_line_parameters();
}
CHKERR simple->addBoundaryField(
"FLUX", flux_space, base, 1);
int coords_dim = 3;
auto no_rule = [](int, int, int) { return -1; };
field_eval_fe_ptr->getRuleHook = no_rule;
auto block_thermal_params = boost::make_shared<BlockedThermalParameters>();
auto block_thermoelastic_params =
boost::make_shared<BlockedThermoElasticParameters>();
auto coeff_expansion_ptr =
block_thermoelastic_params->getCoeffExpansionPtr();
auto ref_temp_ptr = block_thermoelastic_params->getRefTempPtr();
"MAT_THERMAL", block_thermal_params,
Sev::verbose);
field_eval_fe_ptr->getOpPtrVector(), "MAT_THERMOELASTIC",
block_thermoelastic_params, Sev::verbose);
field_eval_fe_ptr->getOpPtrVector(), {H1, HDIV});
auto hencky_common_data_ptr =
mField, field_eval_fe_ptr->getOpPtrVector(),
"U",
"MAT_ELASTIC",
Sev::inform);
auto mat_D_ptr = hencky_common_data_ptr->matDPtr;
auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
field_eval_fe_ptr->getOpPtrVector().push_back(
field_eval_fe_ptr->getOpPtrVector().push_back(
field_eval_fe_ptr->getOpPtrVector().push_back(
field_eval_fe_ptr->getOpPtrVector().push_back(
field_eval_fe_ptr->getOpPtrVector().push_back(
new
typename H::template OpCalculateHenckyThermalStress<SPACE_DIM, IT, 0>(
"U",
tempFieldPtr, hencky_common_data_ptr, coeff_expansion_ptr,
ref_temp_ptr));
field_eval_fe_ptr->getOpPtrVector().push_back(
hencky_common_data_ptr->getMatFirstPiolaStress(),
field_eval_fe_ptr->getOpPtrVector().push_back(
} else {
field_eval_fe_ptr->getOpPtrVector().push_back(
new typename H::template OpCalculateLogC<SPACE_DIM, IT>(
"U", hencky_common_data_ptr));
};
}
}
auto get_skin = [&]() {
CHKERR skin.find_skin(0, body_ents,
false, skin_ents);
return skin_ents;
};
auto filter_flux_blocks = [&](auto skin, bool temp_bc = false) {
auto remove_cubit_blocks = [&](
auto c) {
) {
skin = subtract(skin, ents);
}
};
auto remove_named_blocks = [&](
auto n) {
std::regex(
(boost::format(
"%s(.*)") %
n).str()
))
) {
skin = subtract(skin, ents);
}
};
if (!temp_bc) {
"remove_cubit_blocks");
"remove_named_blocks");
}
"remove_cubit_blocks");
return skin;
};
ParallelComm *pcomm =
CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
PSTATUS_NOT, -1, &boundary_ents);
return boundary_ents;
};
auto remove_temp_bc_ents =
remove_flux_ents);
remove_temp_bc_ents);
MOFEM_LOG(
"SYNC", Sev::noisy) << remove_flux_ents << endl;
MOFEM_LOG(
"SYNC", Sev::noisy) << remove_temp_bc_ents << endl;
#ifndef NDEBUG
remove_flux_ents);
remove_temp_bc_ents);
#endif
simple->getProblemName(),
"FLUX", remove_flux_ents);
simple->getProblemName(),
"TBC", remove_temp_bc_ents);
auto set_init_temp = [](boost::shared_ptr<FieldEntity> field_entity_ptr) {
return 0;
};
"T");
simple->getProblemName(),
"U");
CHKERR bc_mng->pushMarkDOFsOnEntities<HeatFluxCubitBcData>(
simple->getProblemName(),
"FLUX",
false);
}
auto boundary_marker =
bc_mng->getMergedBlocksMarker(vector<string>{"HEATFLUX"});
};
auto block_thermal_params = boost::make_shared<BlockedThermalParameters>();
auto heat_conductivity_ptr = block_thermal_params->getHeatConductivityPtr();
auto heat_capacity_ptr = block_thermal_params->getHeatCapacityPtr();
auto block_thermoelastic_params =
boost::make_shared<BlockedThermoElasticParameters>();
auto coeff_expansion_ptr = block_thermoelastic_params->getCoeffExpansionPtr();
auto ref_temp_ptr = block_thermoelastic_params->getRefTempPtr();
auto time_scale =
boost::make_shared<TimeScale>("", false, [](const double) { return 1; });
auto def_time_scale = [time_scale](const double time) {
return (!time_scale->argFileScale) ? time : 1;
};
auto def_file_name = [time_scale](const std::string &&name) {
return (!time_scale->argFileScale) ? name : "";
};
auto time_bodyforce_scaling = boost::make_shared<TimeScale>(
def_file_name("bodyforce_scale.txt"), false, def_time_scale);
auto time_heatsource_scaling = boost::make_shared<TimeScale>(
def_file_name("heatsource_scale.txt"), false, def_time_scale);
auto time_temperature_scaling = boost::make_shared<TimeScale>(
def_file_name("temperature_bc_scale.txt"), false, def_time_scale);
auto time_displacement_scaling = boost::make_shared<TimeScale>(
def_file_name("displacement_bc_scale.txt"), false, def_time_scale);
auto time_flux_scaling = boost::make_shared<TimeScale>(
def_file_name("flux_bc_scale.txt"), false, def_time_scale);
auto time_force_scaling = boost::make_shared<TimeScale>(
def_file_name("force_bc_scale.txt"), false, def_time_scale);
auto add_domain_rhs_ops = [&](auto &pipeline) {
Sev::inform);
block_thermoelastic_params, Sev::inform);
auto hencky_common_data_ptr =
mField, pipeline,
"U",
"MAT_ELASTIC", Sev::inform);
auto mat_D_ptr = hencky_common_data_ptr->matDPtr;
auto mat_grad_ptr = hencky_common_data_ptr->matGradPtr;
auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
auto vec_temp_ptr = boost::make_shared<VectorDouble>();
auto vec_temp_dot_ptr = boost::make_shared<VectorDouble>();
auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
auto vec_temp_div_ptr = boost::make_shared<VectorDouble>();
pipeline.push_back(
"FLUX", vec_temp_div_ptr));
pipeline.push_back(
mField, pipeline,
"U",
"MAT_ELASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC", Sev::inform);
auto resistance = [heat_conductivity_ptr](
const double,
const double,
return (1. / (*heat_conductivity_ptr));
};
auto capacity = [heat_capacity_ptr](
const double,
const double,
return -(*heat_capacity_ptr);
};
return -1.;
};
pipeline.push_back(
new OpHdivFlux(
"FLUX", mat_flux_ptr, resistance, mat_grad_ptr));
pipeline.push_back(
new OpHDivTemp(
"FLUX", vec_temp_ptr, unity));
pipeline.push_back(
new OpBaseDivFlux(
"T", vec_temp_div_ptr, unity));
pipeline.push_back(
new OpBaseDotT(
"T", vec_temp_dot_ptr, capacity));
CHKERR DomainNaturalBCRhs::AddFluxToPipeline<OpHeatSource>::add(
pipeline,
mField,
"T", {time_scale, time_heatsource_scaling},
"HEAT_SOURCE", Sev::inform);
CHKERR DomainNaturalBCRhs::AddFluxToPipeline<OpBodyForce>::add(
pipeline,
mField,
"U", {time_scale, time_bodyforce_scaling},
"BODY_FORCE", Sev::inform);
CHKERR DomainNaturalBCRhs::AddFluxToPipeline<OpSetTemperatureRhs>::add(
pipeline,
mField,
"T", vec_temp_ptr,
"SETTEMP", Sev::inform);
};
auto add_domain_lhs_ops = [&](auto &pipeline) {
Sev::verbose);
block_thermoelastic_params,
Sev::verbose);
auto hencky_common_data_ptr =
mField, pipeline,
"U",
"MAT_ELASTIC", Sev::inform, 1);
auto mat_D_ptr = hencky_common_data_ptr->matDPtr;
auto mat_grad_ptr = hencky_common_data_ptr->matGradPtr;
auto resistance = [heat_conductivity_ptr](
const double,
const double,
return (1. / (*heat_conductivity_ptr));
};
auto capacity = [heat_capacity_ptr](
const double,
const double,
return -(*heat_capacity_ptr);
};
pipeline.push_back(
new OpHdivHdiv(
"FLUX",
"FLUX", resistance, mat_grad_ptr));
pipeline.push_back(
new OpHdivT(
"FLUX",
"T", []()
constexpr {
return -1; },
true));
auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
pipeline.push_back(
pipeline.push_back(
new OpHdivU(
"FLUX",
"U", mat_flux_ptr, resistance, mat_grad_ptr));
mField, pipeline,
"U",
"T",
"MAT_ELASTIC",
"MAT_THERMAL",
"MAT_THERMOELASTIC", Sev::inform);
auto op_capacity =
new OpCapacity(
"T",
"T", capacity);
op_capacity->feScalingFun = [](
const FEMethod *fe_ptr) {
return fe_ptr->ts_a;
};
pipeline.push_back(op_capacity);
auto vec_temp_ptr = boost::make_shared<VectorDouble>();
CHKERR DomainNaturalBCLhs::AddFluxToPipeline<OpSetTemperatureLhs>::add(
pipeline,
mField,
"T", vec_temp_ptr,
"SETTEMP", Sev::verbose);
};
auto add_boundary_rhs_ops = [&](auto &pipeline) {
CHKERR BoundaryNaturalBC::AddFluxToPipeline<OpForce>::add(
pipeline,
mField,
"U", {time_scale, time_force_scaling},
"FORCE",
Sev::inform);
BoundaryNaturalBC::OpFlux<NaturalTemperatureMeshsets, 3, SPACE_DIM>;
CHKERR BoundaryNaturalBC::AddFluxToPipeline<OpTemperatureBC>::add(
pipeline,
mField,
"FLUX", {time_scale, time_temperature_scaling},
"TEMPERATURE", Sev::inform);
using OpFluxBC =
BoundaryNaturalBC::OpFlux<NaturalMeshsetType<HEATFLUXSET>, 1, 1>;
CHKERR BoundaryNaturalBC::AddFluxToPipeline<OpFluxBC>::add(
pipeline,
mField,
"TBC", {time_scale, time_flux_scaling},
"FLUX",
Sev::inform);
using OpConvectionRhsBC =
T::OpFlux<ThermoElasticOps::ConvectionBcType<BLOCKSET>, 1, 1>;
using OpRadiationRhsBC =
T::OpFlux<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1>;
auto temp_bc_ptr = boost::make_shared<VectorDouble>();
T::AddFluxToPipeline<OpConvectionRhsBC>::add(
pipeline,
mField,
"TBC", temp_bc_ptr,
"CONVECTION", Sev::inform);
T::AddFluxToPipeline<OpRadiationRhsBC>::add(
pipeline,
mField,
"TBC", temp_bc_ptr,
"RADIATION", Sev::inform);
auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
pipeline.push_back(
struct OpTBCTimesNormalFlux
OpTBCTimesNormalFlux(
const std::string
field_name,
boost::shared_ptr<MatrixDouble> vec,
boost::shared_ptr<Range> ents_ptr = nullptr)
auto t_w = OP::getFTensor0IntegrationWeight();
auto t_normal = OP::getFTensor1NormalsAtGaussPts();
auto t_vec = getFTensor1FromMat<SPACE_DIM, 1>(*sourceVec);
for (int gg = 0; gg != OP::nbIntegrationPts; gg++) {
const double alpha = t_w * (t_vec(
i) * t_normal(
i));
int rr = 0;
for (; rr != OP::nbRows; ++rr) {
OP::locF[rr] += alpha * t_row_base;
++t_row_base;
}
for (; rr < OP::nbRowBaseFunctions; ++rr)
++t_row_base;
++t_w;
++t_vec;
++t_normal;
}
EntityType fe_type = OP::getNumeredEntFiniteElementPtr()->getEntType();
if (fe_type == MBTRI) {
OP::locF /= 2;
}
}
protected:
boost::shared_ptr<MatrixDouble> sourceVec;
};
pipeline.push_back(new OpTBCTimesNormalFlux("TBC", mat_flux_ptr));
struct OpBaseNormalTimesTBC
OpBaseNormalTimesTBC(
const std::string
field_name,
boost::shared_ptr<VectorDouble> vec,
boost::shared_ptr<Range> ents_ptr = nullptr)
auto t_w = OP::getFTensor0IntegrationWeight();
auto t_normal = OP::getFTensor1NormalsAtGaussPts();
auto t_vec = getFTensor0FromVec(*sourceVec);
for (int gg = 0; gg != OP::nbIntegrationPts; gg++) {
const double alpha = t_w * t_vec;
int rr = 0;
for (; rr != OP::nbRows; ++rr) {
OP::locF[rr] += alpha * (t_row_base(
i) * t_normal(
i));
++t_row_base;
}
for (; rr < OP::nbRowBaseFunctions; ++rr)
++t_row_base;
++t_w;
++t_vec;
++t_normal;
}
EntityType fe_type = OP::getNumeredEntFiniteElementPtr()->getEntType();
if (fe_type == MBTRI) {
OP::locF /= 2;
}
}
protected:
boost::shared_ptr<VectorDouble> sourceVec;
};
pipeline.push_back(new OpBaseNormalTimesTBC("FLUX", temp_bc_ptr));
};
auto add_boundary_lhs_ops = [&](auto &pipeline) {
using T =
using OpConvectionLhsBC =
T::OpFlux<ThermoElasticOps::ConvectionBcType<BLOCKSET>, 1, 1>;
using OpRadiationLhsBC =
T::OpFlux<ThermoElasticOps::RadiationBcType<BLOCKSET>, 1, 1>;
auto temp_bc_ptr = boost::make_shared<VectorDouble>();
T::AddFluxToPipeline<OpConvectionLhsBC>::add(pipeline,
mField,
"TBC",
"TBC",
"CONVECTION", Sev::verbose);
T::AddFluxToPipeline<OpRadiationLhsBC>::add(
pipeline,
mField,
"TBC",
"TBC", temp_bc_ptr,
"RADIATION", Sev::verbose);
struct OpTBCTimesNormalFlux
OpTBCTimesNormalFlux(const std::string row_field_name,
const std::string col_field_name,
boost::shared_ptr<Range> ents_ptr = nullptr)
:
OP(row_field_name, col_field_name,
OP::OPROWCOL, ents_ptr) {
this->sYmm = false;
this->assembleTranspose = true;
this->onlyTranspose = false;
}
auto t_w = OP::getFTensor0IntegrationWeight();
auto t_normal = OP::getFTensor1NormalsAtGaussPts();
for (int gg = 0; gg != OP::nbIntegrationPts; gg++) {
auto a_mat_ptr = &*OP::locMat.data().begin();
int rr = 0;
for (; rr != OP::nbRows; rr++) {
const double alpha = t_w * t_row_base;
for (int cc = 0; cc != OP::nbCols; cc++) {
*a_mat_ptr += alpha * (t_col_base(
i) * t_normal(
i));
++t_col_base;
++a_mat_ptr;
}
++t_row_base;
}
for (; rr < OP::nbRowBaseFunctions; ++rr)
++t_row_base;
++t_normal;
++t_w;
}
EntityType fe_type = OP::getNumeredEntFiniteElementPtr()->getEntType();
if (fe_type == MBTRI) {
OP::locMat /= 2;
}
}
};
pipeline.push_back(new OpTBCTimesNormalFlux("TBC", "FLUX"));
};
auto get_bc_hook_rhs = [&]() {
mField, pipeline_mng->getDomainRhsFE(),
{time_scale, time_displacement_scaling});
return hook;
};
auto get_bc_hook_lhs = [&]() {
mField, pipeline_mng->getDomainLhsFE(),
{time_scale, time_displacement_scaling});
return hook;
};
pipeline_mng->getDomainRhsFE()->preProcessHook = get_bc_hook_rhs();
pipeline_mng->getDomainLhsFE()->preProcessHook = get_bc_hook_lhs();
CHKERR add_domain_rhs_ops(pipeline_mng->getOpDomainRhsPipeline());
CHKERR add_domain_lhs_ops(pipeline_mng->getOpDomainLhsPipeline());
CHKERR add_boundary_rhs_ops(pipeline_mng->getOpBoundaryRhsPipeline());
CHKERR add_boundary_lhs_ops(pipeline_mng->getOpBoundaryLhsPipeline());
}
auto solver = pipeline_mng->createTSIM();
auto set_section_monitor = [&](auto solver) {
SNES snes;
CHKERR TSGetSNES(solver, &snes);
(void *)(snes_ctx_ptr.get()), nullptr);
};
auto create_post_process_elements = [&]() {
auto block_thermal_params = boost::make_shared<BlockedThermalParameters>();
auto block_thermoelastic_params =
boost::make_shared<BlockedThermoElasticParameters>();
auto coeff_expansion_ptr =
block_thermoelastic_params->getCoeffExpansionPtr();
auto ref_temp_ptr = block_thermoelastic_params->getRefTempPtr();
auto u_ptr = boost::make_shared<MatrixDouble>();
auto mat_grad_ptr = boost::make_shared<MatrixDouble>();
auto mat_strain_ptr = boost::make_shared<MatrixDouble>();
auto mat_stress_ptr = boost::make_shared<MatrixDouble>();
auto vec_temp_ptr = boost::make_shared<VectorDouble>();
auto mat_flux_ptr = boost::make_shared<MatrixDouble>();
auto push_domain_ops = [&](auto &pp_fe) {
auto &pip = pp_fe->getOpPtrVector();
Sev::verbose);
pip, "MAT_THERMOELASTIC", block_thermoelastic_params, Sev::verbose);
pip.push_back(
"U", mat_grad_ptr));
mField, pip,
"U",
"MAT_ELASTIC", Sev::inform);
pip.push_back(
new
typename H::template OpCalculateHenckyThermalStress<SPACE_DIM, IT, 0>(
"U", vec_temp_ptr, elastic_common_ptr, coeff_expansion_ptr,
ref_temp_ptr));
elastic_common_ptr->getMatFirstPiolaStress(), mat_stress_ptr));
pip.push_back(
} else {
mat_stress_ptr = elastic_common_ptr->getMatFirstPiolaStress();
mat_strain_ptr = elastic_common_ptr->getMatLogC();
}
};
auto push_post_proc_ops = [&](auto &pp_fe) {
auto &pip = pp_fe->getOpPtrVector();
pip.push_back(
pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
{{"T", vec_temp_ptr}},
{{"U", u_ptr}, {"FLUX", mat_flux_ptr}},
{},
{{"CAUCHY", mat_stress_ptr}, {"STRAIN", mat_strain_ptr}}
)
);
} else {
pip.push_back(
pp_fe->getPostProcMesh(), pp_fe->getMapGaussPts(),
{{"T", vec_temp_ptr}},
{{"U", u_ptr}, {"FLUX", mat_flux_ptr}},
{{"PIOLA", mat_stress_ptr}},
{{"HENCKY_STRAIN", mat_strain_ptr}}
)
);
}
};
auto domain_post_proc = [&]() {
return boost::shared_ptr<PostProcEle>();
auto pp_fe = boost::make_shared<PostProcEle>(mField);
"push domain ops to domain element");
"push post proc ops to domain element");
return pp_fe;
};
auto skin_post_proc = [&]() {
return boost::shared_ptr<SkinPostProcEle>();
auto pp_fe = boost::make_shared<SkinPostProcEle>(mField);
"push domain ops to side element");
pp_fe->getOpPtrVector().push_back(op_side);
"push post proc ops to skin element");
return pp_fe;
};
return std::make_pair(domain_post_proc(), skin_post_proc());
};
auto monitor_ptr = boost::make_shared<FEMethod>();
auto set_time_monitor = [&](auto dm, auto solver, auto domain_post_proc_fe,
auto skin_post_proc_fe) {
monitor_ptr->preProcessHook = [&]() {
domain_post_proc_fe,
monitor_ptr->getCacheWeakPtr());
CHKERR domain_post_proc_fe->writeFile(
"out_" + boost::lexical_cast<std::string>(monitor_ptr->ts_step) +
".h5m");
}
skin_post_proc_fe,
monitor_ptr->getCacheWeakPtr());
CHKERR skin_post_proc_fe->writeFile(
"out_skin_" +
boost::lexical_cast<std::string>(monitor_ptr->ts_step) + ".h5m");
}
}
->evalFEAtThePoint<SPACE_DIM>(
fieldEvalCoords.data(), 1e-12,
simple->getProblemName(),
simple->getDomainFEName(), fieldEvalData,
auto eval_num_vec =
CHKERR VecZeroEntries(eval_num_vec);
if (tempFieldPtr->size()) {
CHKERR VecSetValue(eval_num_vec, 0, 1, ADD_VALUES);
}
CHKERR VecAssemblyBegin(eval_num_vec);
CHKERR VecAssemblyEnd(eval_num_vec);
double eval_num;
CHKERR VecSum(eval_num_vec, &eval_num);
if (!(int)eval_num) {
"atom test %d failed: did not find elements to evaluate "
"the field, check the coordinates",
}
}
if (tempFieldPtr->size()) {
auto t_temp = getFTensor0FromVec(*tempFieldPtr);
<< "Eval point T: " << t_temp;
if (
atom_test && fabs(monitor_ptr->ts_t - 10) < 1e-12) {
if (
atom_test <= 3 && fabs(t_temp - 554.48) > 1e-2) {
"atom test %d failed: wrong temperature value",
}
if (
atom_test == 4 && fabs(t_temp - 250) > 1e-2) {
"atom test %d failed: wrong temperature value",
}
if (
atom_test == 5 && fabs(t_temp - 1) > 1e-2) {
"atom test %d failed: wrong temperature value",
}
}
}
if (fluxFieldPtr->size1()) {
auto t_flux = getFTensor1FromMat<SPACE_DIM>(*fluxFieldPtr);
auto flux_mag = sqrt(t_flux(
i) * t_flux(
i));
<< "Eval point FLUX magnitude: " << flux_mag;
if (
atom_test && fabs(monitor_ptr->ts_t - 10) < 1e-12) {
if (
atom_test <= 3 && fabs(flux_mag - 27008.0) > 2e1) {
"atom test %d failed: wrong flux value",
atom_test);
}
if (
atom_test == 4 && fabs(flux_mag - 150e3) > 1e-1) {
"atom test %d failed: wrong flux value",
atom_test);
}
if (
atom_test == 5 && fabs(flux_mag) > 1e-6) {
"atom test %d failed: wrong flux value",
atom_test);
}
}
}
if (dispFieldPtr->size1()) {
auto t_disp = getFTensor1FromMat<SPACE_DIM>(*dispFieldPtr);
auto disp_mag = sqrt(t_disp(
i) * t_disp(
i));
<< "Eval point U magnitude: " << disp_mag;
if (
atom_test && fabs(monitor_ptr->ts_t - 10) < 1e-12) {
if (
atom_test == 1 && fabs(disp_mag - 0.00345) > 1e-5) {
"atom test %d failed: wrong displacement value",
}
fabs(disp_mag - 0.00265) > 1e-5) {
"atom test %d failed: wrong displacement value",
}
fabs(t_disp(0) - (std::sqrt(std::exp(0.2)) - 1)) > 1e-5 &&
fabs(t_disp(1) - (std::sqrt(std::exp(0.2)) - 1)) > 1e-5) {
"atom test %d failed: wrong displacement value",
}
}
}
if (strainFieldPtr->size1()) {
auto t_strain =
getFTensor2SymmetricFromMat<SPACE_DIM>(*strainFieldPtr);
auto t_strain_trace = t_strain(
i,
i);
if (
atom_test && fabs(monitor_ptr->ts_t - 10) < 1e-12) {
if (
atom_test == 1 && fabs(t_strain_trace - 0.00679) > 1e-5) {
"atom test %d failed: wrong strain value",
atom_test);
}
fabs(t_strain_trace - 0.00522) > 1e-5) {
"atom test %d failed: wrong strain value",
atom_test);
}
if ((
atom_test == 5) && fabs(t_strain_trace - 0.2) > 1e-5) {
"atom test %d failed: wrong strain value",
atom_test);
}
}
}
if (stressFieldPtr->size1()) {
double von_mises_stress;
auto getVonMisesStress = [&](auto t_stress) {
von_mises_stress = std::sqrt(
0.5 *
((t_stress(0, 0) - t_stress(1, 1)) *
(t_stress(0, 0) - t_stress(1, 1)) +
(
SPACE_DIM == 3 ? (t_stress(1, 1) - t_stress(2, 2)) *
(t_stress(1, 1) - t_stress(2, 2))
: 0) +
(
SPACE_DIM == 3 ? (t_stress(2, 2) - t_stress(0, 0)) *
(t_stress(2, 2) - t_stress(0, 0))
: 0) +
6 * (t_stress(0, 1) * t_stress(0, 1) +
(
SPACE_DIM == 3 ? t_stress(1, 2) * t_stress(1, 2) : 0) +
(
SPACE_DIM == 3 ? t_stress(2, 0) * t_stress(2, 0) : 0))));
};
auto t_stress =
getFTensor2SymmetricFromMat<SPACE_DIM>(*stressFieldPtr);
CHKERR getVonMisesStress(t_stress);
} else {
auto t_stress =
getFTensor2FromMat<SPACE_DIM, SPACE_DIM>(*stressFieldPtr);
CHKERR getVonMisesStress(t_stress);
}
<< "Eval point von Mises Stress: " << von_mises_stress;
if (
atom_test && fabs(monitor_ptr->ts_t - 10) < 1e-12) {
if (
atom_test == 1 && fabs(von_mises_stress - 523.0) > 5e-1) {
"atom test %d failed: wrong von Mises stress value",
}
if (
atom_test == 2 && fabs(von_mises_stress - 16.3) > 5e-2) {
"atom test %d failed: wrong von Mises stress value",
}
if (
atom_test == 3 && fabs(von_mises_stress - 14.9) > 5e-2) {
"atom test %d failed: wrong von Mises stress value",
}
if (
atom_test == 5 && fabs(von_mises_stress) > 5e-2) {
"atom test %d failed: wrong von Mises stress value",
}
}
}
}
};
auto null = boost::shared_ptr<FEMethod>();
monitor_ptr, null);
};
auto set_fieldsplit_preconditioner = [&](auto solver) {
SNES snes;
CHKERR TSGetSNES(solver, &snes);
KSP ksp;
CHKERR SNESGetKSP(snes, &ksp);
PC pc;
PetscBool is_pcfs = PETSC_FALSE;
PetscObjectTypeCompare((PetscObject)pc, PCFIELDSPLIT, &is_pcfs);
if (is_pcfs == PETSC_TRUE) {
auto name_prb =
simple->getProblemName();
CHKERR is_mng->isCreateProblemFieldAndRank(name_prb,
ROW,
"U", 0,
CHKERR is_mng->isCreateProblemFieldAndRank(name_prb,
ROW,
"FLUX", 0, 0,
is_flux);
CHKERR is_mng->isCreateProblemFieldAndRank(name_prb,
ROW,
"T", 0, 0,
is_T);
CHKERR is_mng->isCreateProblemFieldAndRank(name_prb,
ROW,
"TBC", 0, 0,
is_TBC);
IS is_tmp, is_tmp2;
CHKERR ISExpand(is_T, is_flux, &is_tmp);
CHKERR ISExpand(is_TBC, is_tmp, &is_tmp2);
CHKERR PCFieldSplitSetIS(pc, PETSC_NULLPTR, is_TFlux);
CHKERR PCFieldSplitSetIS(pc, PETSC_NULLPTR, is_u);
}
};
CHKERR TSSetIJacobian(solver,
B,
B, PETSC_NULLPTR, PETSC_NULLPTR);
CHKERR TSSetFromOptions(solver);
CHKERR set_section_monitor(solver);
CHKERR set_fieldsplit_preconditioner(solver);
auto [domain_post_proc_fe, skin_post_proc_fe] =
create_post_process_elements();
CHKERR set_time_monitor(dm, solver, domain_post_proc_fe, skin_post_proc_fe);
}
static char help[] =
"...\n\n";
int main(
int argc,
char *argv[]) {
const char param_file[] = "param_file.petsc";
auto core_log = logging::core::get();
core_log->add_sink(
LogManager::createSink(LogManager::getStrmWorld(), "ThermoElastic"));
LogManager::setLog("ThermoElastic");
core_log->add_sink(
LogManager::createSink(LogManager::getStrmSync(), "ThermoElasticSync"));
LogManager::setLog("ThermoElasticSync");
try {
DMType dm_name = "DMMOFEM";
moab::Core mb_instance;
moab::Interface &moab = mb_instance;
}
}
static auto filter_true_skin(MoFEM::Interface &m_field, Range &&skin)
Operators for Piola transformation of the thermal conductivity.
#define MOFEM_LOG_SEVERITY_SYNC(comm, severity)
Synchronise "SYNC" on curtain severity level.
#define MOFEM_LOG_SYNCHRONISE(comm)
Synchronise "SYNC" channel.
#define MOFEM_TAG_AND_LOG(channel, severity, tag)
Tag and log in channel.
#define FTENSOR_INDEX(DIM, I)
Implementation of thermal convection bc.
Thermal operators agnostic to small/large deformations.
Implementation of thermal radiation bc.
void simple(double P1[], double P2[], double P3[], double c[], const int N)
ElementsAndOps< SPACE_DIM >::BoundaryEle BoundaryEle
ElementsAndOps< SPACE_DIM >::DomainEle DomainEle
[Define dimension]
#define CATCH_ERRORS
Catch errors.
FieldApproximationBase
approximation base
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base nme:nme847.
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ L2
field with C-1 continuity
@ HCURL
field with continuous tangents
@ HDIV
field with continuous normal traction
#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 ...
#define CHK_MOAB_THROW(err, msg)
Check error code of MoAB function and throw MoFEM exception.
@ MOFEM_ATOM_TEST_INVALID
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
PetscErrorCode DMoFEMMeshToLocalVector(DM dm, Vec l, InsertMode mode, ScatterMode scatter_mode)
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.
auto createDMVector(DM dm)
Get smart vector from DM.
auto createDMMatrix(DM dm)
Get smart matrix from DM.
#define MOFEM_LOG(channel, severity)
Log.
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
#define MOFEM_LOG_CHANNEL(channel)
Set and reset channel.
MoFEMErrorCode getCubitMeshsetPtr(const int ms_id, const CubitBCType cubit_bc_type, const CubitMeshSets **cubit_meshset_ptr) const
get cubit meshset
FTensor::Index< 'i', SPACE_DIM > i
const double c
speed of light (cm/ns)
const double n
refractive index of diffusive medium
auto commonDataFactory(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, std::string block_name, Sev sev, double scale=1)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
implementation of Data Operators for Forces and Sources
PetscErrorCode DMMoFEMTSSetMonitor(DM dm, TS ts, const std::string fe_name, boost::shared_ptr< MoFEM::FEMethod > method, boost::shared_ptr< MoFEM::BasicMethod > pre_only, boost::shared_ptr< MoFEM::BasicMethod > post_only)
Set Monitor To TS solver.
PetscErrorCode PetscOptionsGetInt(PetscOptions *, const char pre[], const char name[], PetscInt *ivalue, PetscBool *set)
MoFEMErrorCode MoFEMSNESMonitorFields(SNES snes, PetscInt its, PetscReal fgnorm, SnesCtx *ctx)
Sens monitor printing residual field by field.
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
PetscErrorCode PetscOptionsGetScalar(PetscOptions *, const char pre[], const char name[], PetscScalar *dval, PetscBool *set)
PetscErrorCode PetscOptionsGetRealArray(PetscOptions *, const char pre[], const char name[], PetscReal dval[], PetscInt *nmax, PetscBool *set)
auto createVectorMPI(MPI_Comm comm, PetscInt n, PetscInt N)
Create MPI Vector.
OpCalculateScalarFieldValuesFromPetscVecImpl< PetscData::CTX_SET_X_T > OpCalculateScalarFieldValuesDot
auto getDMSnesCtx(DM dm)
Get SNES context data structure used by DM.
OpCalculateQdotQLhs_dU< SPACE_DIM, GAUSS, AssemblyDomainEleOp, IS_LARGE_STRAINS > OpHdivU
Integrate Lhs of flux term coupled to displacement field.
OpBaseDotT OpBaseDivFlux
Integrate Rhs base of temperature times divergence of flux (T)
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMass< 1, 1 > OpCapacity
Integrate Lhs base of temperature times (heat capacity) times base of temperature (T x T)
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpMixDivTimesU< 3, 1, SPACE_DIM > OpHDivTemp
Integrate Rhs div flux base times temperature (T)
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpMixDivTimesScalar< SPACE_DIM > OpHdivT
Integrate Lhs div of base of flux times base of temperature (FLUX x T) and transpose of it,...
OpHdivFluxImpl< SPACE_DIM, IS_LARGE_STRAINS > OpHdivFlux
OpHdivHdivImpl< SPACE_DIM, IS_LARGE_STRAINS > OpHdivHdiv
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpBaseTimesScalar< 1 > OpBaseDotT
Integrate Rhs base of temperature time heat capacity times heat rate (T)
FormsIntegrators< DomainEleOp >::Assembly< A >::LinearForm< I >::OpGradTimesTensor< 1, FIELD_DIM, SPACE_DIM > OpGradTimesTensor
constexpr IntegrationType I
OpPostProcMapInMoab< SPACE_DIM, SPACE_DIM > OpPPMap
PostProcBrokenMeshInMoab< BoundaryEle > SkinPostProcEle
#define EXECUTABLE_DIMENSION
ElementsAndOps< SPACE_DIM >::SideEle SideEle
constexpr auto field_name
static constexpr int approx_order
OpBaseImpl< PETSC, EdgeEleOp > OpBase
BoundaryNaturalBC::OpFlux< NaturalTemperatureMeshsets, 3, SPACE_DIM > OpTemperatureBC
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpGradTensorGrad< 1, SPACE_DIM, SPACE_DIM, 1 > OpKPiola
[Only used for dynamics]
FormsIntegrators< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpGradTimesTensor< 1, SPACE_DIM, SPACE_DIM > OpInternalForcePiola
FTensor::Index< 'm', 3 > m
Simple interface for fast problem set-up.
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.
Definition of the displacement bc data structure.
Data on single entity (This is passed as argument to DataOperator::doWork)
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
FTensor::Tensor1< FTensor::PackPtr< double *, Tensor_Dim >, Tensor_Dim > getFTensor1N(FieldApproximationBase base)
Get base functions for Hdiv/Hcurl spaces.
Class (Function) to enforce essential constrains.
Field evaluator interface.
Section manager is used to create indexes and sections.
Interface for managing meshsets containing materials and boundary conditions.
Natural boundary conditions.
Get vector field for H-div approximation.
Calculate divergence of vector field.
Get value at integration points for scalar field.
Get field gradients at integration pts for scalar field rank 0, i.e. vector field.
Get values at integration pts for tensor field rank 1, i.e. vector field.
Element used to execute operators on side of the element.
Post post-proc data at points from hash maps.
PipelineManager interface.
MoFEMErrorCode setDomainRhsIntegrationRule(RuleHookFun rule)
Problem manager is used to build and partition problems.
Simple interface for fast problem set-up.
MoFEMErrorCode addDomainField(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_ZERO, int verb=-1)
Add field on domain.
MoFEMErrorCode getOptions()
get options
intrusive_ptr for managing petsc objects
MoFEMErrorCode getInterface(IFACE *&iface) const
Get interface reference to pointer of interface.
auto getHeatCapacityPtr()
auto getHeatConductivityPtr()
VectorDouble coeffExpansion
auto getCoeffExpansionPtr()
boost::shared_ptr< FieldEvaluatorInterface::SetPtsData > fieldEvalData
MoFEMErrorCode getCommandLineParameters()
[Run problem]
MoFEMErrorCode runProblem()
[Run problem]
boost::shared_ptr< MatrixDouble > fluxFieldPtr
boost::shared_ptr< VectorDouble > tempFieldPtr
boost::shared_ptr< MatrixDouble > stressFieldPtr
MoFEM::Interface & mField
ThermoElasticProblem(MoFEM::Interface &m_field)
std::array< double, 3 > fieldEvalCoords
boost::shared_ptr< MatrixDouble > dispGradPtr
MoFEMErrorCode opThermoElasticFactoryDomainRhs(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, boost::shared_ptr< HenckyOps::CommonData > elastic_common_ptr, boost::shared_ptr< ThermoElasticProblem::BlockedThermalParameters > thermal_common_ptr, boost::shared_ptr< ThermoElasticProblem::BlockedThermoElasticParameters > thermoelastic_common_ptr, Sev sev)
MoFEMErrorCode setupProblem()
add fields
boost::shared_ptr< MatrixDouble > dispFieldPtr
MoFEMErrorCode bC()
[Set up problem]
MoFEMErrorCode OPs()
[Boundary condition]
boost::shared_ptr< MatrixDouble > strainFieldPtr
MoFEMErrorCode tsSolve()
[Push operators to pipeline]
MoFEMErrorCode opThermoElasticFactoryDomainLhs(MoFEM::Interface &m_field, boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pip, std::string field_name, std::string coupled_field_name, boost::shared_ptr< HenckyOps::CommonData > elastic_common_ptr, boost::shared_ptr< ThermoElasticProblem::BlockedThermalParameters > thermal_common_ptr, boost::shared_ptr< ThermoElasticProblem::BlockedThermoElasticParameters > thermoelastic_common_ptr, Sev sev)
MoFEMErrorCode addMatThermalBlockOps(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string block_name, boost::shared_ptr< BlockedThermalParameters > blockedParamsPtr, Sev sev)
MoFEMErrorCode addMatThermoElasticBlockOps(boost::ptr_deque< ForcesAndSourcesCore::UserDataOperator > &pipeline, std::string block_name, boost::shared_ptr< BlockedThermoElasticParameters > blockedParamsPtr, Sev sev)
constexpr AssemblyType AT
constexpr IntegrationType IT
EssentialBC< BoundaryEleOp >::Assembly< PETSC >::LinearForm< GAUSS >::OpEssentialRhs< HeatFluxCubitBcData, 3, SPACE_DIM > OpEssentialFluxRhs
[Natural boundary conditions]
NaturalBC< DomainEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS > DomainNaturalBCLhs
#define FINITE_DEFORMATION_FLAG
constexpr bool IS_LARGE_STRAINS
EssentialBC< BoundaryEleOp >::Assembly< PETSC >::BiLinearForm< GAUSS >::OpEssentialLhs< HeatFluxCubitBcData, 3, SPACE_DIM > OpEssentialFluxLhs
BoundaryNaturalBC::OpFlux< NaturalForceMeshsets, 1, SPACE_DIM > OpForce
DomainNaturalBCLhs::OpFlux< SetTargetTemperature, 1, 1 > OpSetTemperatureLhs
DomainNaturalBCRhs::OpFlux< NaturalMeshsetType< BLOCKSET >, 1, SPACE_DIM > OpBodyForce
double default_heat_capacity
double default_young_modulus
[Essential boundary conditions (Least square approach)]
double default_coeff_expansion
PetscBool do_output_domain
NaturalBC< DomainEleOp >::Assembly< PETSC >::LinearForm< GAUSS > DomainNaturalBCRhs
[Thermal problem]
DomainNaturalBCRhs::OpFlux< NaturalMeshsetType< BLOCKSET >, 1, 1 > OpHeatSource
double default_heat_conductivity
DomainNaturalBCRhs::OpFlux< SetTargetTemperature, 1, 1 > OpSetTemperatureRhs
double default_poisson_ratio
NaturalBC< BoundaryEleOp >::Assembly< PETSC >::LinearForm< GAUSS > BoundaryNaturalBC
[Body and heat source]
const std::string row_field_name, const std::string col_field_name,
boost::shared_ptr<MatrixDouble> mDptr,
boost::shared_ptr<VectorDouble> coeff_expansion_ptr);
MoFEMErrorCode
iNtegrate(EntitiesFieldData::EntData &row_data,
EntitiesFieldData::EntData &col_data);
private:
boost::shared_ptr<MatrixDouble>
mDPtr;
};
boost::shared_ptr<MatrixDouble> strain_ptr,
boost::shared_ptr<VectorDouble> temp_ptr,
boost::shared_ptr<MatrixDouble> m_D_ptr,
boost::shared_ptr<VectorDouble> coeff_expansion_ptr,
boost::shared_ptr<MatrixDouble> stress_ptr);
boost::shared_ptr<VectorDouble> temp_ptr,
boost::shared_ptr<MatrixDouble> m_D_ptr,
boost::shared_ptr<VectorDouble> coeff_expansion_ptr,
boost::shared_ptr<double> ref_temp_ptr,
boost::shared_ptr<MatrixDouble> stress_ptr);
private:
boost::shared_ptr<VectorDouble>
tempPtr;
boost::shared_ptr<MatrixDouble>
mDPtr;
};
const std::string row_field_name, const std::string col_field_name,
boost::shared_ptr<MatrixDouble> mDptr,
boost::shared_ptr<VectorDouble> coeff_expansion_ptr)
mDPtr(mDptr), coeffExpansionPtr(coeff_expansion_ptr) {
sYmm = false;
}
OpKCauchyThermoElasticity::iNtegrate(EntitiesFieldData::EntData &row_data,
EntitiesFieldData::EntData &col_data) {
auto &locMat = AssemblyDomainEleOp::locMat;
const auto nb_integration_pts = row_data.getN().size1();
const auto nb_row_base_functions = row_data.getN().size2();
auto t_w = getFTensor0IntegrationWeight();
auto t_row_diff_base = row_data.getFTensor1DiffN<
SPACE_DIM>();
auto t_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(*mDPtr);
t_coeff_exp(d, d) = (*coeffExpansionPtr)[
d];
}
t_eigen_strain(
i,
j) = (t_D(
i,
j,
k,
l) * t_coeff_exp(
k,
l));
for (auto gg = 0; gg != nb_integration_pts; ++gg) {
double alpha = getMeasure() * t_w;
auto rr = 0;
for (; rr != AssemblyDomainEleOp::nbRows /
SPACE_DIM; ++rr) {
auto t_mat = getFTensor1FromMat<SPACE_DIM, 1>(locMat, rr *
SPACE_DIM);
auto t_col_base = col_data.getFTensor0N(gg, 0);
for (auto cc = 0; cc != AssemblyDomainEleOp::nbCols; cc++) {
(t_row_diff_base(
j) * t_eigen_strain(
i,
j)) * (t_col_base * alpha);
++t_mat;
++t_col_base;
}
++t_row_diff_base;
}
for (; rr != nb_row_base_functions; ++rr)
++t_row_diff_base;
++t_w;
}
}
OpStressThermal::OpStressThermal(
const std::string
field_name, boost::shared_ptr<MatrixDouble> strain_ptr,
boost::shared_ptr<VectorDouble> temp_ptr,
boost::shared_ptr<MatrixDouble> m_D_ptr,
boost::shared_ptr<VectorDouble> coeff_expansion_ptr,
boost::shared_ptr<MatrixDouble> stress_ptr)
tempPtr(temp_ptr), mDPtr(m_D_ptr), coeffExpansionPtr(coeff_expansion_ptr),
stressPtr(stress_ptr) {
std::fill(&doEntities[MBEDGE], &doEntities[MBMAXTYPE], false);
}
OpStressThermal::OpStressThermal(
boost::shared_ptr<MatrixDouble> strain_ptr,
boost::shared_ptr<VectorDouble> temp_ptr,
boost::shared_ptr<MatrixDouble> m_D_ptr,
boost::shared_ptr<VectorDouble> coeff_expansion_ptr,
boost::shared_ptr<double> ref_temp_ptr,
boost::shared_ptr<MatrixDouble> stress_ptr)
tempPtr(temp_ptr), mDPtr(m_D_ptr), coeffExpansionPtr(coeff_expansion_ptr),
refTempPtr(ref_temp_ptr), stressPtr(stress_ptr) {}
const auto nb_gauss_pts = getGaussPts().size2();
auto t_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(*mDPtr);
auto t_strain = getFTensor2SymmetricFromMat<SPACE_DIM>(*strainPtr);
auto t_stress = getFTensor2SymmetricFromMat<SPACE_DIM>(*stressPtr);
auto t_temp = getFTensor0FromVec(*tempPtr);
t_coeff_exp(d, d) = (*coeffExpansionPtr)[
d];
}
for (size_t gg = 0; gg != nb_gauss_pts; ++gg) {
(t_strain(
k,
l) - t_coeff_exp(
k,
l) * (t_temp - (*refTempPtr)));
++t_strain;
++t_stress;
++t_temp;
}
}
struct SetTargetTemperature;
}
template <AssemblyType A, IntegrationType I, typename OpBase>
template <AssemblyType A, IntegrationType I, typename OpBase>
OpBase>;
template <AssemblyType A, IntegrationType I, typename OpBase>
MoFEM::OpFluxRhsImpl<ThermoElasticOps::SetTargetTemperature, 1, 1, A, I,
OpBase>,
A, I, OpBase
> {
AddFluxToRhsPipelineImpl() = delete;
boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
boost::shared_ptr<VectorDouble> temp_ptr, std::string block_name, Sev sev
) {
using OP_SOURCE = typename FormsIntegrators<OpBase>::template Assembly<
using OP_TEMP = typename FormsIntegrators<OpBase>::template Assembly<
auto add_op = [&](auto &&meshset_vec_ptr) {
for (
auto m : meshset_vec_ptr) {
std::vector<double> block_data;
m->getAttributes(block_data);
if (block_data.size() < 2) {
"Expected two parameters");
}
double target_temperature = block_data[0];
double beta =
block_data[1];
auto ents_ptr = boost::make_shared<Range>();
*(ents_ptr), true);
<<
"Add " << *
m <<
" target temperature " << target_temperature
<< " penalty " << beta;
pipeline.push_back(new OP_SOURCE(
[target_temperature, beta](double, double, double) {
return target_temperature * beta;
},
ents_ptr));
pipeline.push_back(new OP_TEMP(
[beta](double, double, double) { return -beta; }, ents_ptr));
}
};
m_field.
getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
(boost::format("%s(.*)") % block_name).str()
))
);
}
};
template <AssemblyType A, IntegrationType I, typename OpBase>
struct AddFluxToLhsPipelineImpl<
> {
AddFluxToLhsPipelineImpl() = delete;
boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
boost::shared_ptr<VectorDouble> temp_ptr, std::string block_name, Sev sev
) {
using OP_MASS = typename FormsIntegrators<OpBase>::template Assembly<
auto add_op = [&](auto &&meshset_vec_ptr) {
for (
auto m : meshset_vec_ptr) {
std::vector<double> block_data;
m->getAttributes(block_data);
if (block_data.size() != 2) {
"Expected two parameters");
}
double beta =
block_data[1];
auto ents_ptr = boost::make_shared<Range>();
*(ents_ptr), true);
<<
"Add " << *
m <<
" penalty " << beta;
pipeline.push_back(new OP_MASS(
[beta](double, double, double) { return -beta; }, ents_ptr));
}
};
m_field.
getInterface<MeshsetsManager>()->getCubitMeshsetPtr(std::regex(
(boost::format("%s(.*)") % block_name).str()
))
);
}
};
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
boost::shared_ptr< MatrixDouble > mDPtr
OpKCauchyThermoElasticity(const std::string row_field_name, const std::string col_field_name, boost::shared_ptr< MatrixDouble > mDptr, boost::shared_ptr< VectorDouble > coeff_expansion_ptr)
boost::shared_ptr< VectorDouble > coeffExpansionPtr
MoFEMErrorCode iNtegrate(EntitiesFieldData::EntData &row_data, EntitiesFieldData::EntData &col_data)
DEPRECATED OpStressThermal(const std::string field_name, boost::shared_ptr< MatrixDouble > strain_ptr, boost::shared_ptr< VectorDouble > temp_ptr, boost::shared_ptr< MatrixDouble > m_D_ptr, boost::shared_ptr< VectorDouble > coeff_expansion_ptr, boost::shared_ptr< MatrixDouble > stress_ptr)
boost::shared_ptr< VectorDouble > coeffExpansionPtr
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
[Calculate stress]
boost::shared_ptr< MatrixDouble > strainPtr
boost::shared_ptr< MatrixDouble > stressPtr
boost::shared_ptr< double > refTempPtr
boost::shared_ptr< VectorDouble > tempPtr
boost::shared_ptr< MatrixDouble > mDPtr