17 boost::shared_ptr<MatOps::PhysicalEquations> mat_physical_equations_ptr)
25 PetscOptionsBegin(PETSC_COMM_WORLD,
"meta_",
"",
"none");
27 CHKERR PetscOptionsScalar(
"-viscosity_alpha_grad_u",
"viscosity",
"",
36 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
37 boost::shared_ptr<PhysicalEquations> physics_ptr)
override {
44 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
45 const double alpha)
override {
51 std::string row_field, std::string col_field,
52 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
const double alpha) {
62 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
63 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
64 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv);
75 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
76 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
77 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv) {
79 external_strain_vec_ptr, smv);
89 boost::weak_ptr<MatOps::PhysicalEquations> physics_ptr,
90 const double alpha,
const double alpha_grad_u)
99 boost::shared_ptr<MatOps::PhysicalEquations>
105 std::string row_field, std::string col_field,
106 boost::shared_ptr<MatOps::PhysicalEquations> physics_ptr,
107 const double alpha,
const double alpha_grad_u)
118 boost::shared_ptr<MatOps::PhysicalEquations>
128 auto mat_ops_data = physics_ptr->matOpsDataPtr;
133 int nb_dofs = data.getIndices().size();
134 int nb_integration_pts = data.getN().size1();
138 auto t_P = getFTensor2FromMat<3, 3, -1,
DL>(
139 mat_ops_data->getCommonDataPtr(
"PAtPts"));
140 auto t_approx_P_adjoint_log_du = getFTensor1FromMat<
size_symm, -1,
DL>(
141 mat_ops_data->getCommonDataPtr(
"adjointPdUAtPts"));
142 auto t_diff_u = getFTensor4FromMat<3, 3, 3, 3, -1,
DL>(
143 mat_ops_data->getCommonDataPtr(
"diffStretchH1AtPts"));
144 auto t_dot_log_u = getFTensor2SymmetricFromMat<3, -1,
DL>(
145 mat_ops_data->getCommonDataPtr(
"logStretchDotTensorAtPts"));
146 auto t_grad_dot_log_u = getFTensor2FromMat<
size_symm, 3, -1,
DL>(
147 mat_ops_data->getCommonDataPtr(
"gradLogStretchDotTensorAtPts"));
156 auto get_ftensor2 = [](
auto &
v) {
158 &
v[0], &
v[1], &
v[2], &
v[3], &
v[4], &
v[5]);
161 int nb_base_functions = data.getN().size2();
162 auto t_row_base_fun = data.getFTensor0N();
163 auto t_row_grad_fun = data.getFTensor1DiffN<3>();
164 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
166 auto t_nf = get_ftensor2(
nF);
169 t_Ldiff_u(
i,
j, L) = t_diff_u(
i,
j,
k,
l) * t_L(
k,
l, L);
173 a * (t_approx_P_adjoint_log_du(L) - t_Ldiff_u(
i,
j, L) * t_P(
i,
j));
174 t_residual(L) += (
a *
alphaU) * (t_dot_log_u(
i,
j) * t_L(
i,
j, L));
177 t_grad_residual(L,
i) = (
a *
alphaGradU) * t_grad_dot_log_u(L,
i);
180 for (; bb != nb_dofs /
size_symm; ++bb) {
181 t_nf(L) -= t_row_base_fun * t_residual(L);
182 t_nf(L) += t_row_grad_fun(
i) * t_grad_residual(L,
i);
187 for (; bb != nb_base_functions; ++bb) {
193 ++t_approx_P_adjoint_log_du;
214 int nb_integration_pts = row_data.getN().size1();
215 int row_nb_dofs = row_data.getIndices().size();
216 int col_nb_dofs = col_data.getIndices().size();
218 auto get_ftensor2 = [](MatrixDouble &
m,
const int r,
const int c) {
222 &
m(r + 0,
c + 0), &
m(r + 0,
c + 1), &
m(r + 0,
c + 2), &
m(r + 0,
c + 3),
223 &
m(r + 0,
c + 4), &
m(r + 0,
c + 5),
225 &
m(r + 1,
c + 0), &
m(r + 1,
c + 1), &
m(r + 1,
c + 2), &
m(r + 1,
c + 3),
226 &
m(r + 1,
c + 4), &
m(r + 1,
c + 5),
228 &
m(r + 2,
c + 0), &
m(r + 2,
c + 1), &
m(r + 2,
c + 2), &
m(r + 2,
c + 3),
229 &
m(r + 2,
c + 4), &
m(r + 2,
c + 5),
231 &
m(r + 3,
c + 0), &
m(r + 3,
c + 1), &
m(r + 3,
c + 2), &
m(r + 3,
c + 3),
232 &
m(r + 3,
c + 4), &
m(r + 3,
c + 5),
234 &
m(r + 4,
c + 0), &
m(r + 4,
c + 1), &
m(r + 4,
c + 2), &
m(r + 4,
c + 3),
235 &
m(r + 4,
c + 4), &
m(r + 4,
c + 5),
237 &
m(r + 5,
c + 0), &
m(r + 5,
c + 1), &
m(r + 5,
c + 2), &
m(r + 5,
c + 3),
238 &
m(r + 5,
c + 4), &
m(r + 5,
c + 5)
252 auto get_dP = [&]() {
253 auto get_tensor_for_dP =
255 DL>::size(dP, nb_integration_pts);
257 auto mat_ops_data = physicsPtr->matOpsDataPtr;
259 auto t_P = getFTensor2FromMat<3, 3, -1,
DL>(
260 mat_ops_data->getCommonDataPtr(
"PAtPts"));
261 auto t_P_du = getFTensor4FromMat<3, 3, 3, 3, -1,
DL>(
262 mat_ops_data->getCommonDataPtr(
"PAtPts_du"));
263 auto t_approx_P_adjoint_dstretch = getFTensor2FromMat<3, 3, -1,
DL>(
264 mat_ops_data->getCommonDataPtr(
"adjointPdstretchAtPts"));
265 auto t_u = getFTensor2FromMat<3, 3, -1,
DL>(
266 mat_ops_data->getCommonDataPtr(
"stretchH1AtPts"));
267 auto t_diff_u = getFTensor4FromMat<3, 3, 3, 3, -1,
DL>(
268 mat_ops_data->getCommonDataPtr(
"diffStretchH1AtPts"));
269 auto t_grad_h1 = getFTensor2FromMat<3, 3, -1,
DL>(
270 mat_ops_data->getCommonDataPtr(
"wGradH1AtPts"));
271 auto t_eigen_vals = getFTensor1FromMat<3, -1,
DL>(
272 mat_ops_data->getCommonDataPtr(
"eigenVals"));
273 auto t_eigen_vecs = getFTensor2FromMat<3, 3, -1,
DL>(
274 mat_ops_data->getCommonDataPtr(
"eigenVecs"));
276 auto ts_a = getTSa();
279 auto t_dP = get_tensor_for_dP();
280 for (
auto gg = 0; gg != nb_integration_pts; ++gg) {
294 t_Ldiff_u(
i,
j, L) = t_diff_u(
i,
j,
m,
n) * t_L(
m,
n, L);
296 -t_Ldiff_u(
i,
j, L) * (t_P_du(
i,
j,
k,
l) * t_Ldiff_u(
k,
l,
J));
297 t_dP(L,
J) += (ts_a * alphaU) *
298 (t_L(
i,
j, L) * (t_diff(
i,
j,
k,
l) * t_L(
k,
l,
J)));
304 t_approx_P_adjoint_dstretch(
i,
j) - t_P(
i,
k) * t_h1(
j,
k);
306 t_deltaP_sym(
i,
j) = (t_deltaP(
i,
j) || t_deltaP(
j,
i));
307 t_deltaP_sym(
i,
j) /= 2.0;
309 getUniqNb<3>(getVectorAdaptor(&t_eigen_vals(0), 3),
314 t_dP(L,
J) += t_L(
i,
j, L) * (t_diff2_uP2(
i,
j,
k,
l) * t_L(
k,
l,
J));
320 ++t_approx_P_adjoint_dstretch;
328 return get_tensor_for_dP();
331 int row_nb_base_functions = row_data.getN().size2();
332 auto t_row_base_fun = row_data.getFTensor0N();
333 auto t_row_grad_fun = row_data.getFTensor1DiffN<3>();
335 auto t_dP = get_dP();
336 auto v = getVolume();
337 auto ts_a = getTSa();
338 auto t_w = getFTensor0IntegrationWeight();
340 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
344 for (; rr != row_nb_dofs /
size_symm; ++rr) {
345 auto t_col_base_fun = col_data.getFTensor0N(gg, 0);
346 auto t_col_grad_fun = col_data.getFTensor1DiffN<3>(gg, 0);
347 auto t_m = get_ftensor2(K,
size_symm * rr, 0);
348 for (
int cc = 0; cc != col_nb_dofs /
size_symm; ++cc) {
349 const double b =
a * t_row_base_fun * t_col_base_fun;
350 t_m(L,
J) -= b * t_dP(L,
J);
352 (t_row_grad_fun(
i) * t_col_grad_fun(
i));
353 t_m(L,
J) +=
c * t_kd_sym(L,
J);
362 for (; rr != row_nb_base_functions; ++rr) {
376 boost::shared_ptr<DataAtIntegrationPts> data_ptr,
377 boost::shared_ptr<ExternalStrainVec> external_strain_vec_ptr,
378 std::map<std::string, boost::shared_ptr<ScalingMethod>> smv)
380 externalStrainVecPtr(external_strain_vec_ptr), scalingMethodsMap{smv} {}
396 for (
auto &ext_strain_block : (*externalStrainVecPtr)) {
397 auto block_name =
"(.*)ANALYTICAL_EXTERNALSTRAIN(.*)";
398 std::regex reg_name(block_name);
399 if (std::regex_match(ext_strain_block.blockName, reg_name)) {
401 "Analytical external strain not implemented for Neo-Hookean "
405 if (ext_strain_block.ents.find(fe_ent) != ext_strain_block.ents.end()) {
407 if (scalingMethodsMap.find(ext_strain_block.blockName) !=
408 scalingMethodsMap.end()) {
410 scalingMethodsMap.at(ext_strain_block.blockName)->getScale(time);
413 <<
"No scaling method found for " << ext_strain_block.blockName;
417 double external_strain_val =
scale * ext_strain_block.val;
418 double K = ext_strain_block.bulkModulusK;
424 int nb_dofs = data.getIndices().size();
425 int nb_integration_pts = data.getN().size1();
426 auto vol = getVolume();
427 auto t_w = getFTensor0IntegrationWeight();
436 int nb_base_functions = data.getN().size2();
437 auto t_row_base_fun = data.getFTensor0N();
439 const double bulk_modulus = K;
440 const double diag_val =
442 auto fun_neohookean_bulk = [](
double K,
double tr) {
return K * tr; };
443 const double sigma_J = fun_neohookean_bulk(bulk_modulus, 3 * diag_val);
445 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
446 double a = vol * t_w;
450 t_residual(L) = (t_L(
i,
j, L) *
t_kd(
i,
j)) * sigma_J;
453 auto t_nf = getFTensor1FromPtr<size_symm>(&*nF.data().begin());
455 for (; bb != nb_dofs /
size_symm; ++bb) {
456 t_nf(L) -= t_row_base_fun * t_residual(L);
460 for (; bb != nb_base_functions; ++bb) {
#define FTENSOR_INDEX(DIM, I)
Fourth-order differential tensor symmetric in both index pairs.
Kronecker Delta class symmetric.
Mapping from symmetric tensor indices to packed storage index.
#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 ...
#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
ForcesAndSourcesCore::UserDataOperator UserDataOperator
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
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)
VolUserDataOperator * returnOpSpatialPhysical(const std::string &field_name, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha) override
VolUserDataOperator * returnOpSpatialPhysical_du_du(std::string row_field, std::string col_field, boost::shared_ptr< DataAtIntegrationPts > data_ptr, const double alpha)
MatPhysicalEquations(boost::shared_ptr< MatOps::PhysicalEquations > mat_physical_equations_ptr)
boost::shared_ptr< MatOps::PhysicalEquations > matPhysicalEquationsPtr
UserDataOperator * returnOpJacobian(const bool eval_rhs, const bool eval_lhs, boost::shared_ptr< DataAtIntegrationPts > data_ptr, boost::shared_ptr< PhysicalEquations > physics_ptr) override
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.
auto getFTensor0IntegrationWeight()
Get integration weights.
@ 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.
double getVolume() const
element volume (linear geometry)
VectorDouble nF
local right hand side vector