v0.16.0
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Private Attributes | List of all members
EshelbianPlasticity::OpTopologicalObjectivePythonImpl Struct Reference
Inheritance diagram for EshelbianPlasticity::OpTopologicalObjectivePythonImpl:
[legend]
Collaboration diagram for EshelbianPlasticity::OpTopologicalObjectivePythonImpl:
[legend]

Public Types

using OP = ForcesAndSourcesCore::UserDataOperator
 

Public Member Functions

 OpTopologicalObjectivePythonImpl (boost::shared_ptr< DataAtIntegrationPts > data_at_pts_ptr, boost::shared_ptr< TopologicalData > topo_p, boost::shared_ptr< ObjectiveFunctionData > python_ptr, const ObjectiveModelType eval_energy_model=PYTHON_MODEL)
 
MoFEMErrorCode doWork (int side, EntityType type, EntData &data)
 

Private Attributes

ObjectiveModelType evalEnergyModel = PYTHON_MODEL
 
boost::shared_ptr< DataAtIntegrationPtsdataAtPts
 
boost::shared_ptr< TopologicalDatatopoData
 
boost::shared_ptr< ObjectiveFunctionDatapythonPtr
 

Detailed Description

Definition at line 338 of file EshelbianTopologicalDerivativeOperators.cpp.

Member Typedef Documentation

◆ OP

using EshelbianPlasticity::OpTopologicalObjectivePythonImpl::OP = ForcesAndSourcesCore::UserDataOperator

Definition at line 340 of file EshelbianTopologicalDerivativeOperators.cpp.

Constructor & Destructor Documentation

◆ OpTopologicalObjectivePythonImpl()

EshelbianPlasticity::OpTopologicalObjectivePythonImpl::OpTopologicalObjectivePythonImpl ( boost::shared_ptr< DataAtIntegrationPts data_at_pts_ptr,
boost::shared_ptr< TopologicalData topo_p,
boost::shared_ptr< ObjectiveFunctionData python_ptr,
const ObjectiveModelType  eval_energy_model = PYTHON_MODEL 
)
inline

Member Function Documentation

◆ doWork()

MoFEMErrorCode EshelbianPlasticity::OpTopologicalObjectivePythonImpl::doWork ( int  side,
EntityType  type,
EntData data 
)

Definition at line 362 of file EshelbianTopologicalDerivativeOperators.cpp.

