17 boost::shared_ptr<MatOps::MatPiolaResponse> mat_physical_equations_ptr,
23 "Mat core physical equations are not allocated");
29 PetscOptionsBegin(PETSC_COMM_WORLD,
"meta_",
"",
"none");
31 CHKERR PetscOptionsScalar(
"-viscosity_alpha_grad_u",
32 "Logarithmic-stretch-gradient rate viscosity",
"",
36 <<
"alphaGradU (-meta_viscosity_alpha_grad_u), "
37 "logarithmic-stretch-gradient rate viscosity: "
44 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
45 boost::shared_ptr<PhysicalEquations> physics_ptr)
override {
53 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
54 boost::shared_ptr<MatOps::MatElastic> physics_ptr,
55 boost::shared_ptr<double> total_helmholtz_free_energy_ptr)
61 "Mat core energy data is not allocated");
64 "Mat core physical equations are not allocated");
77 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
78 const double alpha)
override {
84 std::string row_field, std::string col_field,
85 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
86 const double alpha)
override {
95 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
96 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
97 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv);
108 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
109 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
110 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv)
override {
112 external_strain_vec_ptr, smv);
122 boost::weak_ptr<MatOps::PhysicalEquations> physics_ptr,
123 const double alpha,
const double alpha_grad_u)
132 boost::shared_ptr<MatOps::PhysicalEquations>
138 std::string row_field, std::string col_field,
139 boost::shared_ptr<MatOps::PhysicalEquations> physics_ptr,
140 const double alpha,
const double alpha_grad_u)
151 boost::shared_ptr<MatOps::PhysicalEquations>
159 boost::shared_ptr<MatOps::MatElastic> mat_elastic_ptr,
165 "Mat core elastic equations are not allocated");
172 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
173 boost::shared_ptr<double> total_helmholtz_free_energy_ptr)
override {
190 auto mat_ops_data =
physicsPtr->matOpsDataPtr;
193 "Mat core material data is not allocated");
195 const int nb_integration_pts = getGaussPts().size2();
196 if (nb_integration_pts <= 0)
198 "Mat core energy operator has no integration points");
200 auto mat_grad_ptr = mat_ops_data->getCommonDataPtr(
"grad");
201 auto mat_F_ptr = mat_ops_data->getActiveDataPtr(
"F");
202 auto mat_energy_ptr =
physicsPtr->getEnergyDensityPtr();
203 if (!mat_grad_ptr || !mat_F_ptr || !mat_energy_ptr)
205 "Mat core energy evaluation has incomplete material data");
206 if (mat_grad_ptr->size1() != nb_integration_pts ||
209 "Mat core energy gradient data has size %zu x %zu; expected %d "
211 mat_grad_ptr->size1(), mat_grad_ptr->size2(), nb_integration_pts,
215 mat_energy_ptr->resize(1, 1,
false);
217 const auto get_material_tag = [&]() {
219 for (
const auto &tag_range_pair : *
physicsPtr->tagVsRangePtr) {
220 if (tag_range_pair.second.find(getFEEntityHandle()) !=
221 tag_range_pair.second.end())
222 return tag_range_pair.first;
228 "ADOL-C tag not found " +
234 const int material_tag = get_material_tag();
235 auto *fe_ptr =
const_cast<FEMethod *
>(getFEMethod());
238 "Mat core energy operator has no finite-element method");
239 const EntityHandle ent = fe_ptr->getFEEntityHandle();
242 "Mat core energy operator has no finite-element entity");
244 using GaussLayout = DataLayoutTraits<DataLayout::GaussByCoeffs>;
245 auto get_grad_at_pts = MatrixSizeHelper<
247 GaussLayout>::get(*mat_grad_ptr, nb_integration_pts);
251 auto t_grad_at_pts = get_grad_at_pts();
252 dataAtPts->energyAtPts.resize(nb_integration_pts,
false);
253 auto t_energy_at_pts = getFTensor0FromVec(
dataAtPts->energyAtPts);
255 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
257 getFTensor2FromPtr<SPACE_DIM, SPACE_DIM>(mat_F_ptr->data().data());
258 t_F(
i,
J) = t_grad_at_pts(
i,
J);
262 auto t_energy = getFTensor0FromMat(mat_energy_ptr);
263 const double energy_density = t_energy;
264 if (!std::isfinite(energy_density))
265 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FP,
266 "Mat core returned non-finite energy density at point %d on "
268 gg,
static_cast<unsigned long>(ent));
269 t_energy_at_pts = energy_density;
277 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FP,
278 "Mat core accumulated energy is non-finite before integration");
279 const double element_measure = getMeasure();
280 if (!std::isfinite(element_measure) || element_measure < 0.)
281 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FP,
282 "Mat core element measure is invalid: %.16g", element_measure);
284 auto t_w = getFTensor0IntegrationWeight();
285 auto t_energy_at_pts_integral = getFTensor0FromVec(
dataAtPts->energyAtPts);
286 auto t_plasticF =
dataAtPts->getFTensorPlasticF(nb_integration_pts);
287 double local_energy = 0;
288 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
289 const double weight = t_w;
290 const double energy_density = t_energy_at_pts_integral;
291 const double det_plasticF = determinantTensor3by3(t_plasticF);
292 if (!std::isfinite(weight) || !std::isfinite(det_plasticF) ||
294 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FP,
295 "Invalid Mat core energy quadrature data at point %d on "
297 gg,
static_cast<unsigned long>(ent));
298 local_energy += weight * det_plasticF * energy_density;
301 ++t_energy_at_pts_integral;
305 const double element_energy = element_measure * local_energy;
306 const double accumulated_energy =
308 if (!std::isfinite(element_energy) || !std::isfinite(accumulated_energy))
309 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FP,
310 "Mat core integrated energy is non-finite on entity %lu",
311 static_cast<unsigned long>(ent));
322 auto physics_ptr = physicsPtr;
323 auto mat_ops_data = physics_ptr->matOpsDataPtr;
326 auto t_L = FTensor::SymmLTensor<double, 3>();
328 int nb_dofs = data.getIndices().size();
329 int nb_integration_pts = data.getN().size1();
330 auto v = getVolume();
331 auto t_w = getFTensor0IntegrationWeight();
333 auto t_P = getFTensor2FromMat<3, 3, -1,
DL>(
334 mat_ops_data->getCommonDataPtr(
"PAtPts"));
335 auto t_approx_P_adjoint_log_du = getFTensor1FromMat<
size_symm, -1,
DL>(
336 mat_ops_data->getCommonDataPtr(
"adjointPdUAtPts"));
337 auto t_diff_u = getFTensor4FromMat<3, 3, 3, 3, -1,
DL>(
338 mat_ops_data->getCommonDataPtr(
"diffStretchH1AtPts"));
339 auto t_dot_log_u = getFTensor2SymmetricFromMat<3, -1,
DL>(
340 mat_ops_data->getCommonDataPtr(
"logStretchDotTensorAtPts"));
341 auto t_grad_dot_log_u = getFTensor2FromMat<
size_symm, 3, -1,
DL>(
342 mat_ops_data->getCommonDataPtr(
"gradLogStretchDotTensorAtPts"));
343 auto t_plasticF = getFTensor2SymmetricFromMat<3, -1,
DL>(
344 mat_ops_data->getCommonDataPtr(
"plasticF"));
345 auto t_invPlasticF = getFTensor2FromMat<3, 3, -1,
DL>(
346 mat_ops_data->getCommonDataPtr(
"invPlasticF"));
355 auto get_ftensor2 = [](
auto &
v) {
357 &
v[0], &
v[1], &
v[2], &
v[3], &
v[4], &
v[5]);
360 int nb_base_functions = data.getN().size2();
361 auto t_row_base_fun = data.getFTensor0N();
362 auto t_row_grad_fun = data.getFTensor1DiffN<3>();
363 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
364 const double det_plasticF = determinantTensor3by3(t_plasticF);
365 const double a =
v * t_w * det_plasticF;
366 auto t_nf = get_ftensor2(nF);
369 t_Ldiff_u(
i,
j, L) = t_diff_u(
i,
j,
k,
l) * t_L(
k,
l, L);
373 a * (t_approx_P_adjoint_log_du(L) - t_Ldiff_u(
i,
j, L) * t_P(
i,
j));
374 t_residual(L) += (
a *
alphaU) * (t_dot_log_u(
i,
j) * t_L(
i,
j, L));
377 t_grad_dot_log_u_intermediate(L,
j) =
378 t_grad_dot_log_u(L,
i) * t_invPlasticF(
i,
j);
380 t_grad_residual(L,
j) =
384 for (; bb != nb_dofs /
size_symm; ++bb) {
386 t_row_grad_intermediate(
j) = t_row_grad_fun(
i) * t_invPlasticF(
i,
j);
387 t_nf(L) -= t_row_base_fun * t_residual(L);
388 t_nf(L) += t_row_grad_intermediate(
j) * t_grad_residual(L,
j);
393 for (; bb != nb_base_functions; ++bb) {
399 ++t_approx_P_adjoint_log_du;
417 auto t_L = FTensor::SymmLTensor<double, 3>();
418 auto t_diff = FTensor::DiffTensor<double>();
421 int nb_integration_pts = row_data.getN().size1();
422 int row_nb_dofs = row_data.getIndices().size();
423 int col_nb_dofs = col_data.getIndices().size();
425 auto get_ftensor2 = [](MatrixDouble &
m,
const int r,
const int c) {
429 &
m(r + 0,
c + 0), &
m(r + 0,
c + 1), &
m(r + 0,
c + 2), &
m(r + 0,
c + 3),
430 &
m(r + 0,
c + 4), &
m(r + 0,
c + 5),
432 &
m(r + 1,
c + 0), &
m(r + 1,
c + 1), &
m(r + 1,
c + 2), &
m(r + 1,
c + 3),
433 &
m(r + 1,
c + 4), &
m(r + 1,
c + 5),
435 &
m(r + 2,
c + 0), &
m(r + 2,
c + 1), &
m(r + 2,
c + 2), &
m(r + 2,
c + 3),
436 &
m(r + 2,
c + 4), &
m(r + 2,
c + 5),
438 &
m(r + 3,
c + 0), &
m(r + 3,
c + 1), &
m(r + 3,
c + 2), &
m(r + 3,
c + 3),
439 &
m(r + 3,
c + 4), &
m(r + 3,
c + 5),
441 &
m(r + 4,
c + 0), &
m(r + 4,
c + 1), &
m(r + 4,
c + 2), &
m(r + 4,
c + 3),
442 &
m(r + 4,
c + 4), &
m(r + 4,
c + 5),
444 &
m(r + 5,
c + 0), &
m(r + 5,
c + 1), &
m(r + 5,
c + 2), &
m(r + 5,
c + 3),
445 &
m(r + 5,
c + 4), &
m(r + 5,
c + 5)
459 auto get_dP = [&]() {
460 auto get_tensor_for_dP =
462 DL>::size(dP, nb_integration_pts);
464 auto mat_ops_data = physicsPtr->matOpsDataPtr;
466 auto t_P = getFTensor2FromMat<3, 3, -1,
DL>(
467 mat_ops_data->getCommonDataPtr(
"PAtPts"));
468 auto t_P_du = getFTensor4FromMat<3, 3, 3, 3, -1,
DL>(
469 mat_ops_data->getCommonDataPtr(
"PAtPts_du"));
470 auto t_approx_P_adjoint_dstretch = getFTensor2FromMat<3, 3, -1,
DL>(
471 mat_ops_data->getCommonDataPtr(
"adjointPdstretchAtPts"));
472 auto t_u = getFTensor2FromMat<3, 3, -1,
DL>(
473 mat_ops_data->getCommonDataPtr(
"stretchH1AtPts"));
474 auto t_diff_u = getFTensor4FromMat<3, 3, 3, 3, -1,
DL>(
475 mat_ops_data->getCommonDataPtr(
"diffStretchH1AtPts"));
476 auto t_grad_h1 = getFTensor2FromMat<3, 3, -1,
DL>(
477 mat_ops_data->getCommonDataPtr(
"wGradH1AtPts"));
478 auto t_eigen_vals = getFTensor1FromMat<3, -1,
DL>(
479 mat_ops_data->getCommonDataPtr(
"eigenVals"));
480 auto t_eigen_vecs = getFTensor2FromMat<3, 3, -1,
DL>(
481 mat_ops_data->getCommonDataPtr(
"eigenVecs"));
482 auto t_invPlasticF = getFTensor2FromMat<3, 3, -1,
DL>(
483 mat_ops_data->getCommonDataPtr(
"invPlasticF"));
485 auto ts_a = getTSa();
488 auto t_dP = get_tensor_for_dP();
489 for (
auto gg = 0; gg != nb_integration_pts; ++gg) {
496 t_h1(
i,
j) = t_grad_h1(
i,
k) * t_invPlasticF(
k,
j) +
t_kd(
i,
j);
503 t_Ldiff_u(
i,
j, L) = t_diff_u(
i,
j,
m,
n) * t_L(
m,
n, L);
505 -t_Ldiff_u(
i,
j, L) * (t_P_du(
i,
j,
k,
l) * t_Ldiff_u(
k,
l,
J));
506 t_dP(L,
J) += (ts_a *
alphaU) *
507 (t_L(
i,
j, L) * (t_diff(
i,
j,
k,
l) * t_L(
k,
l,
J)));
513 t_approx_P_adjoint_dstretch(
i,
j) - t_P(
i,
k) * t_h1(
j,
k);
515 t_deltaP_sym(
i,
j) = (t_deltaP(
i,
j) || t_deltaP(
j,
i));
516 t_deltaP_sym(
i,
j) /= 2.0;
517 auto nb_uniq = getUniqNb<3>(getVectorAdaptor(&t_eigen_vals(0), 3),
522 t_dP(L,
J) += t_L(
i,
j, L) * (t_diff2_uP2(
i,
j,
k,
l) * t_L(
k,
l,
J));
528 ++t_approx_P_adjoint_dstretch;
537 return get_tensor_for_dP();
540 int row_nb_base_functions = row_data.getN().size2();
541 auto t_row_base_fun = row_data.getFTensor0N();
542 auto t_row_grad_fun = row_data.getFTensor1DiffN<3>();
544 auto t_dP = get_dP();
545 auto v = getVolume();
546 auto ts_a = getTSa();
547 auto t_w = getFTensor0IntegrationWeight();
548 auto mat_ops_data = physicsPtr->matOpsDataPtr;
549 auto t_plasticF = getFTensor2SymmetricFromMat<3, -1,
DL>(
550 mat_ops_data->getCommonDataPtr(
"plasticF"));
551 auto t_invPlasticF = getFTensor2FromMat<3, 3, -1,
DL>(
552 mat_ops_data->getCommonDataPtr(
"invPlasticF"));
554 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
555 const double det_plasticF = determinantTensor3by3(t_plasticF);
556 const double a =
v * t_w * det_plasticF;
559 for (; rr != row_nb_dofs /
size_symm; ++rr) {
561 t_row_grad_intermediate(
j) = t_row_grad_fun(
i) * t_invPlasticF(
i,
j);
562 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
563 auto t_col_grad_fun = col_data.getFTensor1DiffN<3>(gg, 0);
564 auto t_m = get_ftensor2(K,
size_symm * rr, 0);
565 for (
int cc = 0; cc != col_nb_dofs /
size_symm; ++cc) {
567 t_col_grad_intermediate(
j) = t_col_grad_fun(
i) * t_invPlasticF(
i,
j);
568 const double b =
a * t_row_base_fun * t_col_base_fun;
569 t_m(L,
J) -= b * t_dP(L,
J);
570 const double c = (
a *
alphaGradU * ts_a) * (t_row_grad_intermediate(
j) *
571 t_col_grad_intermediate(
j));
572 t_m(L,
J) +=
c * t_kd_sym(L,
J);
581 for (; rr != row_nb_base_functions; ++rr) {
597 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
598 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
599 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv)
601 externalStrainVecPtr(external_strain_vec_ptr), scalingMethodsMap{smv} {}
615 for (
auto &ext_strain_block : (*externalStrainVecPtr)) {
616 auto block_name =
"(.*)ANALYTICAL_EXTERNALSTRAIN(.*)";
617 std::regex reg_name(block_name);
618 if (std::regex_match(ext_strain_block.blockName, reg_name)) {
620 "Analytical external strain not implemented for Neo-Hookean "
624 if (ext_strain_block.ents.find(fe_ent) != ext_strain_block.ents.end()) {
626 if (scalingMethodsMap.find(ext_strain_block.blockName) !=
627 scalingMethodsMap.end()) {
629 scalingMethodsMap.at(ext_strain_block.blockName)->getScale(time);
632 <<
"No scaling method found for " << ext_strain_block.blockName;
636 double external_strain_val =
scale * ext_strain_block.val;
637 double K = ext_strain_block.bulkModulusK;
640 auto t_L = FTensor::SymmLTensor<double, 3>();
643 int nb_dofs = data.getIndices().size();
644 int nb_integration_pts = data.getN().size1();
645 auto vol = getVolume();
646 auto t_w = getFTensor0IntegrationWeight();
647 auto t_plasticF =
dataAtPts->getFTensorPlasticF(nb_integration_pts);
656 int nb_base_functions = data.getN().size2();
657 auto t_row_base_fun = data.getFTensor0N();
659 const double bulk_modulus = K;
660 const double diag_val =
662 auto fun_neohookean_bulk = [](
double K,
double tr) {
return K * tr; };
663 const double sigma_J = fun_neohookean_bulk(bulk_modulus, 3 * diag_val);
665 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
666 const double det_plasticF = determinantTensor3by3(t_plasticF);
667 const double a = vol * t_w * det_plasticF;
672 t_residual(L) = (t_L(
i,
j, L) *
t_kd(
i,
j)) * sigma_J;
675 auto t_nf = getFTensor1FromPtr<size_symm>(&*nF.data().begin());
677 for (; bb != nb_dofs /
size_symm; ++bb) {
678 t_nf(L) -= t_row_base_fun * t_residual(L);
682 for (; bb != nb_base_functions; ++bb) {
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
#define FTENSOR_INDEX(DIM, I)
Kronecker Delta class symmetric.
#define CHK_THROW_MESSAGE(err, msg)
Check and throw MoFEM exception.
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_OPERATION_UNSUCCESSFUL
@ 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 MOFEM_LOG(channel, severity)
Log.
FTensor::Index< 'i', SPACE_DIM > i
const double c
speed of light (cm/ns)
const double v
phase velocity of light in medium (cm/ns)
const double n
refractive index of diffusive medium
FTensor::Index< 'J', DIM1 > J
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
auto getDiffDiffMat(A &&t_val, B &&t_vec, Fun< double > f, Fun< double > d_f, Fun< double > dd_f, C &&t_S, const int nb)
Get the Diff Diff Mat object.
EntitiesFieldData::EntData EntData
static constexpr auto size_symm
constexpr auto field_name
FTensor::Index< 'm', 3 > m
static enum StretchSelector stretchSelector
static enum RotSelector gradApproximator
static PetscBool physicalTimeFlg
static double currentPhysicalTime
static boost::function< double(const double)> f
static boost::function< double(const double)> dd_f
static boost::function< double(const double)> d_f
static boost::function< double(const double)> inv_f
boost::shared_ptr< MatOps::MatElastic > matElasticPtr
bool providesHelmholtzFreeEnergy() const override
MatElasticPhysicalEquations(boost::shared_ptr< MatOps::MatElastic > mat_elastic_ptr, const MaterialModel material_model, const Features features)
VolUserDataOperator * returnOpCalculateHelmholtzFreeEnergy(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< double > total_helmholtz_free_energy_ptr) override
OpCalculateHelmholtzFreeEnergy(boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< MatOps::MatElastic > physics_ptr, boost::shared_ptr< double > total_helmholtz_free_energy_ptr)
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
boost::shared_ptr< double > totalHelmholtzFreeEnergyPtr
boost::shared_ptr< MatOps::MatElastic > physicsPtr
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
std::map< std::string, boost::shared_ptr< ScalingMethod > > scalingMethodsMap
boost::shared_ptr< ExternalStrainVec > externalStrainVecPtr
OpSpatialPhysicalExternalStrain(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< ExternalStrainVec > external_strain_vec_ptr, std::map< std::string, boost::shared_ptr< ScalingMethod > > smv)
MoFEMErrorCode integrate(EntData &data)
OpSpatialPhysical_du_du(std::string row_field, std::string col_field, boost::shared_ptr< MatOps::PhysicalEquations > physics_ptr, const double alpha, const double alpha_grad_u)
MoFEMErrorCode integrate(EntData &row_data, EntData &col_data)
boost::shared_ptr< MatOps::PhysicalEquations > physicsPtr
material physical equations
MoFEMErrorCode integrate(EntData &data)
boost::shared_ptr< MatOps::PhysicalEquations > physicsPtr
material physical equations
OpSpatialPhysical(const std::string &field_name, boost::weak_ptr< MatOps::PhysicalEquations > physics_ptr, const double alpha, const double alpha_grad_u)
MoFEMErrorCode getOptions()
VolUserDataOperator * returnOpSpatialPhysicalExternalStrain(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< ExternalStrainVec > external_strain_vec_ptr, std::map< std::string, boost::shared_ptr< ScalingMethod > > smv) override
VolUserDataOperator * returnOpSpatialPhysical(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha) override
MatPhysicalEquations(boost::shared_ptr< MatOps::MatPiolaResponse > mat_physical_equations_ptr, const MaterialModel material_model, const Features features)
boost::shared_ptr< MatOps::MatPiolaResponse > matPhysicalEquationsPtr
UserDataOperator * returnOpJacobian(const bool eval_rhs, const bool eval_lhs, boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr) override
VolUserDataOperator * returnOpSpatialPhysical_du_du(std::string row_field, std::string col_field, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha) override
std::bitset< LAST_FEATURE > Features
bool sYmm
If true assume that matrix is symmetric structure.
Data on single entity (This is passed as argument to DataOperator::doWork)
EntityHandle getFEEntityHandle() const
Return finite element entity handle.
@ OPROW
operator doWork function is executed on FE rows
@ OPROWCOL
operator doWork is executed on FE rows &columns
const FEMethod * getFEMethod() const
Return raw pointer to Finite Element Method object.
PetscReal ts_t
Current time value.