#ifndef EXECUTABLE_DIMENSION
#define EXECUTABLE_DIMENSION 3
#endif
0>;
GAUSS>::OpMixDivTimesScalar<SPACE_DIM>;
GAUSS>::OpBaseTimesVector<3, SPACE_DIM, 1>;
GAUSS>::OpMixDivTimesU<3, 1, SPACE_DIM>;
GAUSS>::OpBaseTimesScalar<1>;
GAUSS>::OpEssentialRhs<HeatFluxCubitBcData, 3, SPACE_DIM>;
GAUSS>::OpEssentialLhs<HeatFluxCubitBcData, 3, SPACE_DIM>;
1;
CHKERR moab.add_entities(*out_meshset,
r);
CHKERR moab.write_file(name.c_str(),
"VTK",
"", out_meshset->get_ptr(), 1);
};
private:
std::array<double, SPACE_DIM> fieldEvalCoords;
boost::shared_ptr<FieldEvaluatorInterface::SetPtsData> fieldEvalData;
boost::shared_ptr<VectorDouble> tempFieldPtr;
boost::shared_ptr<MatrixDouble> fluxFieldPtr;
boost::shared_ptr<MatrixDouble> dispFieldPtr;
boost::shared_ptr<MatrixDouble> dispGradPtr;
boost::shared_ptr<MatrixDouble> strainFieldPtr;
boost::shared_ptr<MatrixDouble> stressFieldPtr;
getCommandLineParameters();
struct BlockedParameters
: public boost::enable_shared_from_this<BlockedParameters> {
double heatConductivity;
double heatCapacity;
inline auto getDPtr() {
return boost::shared_ptr<MatrixDouble>(shared_from_this(), &mD);
}
inline auto getCoeffExpansionPtr() {
return boost::shared_ptr<VectorDouble>(shared_from_this(),
&coeffExpansion);
}
inline auto getHeatConductivityPtr() {
return boost::shared_ptr<double>(shared_from_this(), &heatConductivity);
}
inline auto getHeatCapacityPtr() {
return boost::shared_ptr<double>(shared_from_this(), &heatCapacity);
}
};
boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
std::string block_elastic_name, std::string block_thermal_name,
boost::shared_ptr<BlockedParameters> blockedParamsPtr,
Sev sev);
};
boost::ptr_deque<ForcesAndSourcesCore::UserDataOperator> &pipeline,
std::string block_elastic_name, std::string block_thermal_name,
boost::shared_ptr<BlockedParameters> blockedParamsPtr,
Sev sev) {
OpMatElasticBlocks(boost::shared_ptr<MatrixDouble>
m,
double bulk_modulus_K,
std::vector<const CubitMeshSets *> meshset_vec_ptr)
"Can not get data from block");
}
for (auto &b : blockData) {
if (b.blockEnts.find(getFEEntityHandle()) != b.blockEnts.end()) {
CHKERR getMatDPtr(matDPtr, b.bulkModulusK, b.shearModulusG);
}
}
CHKERR getMatDPtr(matDPtr, bulkModulusKDefault, shearModulusGDefault);
}
private:
boost::shared_ptr<MatrixDouble> matDPtr;
double bulkModulusK;
double shearModulusG;
};
double bulkModulusKDefault;
double shearModulusGDefault;
std::vector<BlockData> blockData;
std::vector<const CubitMeshSets *> meshset_vec_ptr,
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 two attributes");
}
auto get_block_ents = [&]() {
m_field.
get_moab().get_entities_by_handle(
m->meshset, ents,
true);
return ents;
};
blockData.push_back(
}
}
auto set_material_stiffness = [&]() {
}
auto t_D = getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(*mat_D_ptr);
};
set_material_stiffness();
}
};
double default_bulk_modulus_K =
double default_shear_modulus_G =
pipeline.push_back(new OpMatElasticBlocks(
blockedParamsPtr->getDPtr(), default_bulk_modulus_K,
default_shear_modulus_G, mField, sev,
(boost::format("%s(.*)") % block_elastic_name).str()
))
));
OpMatThermalBlocks(boost::shared_ptr<VectorDouble> expansion_ptr,
boost::shared_ptr<double> conductivity_ptr,
boost::shared_ptr<double> capacity_ptr,
std::vector<const CubitMeshSets *> meshset_vec_ptr)
expansionPtr(expansion_ptr), conductivityPtr(conductivity_ptr),
capacityPtr(capacity_ptr) {
"Can not get data from block");
}
for (auto &b : blockData) {
if (b.blockEnts.find(getFEEntityHandle()) != b.blockEnts.end()) {
*expansionPtr = b.expansion;
*conductivityPtr = b.conductivity;
*capacityPtr = b.capacity;
}
}
}
private:
double conductivity;
double capacity;
};
std::vector<BlockData> blockData;
std::vector<const CubitMeshSets *> meshset_vec_ptr,
for (
auto m : meshset_vec_ptr) {
std::vector<double> block_data;
CHKERR m->getAttributes(block_data);
if (block_data.size() < 3) {
"Expected that block has at least three attributes");
}
auto get_block_ents = [&]() {
m_field.
get_moab().get_entities_by_handle(
m->meshset, ents,
true);
return ents;
};
auto get_expansion = [&]() {
if (block_data.size() > 3) {
expansion[1] = block_data[3];
}
if (
SPACE_DIM == 3 && block_data.size() > 4) {
expansion[2] = block_data[4];
}
return expansion;
};
auto coeff_exp_vec = get_expansion();
<<
m->getName() <<
": conductivity = " << block_data[0]
<< " capacity = " << block_data[1]
<< " expansion = " << coeff_exp_vec;
blockData.push_back(
{block_data[0], block_data[1], coeff_exp_vec, get_block_ents()});
}
}
boost::shared_ptr<VectorDouble> expansionPtr;
boost::shared_ptr<double> conductivityPtr;
boost::shared_ptr<double> capacityPtr;
};
pipeline.push_back(new OpMatThermalBlocks(
blockedParamsPtr->getCoeffExpansionPtr(),
blockedParamsPtr->getHeatConductivityPtr(),
blockedParamsPtr->getHeatCapacityPtr(), mField, sev,
(boost::format("%s(.*)") % block_thermal_name).str()
))
));
}
CHKERR getCommandLineParameters();
}
auto get_command_line_parameters = [&]() {
PETSC_NULL);
PETSC_NULL);
PETSC_NULL);
PETSC_NULL);
PETSC_NULL);
PETSC_NULL);
PETSC_NULL);
PETSC_NULL);
<<
"Reference temperature " <<
ref_temp;
};
CHKERR get_command_line_parameters();
}
CHKERR simple->addBoundaryField(
"FLUX", flux_space, base, 1);
fieldEvalCoords.data(), &coords_dim,
tempFieldPtr = boost::make_shared<VectorDouble>();
fluxFieldPtr = boost::make_shared<MatrixDouble>();
dispFieldPtr = boost::make_shared<MatrixDouble>();
dispGradPtr = boost::make_shared<MatrixDouble>();
strainFieldPtr = boost::make_shared<MatrixDouble>();
stressFieldPtr = boost::make_shared<MatrixDouble>();
fieldEvalData =
fieldEvalData,
simple->getDomainFEName());
} else {
fieldEvalData,
simple->getDomainFEName());
}
fieldEvalData->setEvalPoints(fieldEvalCoords.data(), 1);
auto no_rule = [](
int,
int,
int) {
return -1; };
auto field_eval_fe_ptr = fieldEvalData->feMethodPtr.lock();
field_eval_fe_ptr->getRuleHook = no_rule;
auto block_params = boost::make_shared<BlockedParameters>();
auto mDPtr = block_params->getDPtr();
auto coeff_expansion_ptr = block_params->getCoeffExpansionPtr();
"MAT_THERMAL", block_params, Sev::verbose);
field_eval_fe_ptr->getOpPtrVector(), {H1, HDIV});
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(
dispGradPtr));
field_eval_fe_ptr->getOpPtrVector().push_back(
field_eval_fe_ptr->getOpPtrVector().push_back(
coeff_expansion_ptr, stressFieldPtr));
}
}
auto get_skin = [&]() {
CHKERR mField.get_moab().get_entities_by_dimension(0,
SPACE_DIM, body_ents);
Skinner skin(&mField.get_moab());
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) {
) {
CHKERR mField.get_moab().get_entities_by_dimension(
skin = subtract(skin, ents);
}
};
auto remove_named_blocks = [&](
auto n) {
std::regex(
(boost::format(
"%s(.*)") %
n).str()
))
) {
CHKERR mField.get_moab().get_entities_by_dimension(
skin = subtract(skin, ents);
}
};
if (!temp_bc) {
"remove_cubit_blocks");
"remove_named_blocks");
}
"remove_cubit_blocks");
return skin;
};
auto filter_true_skin = [&](auto skin) {
ParallelComm *pcomm =
CHKERR pcomm->filter_pstatus(skin, PSTATUS_SHARED | PSTATUS_MULTISHARED,
PSTATUS_NOT, -1, &boundary_ents);
return boundary_ents;
};
auto remove_flux_ents = filter_true_skin(filter_flux_blocks(get_skin()));
auto remove_temp_bc_ents =
filter_true_skin(filter_flux_blocks(get_skin(), true));
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
mField.get_moab(),
(boost::format("flux_remove_%d.vtk") % mField.get_comm_rank()).str(),
remove_flux_ents);
mField.get_moab(),
(boost::format("temp_bc_remove_%d.vtk") % mField.get_comm_rank()).str(),
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) {
field_entity_ptr->getEntFieldData()[0] =
init_temp;
return 0;
};
CHKERR mField.getInterface<
FieldBlas>()->fieldLambdaOnEntities(set_init_temp,
"T");
simple->getProblemName(),
"U");
simple->getProblemName(),
"FLUX",
false);
}
auto boundary_marker =
bc_mng->getMergedBlocksMarker(vector<string>{"HEATFLUX"});
};
auto block_params = boost::make_shared<BlockedParameters>();
auto mDPtr = block_params->getDPtr();
auto coeff_expansion_ptr = block_params->getCoeffExpansionPtr();
auto heat_conductivity_ptr = block_params->getHeatConductivityPtr();
auto heat_capacity_ptr = block_params->getHeatCapacityPtr();
auto time_scale = boost::make_shared<TimeScale>();
auto time_bodyforce_scaling =
boost::make_shared<TimeScale>("bodyforce_scale.txt");
auto time_heatsource_scaling =
boost::make_shared<TimeScale>("heatsource_scale.txt");
auto time_temperature_scaling =
boost::make_shared<TimeScale>("temperature_bc_scale.txt");
auto time_displacement_scaling =
boost::make_shared<TimeScale>("displacement_bc_scale.txt");
auto time_flux_scaling = boost::make_shared<TimeScale>("flux_bc_scale.txt");
auto time_force_scaling = boost::make_shared<TimeScale>("force_bc_scale.txt");
auto add_domain_rhs_ops = [&](auto &pipeline) {
Sev::inform);
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 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(
"U", mat_grad_ptr));
pipeline.push_back(
pipeline.push_back(
new OpStressThermal(mat_strain_ptr, vec_temp_ptr, mDPtr,
coeff_expansion_ptr,
mat_stress_ptr));
"U", mat_stress_ptr,
[](double, double, double) constexpr { return 1; }));
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));
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));
pipeline, mField, "T", {time_scale, time_heatsource_scaling},
"HEAT_SOURCE", Sev::inform);
pipeline, mField, "U", {time_scale, time_bodyforce_scaling},
"BODY_FORCE", Sev::inform);
pipeline, mField, "T", vec_temp_ptr, "SETTEMP", Sev::inform);
};
auto add_domain_lhs_ops = [&](auto &pipeline) {
Sev::verbose);
pipeline.push_back(
new OpKCauchy(
"U",
"U", mDPtr));
"U", "T", mDPtr, coeff_expansion_ptr));
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));
pipeline.push_back(
new OpHdivT(
"FLUX",
"T", []() constexpr {
return -1; },
true));
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>();
pipeline, mField, "T", vec_temp_ptr, "SETTEMP", Sev::verbose);
};
auto add_boundary_rhs_ops = [&](auto &pipeline) {
pipeline, mField, "U", {time_scale, time_force_scaling}, "FORCE",
Sev::inform);
pipeline, mField, "FLUX", {time_scale, time_temperature_scaling},
"TEMPERATURE", Sev::inform);
using OpFluxBC =
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();
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_element = [&]() {
auto post_proc_fe = boost::make_shared<PostProcEle>(mField);
auto block_params = boost::make_shared<BlockedParameters>();
auto mDPtr = block_params->getDPtr();
auto coeff_expansion_ptr = block_params->getCoeffExpansionPtr();
"MAT_THERMAL", block_params, Sev::verbose);
post_proc_fe->getOpPtrVector(), {H1, HDIV});
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>();
post_proc_fe->getOpPtrVector().push_back(
post_proc_fe->getOpPtrVector().push_back(
auto u_ptr = boost::make_shared<MatrixDouble>();
post_proc_fe->getOpPtrVector().push_back(
post_proc_fe->getOpPtrVector().push_back(
mat_grad_ptr));
post_proc_fe->getOpPtrVector().push_back(
post_proc_fe->getOpPtrVector().push_back(
coeff_expansion_ptr, mat_stress_ptr));
post_proc_fe->getOpPtrVector().push_back(
post_proc_fe->getPostProcMesh(), post_proc_fe->getMapGaussPts(),
{{"T", vec_temp_ptr}},
{{"U", u_ptr}, {"FLUX", mat_flux_ptr}},
{},
{{"STRAIN", mat_strain_ptr}, {"STRESS", mat_stress_ptr}}
)
);
return post_proc_fe;
};
auto monitor_ptr = boost::make_shared<FEMethod>();
auto post_proc_fe = create_post_process_element();
auto set_time_monitor = [&](auto dm, auto solver) {
monitor_ptr->preProcessHook = [&]() {
post_proc_fe,
monitor_ptr->getCacheWeakPtr());
CHKERR post_proc_fe->writeFile(
"out_" + boost::lexical_cast<std::string>(monitor_ptr->ts_step) +
".h5m");
}
->evalFEAtThePoint3D(
fieldEvalCoords.data(), 1e-12,
simple->getProblemName(),
simple->getDomainFEName(), fieldEvalData,
mField.get_comm_rank(), mField.get_comm_rank(), nullptr,
} else {
->evalFEAtThePoint2D(
fieldEvalCoords.data(), 1e-12,
simple->getProblemName(),
simple->getDomainFEName(), fieldEvalData,
mField.get_comm_rank(), mField.get_comm_rank(), nullptr,
}
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()) {
<< "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 (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 (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",
}
}
}
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 (stressFieldPtr->size1()) {
auto t_stress =
getFTensor2SymmetricFromMat<SPACE_DIM>(*stressFieldPtr);
auto 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))));
<< "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",
}
}
}
}
};
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_NULL, is_TFlux);
CHKERR PCFieldSplitSetIS(pc, PETSC_NULL, is_u);
}
};
CHKERR TSSetFromOptions(solver);
CHKERR set_section_monitor(solver);
CHKERR set_fieldsplit_preconditioner(solver);
CHKERR set_time_monitor(dm, solver);
}
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(
core_log->add_sink(
try {
DMType dm_name = "DMMOFEM";
}
}
const std::string row_field_name, const std::string col_field_name,
boost::shared_ptr<MatrixDouble> mDptr,
boost::shared_ptr<VectorDouble> coeff_expansion_ptr);
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<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;
}
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;
auto t_mat = getFTensor1FromMat<SPACE_DIM, 1>(locMat, rr *
SPACE_DIM);
auto t_col_base = col_data.getFTensor0N(gg, 0);
(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<MatrixDouble> stress_ptr)
tempPtr(temp_ptr), mDPtr(m_D_ptr), coeffExpansionPtr(coeff_expansion_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);
t_coeff_exp(
d,
d) = (*coeffExpansionPtr)[
d];
}
for (size_t gg = 0; gg != nb_gauss_pts; ++gg) {
t_stress(
i,
j) = t_D(
i,
j,
k,
l) *
++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<
A>::template LinearForm<I>::template OpSource<1, 1>;
using OP_TEMP = typename FormsIntegrators<OpBase>::template Assembly<
A>::template LinearForm<I>::template OpBaseTimesScalar<1>;
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()
))
);
}
};