364 {
366
367#ifndef NDEBUG
368 if (!dataAtPts)
369 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
370 "DataAtIntegrationPts pointer is null");
371 if (!topoData)
372 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
373 "Topological data pointer is null");
374#endif // NDEBUG
375
376 const int nb_gauss_pts = getGaussPts().size2();
377 if (!nb_gauss_pts)
379
380 auto stress_full_ptr = boost::make_shared<MatrixDouble>();
381 auto get_stress_full =
382 MatrixSizeHelper<GetFTensor2FromMatType<SPACE_DIM, SPACE_DIM, -1, DL>,
383 DL>::size(*stress_full_ptr, nb_gauss_pts);
384 stress_full_ptr->clear();
385 auto strain_full_ptr = boost::make_shared<MatrixDouble>();
386 auto get_strain_full =
387 MatrixSizeHelper<GetFTensor2FromMatType<SPACE_DIM, SPACE_DIM, -1, DL>,
388 DL>::size(*strain_full_ptr, nb_gauss_pts);
389 strain_full_ptr->clear();
390
391 auto t_stress = get_stress_full();
392 auto t_strain = get_strain_full();
393
394 auto t_biot = dataAtPts->getFTensorAdjointPdstretch(nb_gauss_pts);
395 auto t_u = dataAtPts->getFTensorStretch(nb_gauss_pts);
396
397 auto next = [&]() {
398 ++t_stress;
399 ++t_strain;
400 ++t_biot;
401 ++t_u;
402 };
403
405
406 for (auto gg = 0; gg != nb_gauss_pts; ++gg) {
407 // we have to handle all variants, that will render how the Jacobian
408 // gradient is evaluated.
409 t_stress(i, j) = t_biot(i, j);
410 t_strain(i, j) = t_u(i, j);
411 next();
412 }
413
414 auto evaluate_python_objective = [&]() {
416 if (!pythonPtr)
417 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
418 "ObjectiveFunctionData pointer is null");
419
420 auto &coords = OP::getCoordsAtGaussPts();
421 CHKERR pythonPtr->evalInteriorObjectiveFunction(
422 coords, dataAtPts->getSmallWL2AtPts(), stress_full_ptr, strain_full_ptr,
423 topoData->getObjAtPts(), false);
424 CHKERR pythonPtr->evalInteriorObjectiveGradientStrain(
425 coords, dataAtPts->getSmallWL2AtPts(), stress_full_ptr, strain_full_ptr,
426 topoData->getObjDStrainAtPts(), false);
427 CHKERR pythonPtr->evalInteriorObjectiveGradientU(
428 coords, dataAtPts->getSmallWL2AtPts(), stress_full_ptr, strain_full_ptr,
429 topoData->getObjDDisplacementAtPts(), false);
430 CHKERR pythonPtr->evalInteriorObjectiveGradientStress(
431 coords, dataAtPts->getSmallWL2AtPts(), stress_full_ptr, strain_full_ptr,
432 topoData->getObjDStressAtPts(), false);
434 };
435
436 auto evaluate_energy_of_hencky_model = [&]() {
438
439 MatrixSizeHelper<GetFTensor1FromMatType<SPACE_DIM, -1, DL>, DL>::size(
440 *topoData->getObjDDisplacementAtPts(), nb_gauss_pts);
441 topoData->getObjDDisplacementAtPts()->clear();
442 MatrixSizeHelper<GetFTensor2FromMatType<SPACE_DIM, SPACE_DIM, -1, DL>,
443 DL>::size(*topoData->getObjDStressAtPts(), nb_gauss_pts);
444 topoData->getObjDStressAtPts()->clear();
445 MatrixSizeHelper<GetFTensor1FromMatType<SPACE_DIM, -1, DL>, DL>::size(
446 *topoData->getObjDRotationAtPts(), nb_gauss_pts);
447
448 auto eval_evergy = [&](auto &&t_D) {
449 auto get_obj =
450 MatrixSizeHelper<GetFTensor1FromMatType<1, -1, DL>, DL>::size(
451 *topoData->getObjAtPts(), nb_gauss_pts);
452 auto get_dstrain_obj =
453 MatrixSizeHelper<GetFTensor2FromMatType<SPACE_DIM, SPACE_DIM, -1, DL>,
454 DL>::size(*topoData->getObjDStrainAtPts(),
455 nb_gauss_pts);
456 auto t_obj = get_obj();
457 auto t_dstrain_obj = get_dstrain_obj();
458 auto t_log_u = dataAtPts->getFTensorLogStretchTotal(nb_gauss_pts);
459 for (int gg = 0; gg != nb_gauss_pts; ++gg) {
460 t_obj(0) = 0.5 * (t_log_u(i, j) * t_D(i, j, k, l) * t_log_u(k, l));
461 t_dstrain_obj(i, j) = t_D(i, j, k, l) * t_log_u(k, l);
462 ++t_log_u;
463 ++t_obj;
464 ++t_dstrain_obj;
465 ++t_D;
466 }
467 };
468
470 eval_evergy(
471 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(dataAtPts->matD));
472 } else {
473 eval_evergy(getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM>(dataAtPts->matD));
474 }
475
476 topoData->getObjDRotationAtPts()->clear();
478 };
479
480 auto evaluate_energy_of_hencky_model_nostreach = [&]() {
482
483 MatrixSizeHelper<GetFTensor1FromMatType<SPACE_DIM, -1, DL>, DL>::size(
484 *topoData->getObjDDisplacementAtPts(), nb_gauss_pts);
485 topoData->getObjDDisplacementAtPts()->clear();
486 MatrixSizeHelper<GetFTensor2FromMatType<SPACE_DIM, SPACE_DIM, -1, DL>,
487 DL>::size(*topoData->getObjDStrainAtPts(), nb_gauss_pts);
488 topoData->getObjDStrainAtPts()->clear();
489 MatrixSizeHelper<GetFTensor1FromMatType<SPACE_DIM, -1, DL>, DL>::size(
490 *topoData->getObjDRotationAtPts(), nb_gauss_pts);
491 topoData->getObjDRotationAtPts()->clear();
492
493 auto eval_evergy = [&](auto &&t_inv_D) {
494 auto get_obj =
495 MatrixSizeHelper<GetFTensor1FromMatType<1, -1, DL>, DL>::size(
496 *topoData->getObjAtPts(), nb_gauss_pts);
497 auto get_dstress_obj =
498 MatrixSizeHelper<GetFTensor2FromMatType<SPACE_DIM, SPACE_DIM, -1, DL>,
499 DL>::size(*topoData->getObjDStressAtPts(),
500 nb_gauss_pts);
501 auto t_obj = get_obj();
502 auto t_dstress_obj = get_dstress_obj();
503 auto t_stress = dataAtPts->getFTensorAdjointPdstretch(nb_gauss_pts);
504 for (int gg = 0; gg != nb_gauss_pts; ++gg) {
505 t_obj(0) =
506 0.5 * (t_stress(i, j) * t_inv_D(i, j, k, l) * t_stress(k, l));
507 t_dstress_obj(i, j) = t_inv_D(i, j, k, l) * t_stress(k, l);
508 ++t_stress;
509 ++t_obj;
510 ++t_dstress_obj;
511 ++t_inv_D;
512 }
513 };
514
518 eval_evergy(
519 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(dataAtPts->matInvD));
520 } else {
521 eval_evergy(
522 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM>(dataAtPts->matInvD));
523 }
525 };
526
527 auto conversion_of_biot_stress = [&]() {
529 // Python differentiates the objective with respect to Biot stress. The
530 // material equations need the corresponding Piola and rotation derivatives.
531 MatrixSizeHelper<GetFTensor1FromMatType<SPACE_DIM, -1, DL>, DL>::size(
532 *topoData->getObjDRotationAtPts(), nb_gauss_pts);
533 topoData->getObjDRotationAtPts()->clear();
534
535 auto t_obj_dbiot = topoData->getFTensorObjDStress(nb_gauss_pts);
536 auto t_obj_domega = topoData->getFTensorObjDRotation(nb_gauss_pts);
537 auto t_R = dataAtPts->getFTensorRotMat(nb_gauss_pts);
538 auto t_P = dataAtPts->getFTensorApproxP(nb_gauss_pts);
539 auto t_grad_h1 = dataAtPts->getFTensorSmallWGradH1(nb_gauss_pts);
540 auto t_omega = dataAtPts->getFTensorRotAxis(nb_gauss_pts);
541
547 constexpr auto t_kd = FTensor::Kronecker_Delta<double>();
548
549 for (auto gg = 0; gg != nb_gauss_pts; ++gg) {
551 t_dJ_dbiot(l, o) = t_obj_dbiot(l, o);
552
554 case SMALL_ROT:
555 // In the linear/small formulation Python sees the Piola field itself:
556 // B = P. There is no rotation or H1-gradient pullback to apply.
557 t_obj_dbiot(i, k) = t_dJ_dbiot(i, k);
558 t_obj_domega(m) = 0;
559 break;
560 case NO_H1_CONFIGURATION: {
563 case LARGE_ROT:
564 t_diff_R(i, l, m) =
565 LieGroups::SO3::diffExp(t_omega, t_omega.l2())(i, l, m);
566 break;
567 default:
568 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
569 "rotationSelector not handled");
570 }
571
572 // Python sees B = R^T P.
573 t_obj_dbiot(i, k) = t_R(i, l) * t_dJ_dbiot(l, k);
574 t_obj_domega(m) = t_dJ_dbiot(l, k) * t_diff_R(i, l, m) * t_P(i, k);
575 } break;
576 case LARGE_ROT:
577 case MODERATE_ROT: {
579 t_h1(o, k) = t_kd(o, k) + t_grad_h1(o, k);
580
583 case SMALL_ROT:
584 t_diff_R(i, l, m) = levi_civita(i, l, m);
585 break;
586 case LARGE_ROT:
587 t_diff_R(i, l, m) =
588 LieGroups::SO3::diffExp(t_omega, t_omega.l2())(i, l, m);
589 break;
590 default:
591 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
592 "rotationSelector not handled");
593 }
594
595 // Python sees B = R^T P H1^T.
596 t_obj_dbiot(i, k) = t_R(i, l) * (t_dJ_dbiot(l, o) * t_h1(o, k));
597 t_obj_domega(m) =
598 t_dJ_dbiot(l, o) * (t_diff_R(i, l, m) * t_P(i, k)) * t_h1(o, k);
599 } break;
600 default:
601 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
602 "gradApproximator not handled");
603 }
604
605 ++t_obj_dbiot;
606 ++t_obj_domega;
607 ++t_R;
608 ++t_P;
609 ++t_grad_h1;
610 ++t_omega;
611 }
612
614 };
615
616 auto conversion_of_stretch = [&]() {
618 // Python sees the physical stretch tensor. The stretch field stores log
619 // stretch, so convert dJ/dU to dJ/dlogU once here.
620 auto t_obj_dstretch = topoData->getFTensorObjDStrain(nb_gauss_pts);
621 auto t_diff_stretch = dataAtPts->getFTensorDiffStretch(nb_gauss_pts);
622
627
628 for (auto gg = 0; gg != nb_gauss_pts; ++gg) {
630 t_dJ_dstretch(i, j) = t_obj_dstretch(i, j);
631
632 t_obj_dstretch(k, l) = t_dJ_dstretch(i, j) * t_diff_stretch(i, j, k, l);
633
634 ++t_obj_dstretch;
635 ++t_diff_stretch;
636 }
637
639 };
640
641 auto conversion_of_stretch_to_stress_for_no_stretch = [&](auto t_inv_D) {
643 // In no-stretch mode, log stretch is computed from the stress field. Fold
644 // the objective stretch derivative into the stress derivative buffer.
645 auto t_obj_dstress = topoData->getFTensorObjDStress(nb_gauss_pts);
646 auto t_obj_dstretch = topoData->getFTensorObjDStrain(nb_gauss_pts);
647
652
653 for (auto gg = 0; gg != nb_gauss_pts; ++gg) {
655 t_dstretch_dstress(i, j) =
656 ((t_obj_dstretch(k, l) || t_obj_dstretch(l, k)) / 2.) *
657 t_inv_D(k, l, i, j);
658
659 t_obj_dstress(i, j) += t_dstretch_dstress(i, j);
660
661 ++t_obj_dstress;
662 ++t_obj_dstretch;
663 ++t_inv_D;
664 }
665
667 };
668
669 switch (evalEnergyModel) {
670 case PYTHON_MODEL:
671 CHKERR evaluate_python_objective();
672 CHKERR conversion_of_biot_stress();
677 CHKERR conversion_of_stretch_to_stress_for_no_stretch(
678 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(dataAtPts->matInvD));
679 } else {
680 CHKERR conversion_of_stretch_to_stress_for_no_stretch(
681 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM>(dataAtPts->matInvD));
682 }
683 } else {
684 CHKERR conversion_of_stretch();
685 }
686 break;
687 case HENCKY_MODEL:
689 CHKERR evaluate_energy_of_hencky_model_nostreach();
690 CHKERR conversion_of_biot_stress();
691 } else {
692 CHKERR evaluate_energy_of_hencky_model();
693 }
694 break;
695 default:
696 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
697 "Objective model type not handled");
698 }
699
701}
#define FTENSOR_INDEXES(DIM,...)
#define FTENSOR_INDEX(DIM, I)
constexpr int SPACE_DIM
Kronecker Delta class.
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
Definition definitions.h:31
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
constexpr auto t_kd
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
constexpr std::enable_if<(Dim0<=2 &&Dim1<=2), Tensor2_Expr< Levi_Civita< T >, T, Dim0, Dim1, i, j > >::type levi_civita(const Index< i, Dim0 > &, const Index< j, Dim1 > &)
levi_civita functions to make for easy adhoc use
decltype(GetFTensor1FromMatImpl< Tensor_Dim, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor1FromMatType
decltype(GetFTensor2FromMatImpl< Tensor_Dim0, Tensor_Dim1, S, DL, M >::get(std::declval< M & >(), 0, 0)) GetFTensor2FromMatType
FTensor::Index< 'm', 3 > m
static enum StretchHandling stretchHandling
static enum RotSelector rotSelector
static enum RotSelector gradApproximator
static bool hasNonHomogeneousMaterialBlock
static bool isNoStretch()
static auto diffExp(A &&t_w_vee, B &&theta)
Definition Lie.hpp:105

Member Data Documentation

◆ dataAtPts

boost::shared_ptr<DataAtIntegrationPts> EshelbianPlasticity::OpTopologicalObjectivePythonImpl::dataAtPts
private

Definition at line 357 of file EshelbianTopologicalDerivativeOperators.cpp.

◆ evalEnergyModel

ObjectiveModelType EshelbianPlasticity::OpTopologicalObjectivePythonImpl::evalEnergyModel = PYTHON_MODEL
private

Definition at line 356 of file EshelbianTopologicalDerivativeOperators.cpp.

◆ pythonPtr

boost::shared_ptr<ObjectiveFunctionData> EshelbianPlasticity::OpTopologicalObjectivePythonImpl::pythonPtr
private

Definition at line 359 of file EshelbianTopologicalDerivativeOperators.cpp.

◆ topoData

boost::shared_ptr<TopologicalData> EshelbianPlasticity::OpTopologicalObjectivePythonImpl::topoData
private

Definition at line 358 of file EshelbianTopologicalDerivativeOperators.cpp.


The documentation for this struct was generated from the following file: