v0.16.3
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< DataAtIntegrationPts > dataAtPts
 
boost::shared_ptr< TopologicalData > topoData
 
boost::shared_ptr< ObjectiveFunctionData > pythonPtr
 

Detailed Description

Definition at line 333 of file EshelbianTopologicalDerivativeOperators.cpp.

Member Typedef Documentation

◆ OP

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

Definition at line 335 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 354 of file EshelbianTopologicalDerivativeOperators.cpp.

356 {
358
359#ifndef NDEBUG
360 if (!dataAtPts)
361 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
362 "DataAtIntegrationPts pointer is null");
363 if (!topoData)
364 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
365 "Topological data pointer is null");
366#endif // NDEBUG
367
368 const int nb_gauss_pts = getGaussPts().size2();
369 if (!nb_gauss_pts)
371
372 MatrixSizeHelper<GetFTensor1FromMatType<3, -1, DL>, DL>::size(
373 *topoData->objConstantRotation, nb_gauss_pts);
374 topoData->objConstantRotation->clear();
375 const auto &features = dataAtPts->physicsPtr->getFeatures();
376 const auto variable_compliance_mask =
380
381 auto stress_full_ptr = boost::make_shared<MatrixDouble>();
382 auto get_stress_full =
383 MatrixSizeHelper<GetFTensor2FromMatType<SPACE_DIM, SPACE_DIM, -1, DL>,
384 DL>::size(*stress_full_ptr, nb_gauss_pts);
385 stress_full_ptr->clear();
386 auto strain_full_ptr = boost::make_shared<MatrixDouble>();
387 auto get_strain_full =
388 MatrixSizeHelper<GetFTensor2FromMatType<SPACE_DIM, SPACE_DIM, -1, DL>,
389 DL>::size(*strain_full_ptr, nb_gauss_pts);
390 strain_full_ptr->clear();
391
392 auto t_stress = get_stress_full();
393 auto t_strain = get_strain_full();
394
395 auto t_biot = dataAtPts->getFTensorAdjointPdstretch(nb_gauss_pts);
396 auto t_u = dataAtPts->getFTensorStretch(nb_gauss_pts);
397
398 auto next = [&]() {
399 ++t_stress;
400 ++t_strain;
401 ++t_biot;
402 ++t_u;
403 };
404
406
407 for (auto gg = 0; gg != nb_gauss_pts; ++gg) {
408 // we have to handle all variants, that will render how the Jacobian
409 // gradient is evaluated.
410 t_stress(i, j) = t_biot(i, j);
411 t_strain(i, j) = t_u(i, j);
412 next();
413 }
414
415 auto evaluate_python_objective = [&]() {
417 if (!pythonPtr)
418 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
419 "ObjectiveFunctionData pointer is null");
420
421 auto &coords = OP::getCoordsAtGaussPts();
422 CHKERR pythonPtr->evalInteriorObjectiveFunction(
423 coords, dataAtPts->getSmallWL2AtPts(), stress_full_ptr, strain_full_ptr,
424 topoData->getObjAtPts(), false);
425 CHKERR pythonPtr->evalInteriorObjectiveGradientStrain(
426 coords, dataAtPts->getSmallWL2AtPts(), stress_full_ptr, strain_full_ptr,
427 topoData->getObjDStrainAtPts(), false);
428 CHKERR pythonPtr->evalInteriorObjectiveGradientU(
429 coords, dataAtPts->getSmallWL2AtPts(), stress_full_ptr, strain_full_ptr,
430 topoData->getObjDDisplacementAtPts(), false);
431 CHKERR pythonPtr->evalInteriorObjectiveGradientStress(
432 coords, dataAtPts->getSmallWL2AtPts(), stress_full_ptr, strain_full_ptr,
433 topoData->getObjDStressAtPts(), false);
435 };
436
437 auto evaluate_energy_of_hencky_model = [&]() {
439
440 MatrixSizeHelper<GetFTensor1FromMatType<SPACE_DIM, -1, DL>, DL>::size(
441 *topoData->getObjDDisplacementAtPts(), nb_gauss_pts);
442 topoData->getObjDDisplacementAtPts()->clear();
443 MatrixSizeHelper<GetFTensor2FromMatType<SPACE_DIM, SPACE_DIM, -1, DL>,
444 DL>::size(*topoData->getObjDStressAtPts(), nb_gauss_pts);
445 topoData->getObjDStressAtPts()->clear();
446 MatrixSizeHelper<GetFTensor1FromMatType<SPACE_DIM, -1, DL>, DL>::size(
447 *topoData->getObjDRotationAtPts(), nb_gauss_pts);
448
449 auto eval_evergy = [&](auto &&t_D) {
450 auto get_obj =
451 MatrixSizeHelper<GetFTensor1FromMatType<1, -1, DL>, DL>::size(
452 *topoData->getObjAtPts(), nb_gauss_pts);
453 auto get_dstrain_obj =
454 MatrixSizeHelper<GetFTensor2FromMatType<SPACE_DIM, SPACE_DIM, -1, DL>,
455 DL>::size(*topoData->getObjDStrainAtPts(),
456 nb_gauss_pts);
457 auto t_obj = get_obj();
458 auto t_dstrain_obj = get_dstrain_obj();
459 auto t_log_u = dataAtPts->getFTensorLogStretchTotal(nb_gauss_pts);
460 for (int gg = 0; gg != nb_gauss_pts; ++gg) {
461 t_obj(0) = 0.5 * (t_log_u(i, j) * t_D(i, j, k, l) * t_log_u(k, l));
462 t_dstrain_obj(i, j) = t_D(i, j, k, l) * t_log_u(k, l);
463 ++t_log_u;
464 ++t_obj;
465 ++t_dstrain_obj;
466 ++t_D;
467 }
468 };
469
471 eval_evergy(
472 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(dataAtPts->matD));
473 } else {
474 eval_evergy(getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM>(dataAtPts->matD));
475 }
476
477 topoData->getObjDRotationAtPts()->clear();
479 };
480
481 auto evaluate_energy_of_hencky_model_nostreach = [&]() {
483
484 MatrixSizeHelper<GetFTensor1FromMatType<SPACE_DIM, -1, DL>, DL>::size(
485 *topoData->getObjDDisplacementAtPts(), nb_gauss_pts);
486 topoData->getObjDDisplacementAtPts()->clear();
487 MatrixSizeHelper<GetFTensor2FromMatType<SPACE_DIM, SPACE_DIM, -1, DL>,
488 DL>::size(*topoData->getObjDStrainAtPts(), nb_gauss_pts);
489 topoData->getObjDStrainAtPts()->clear();
490 MatrixSizeHelper<GetFTensor1FromMatType<SPACE_DIM, -1, DL>, DL>::size(
491 *topoData->getObjDRotationAtPts(), nb_gauss_pts);
492 topoData->getObjDRotationAtPts()->clear();
493
494 auto eval_evergy = [&](auto &&t_inv_D) {
495 auto get_obj =
496 MatrixSizeHelper<GetFTensor1FromMatType<1, -1, DL>, DL>::size(
497 *topoData->getObjAtPts(), nb_gauss_pts);
498 auto get_dstress_obj =
499 MatrixSizeHelper<GetFTensor2FromMatType<SPACE_DIM, SPACE_DIM, -1, DL>,
500 DL>::size(*topoData->getObjDStressAtPts(),
501 nb_gauss_pts);
502 auto t_obj = get_obj();
503 auto t_dstress_obj = get_dstress_obj();
504 auto t_stress = dataAtPts->getFTensorAdjointPdstretch(nb_gauss_pts);
505 for (int gg = 0; gg != nb_gauss_pts; ++gg) {
506 t_obj(0) =
507 0.5 * (t_stress(i, j) * t_inv_D(i, j, k, l) * t_stress(k, l));
508 t_dstress_obj(i, j) = t_inv_D(i, j, k, l) * t_stress(k, l);
509 ++t_stress;
510 ++t_obj;
511 ++t_dstress_obj;
512 ++t_inv_D;
513 }
514 };
515
516 if ((features & variable_compliance_mask).none()) {
517 eval_evergy(
518 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(dataAtPts->matInvD));
519 } else {
520 eval_evergy(
521 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM>(dataAtPts->matInvD));
522 }
524 };
525
526 auto conversion_of_biot_stress = [&]() {
528 // Pull Python's Biot-stress covector back to Piola and both rotation
529 // factors.
530 MatrixSizeHelper<GetFTensor1FromMatType<3, -1, DL>, DL>::size(
531 *topoData->getObjDRotationAtPts(), nb_gauss_pts);
532 topoData->getObjDRotationAtPts()->clear();
533 auto objective = topoData->getFTensorObjDStress(nb_gauss_pts);
534 auto R = dataAtPts->getFTensorRotMat(nb_gauss_pts);
535 auto P = dataAtPts->getFTensorApproxP(nb_gauss_pts);
536 auto gradient = dataAtPts->getFTensorSmallWGradH1(nb_gauss_pts);
537 FTENSOR_INDEXES(3, i, k, l, m, o);
538 constexpr auto identity = FTensor::Kronecker_Delta<double>();
539 for (int gg = 0; gg != nb_gauss_pts; ++gg) {
541 covector(l, o) = objective(l, o);
542 h1(o, k) = identity(o, k);
545 h1(o, k) += gradient(o, k);
546 objective(i, k) = R(i, l) * (covector(l, o) * h1(o, k));
547 for (int mode = 0; mode != 2; ++mode) {
550 using namespace LogarithmicDirectionalDerivatives;
551 const auto read = [&](MatrixPtr values) {
552 Vector result;
553 auto view = GetFTensor1FromMatImpl<3, -1, DL, MatrixDouble>::get(
554 *values, gg, 0);
555 result(i) = view(i);
556 return result;
557 };
558 const SplitRotation rotation(read(dataAtPts->constantRotation),
559 read(dataAtPts->higherRotation));
560 derivative(i, l, m) = rotation.firstTensor(mode)(i, l, m);
561 } else {
562 derivative(i, l, m) = levi_civita(i, l, m);
563 }
564 auto rotation_covector =
565 topoData->getFTensorObjDRotation(nb_gauss_pts, mode, gg);
566 rotation_covector(m) =
567 covector(l, o) * (derivative(i, l, m) * P(i, k)) * h1(o, k);
568 }
569 }
570 ++objective;
571 ++R;
572 ++P;
573 ++gradient;
574 }
576 };
577
578 auto conversion_of_stretch = [&]() {
580 // Python sees the physical stretch tensor. The stretch field stores log
581 // stretch, so convert dJ/dU to dJ/dlogU once here.
582 auto t_obj_dstretch = topoData->getFTensorObjDStrain(nb_gauss_pts);
583 auto t_diff_stretch = dataAtPts->getFTensorDiffStretch(nb_gauss_pts);
584
589
590 for (auto gg = 0; gg != nb_gauss_pts; ++gg) {
592 t_dJ_dstretch(i, j) = t_obj_dstretch(i, j);
593
594 t_obj_dstretch(k, l) = t_dJ_dstretch(i, j) * t_diff_stretch(i, j, k, l);
595
596 ++t_obj_dstretch;
597 ++t_diff_stretch;
598 }
599
601 };
602
603 auto conversion_of_stretch_to_stress_for_no_stretch = [&](auto t_inv_D) {
605 // In no-stretch mode, log stretch is computed from the stress field. Fold
606 // the objective stretch derivative into the stress derivative buffer.
607 auto t_obj_dstress = topoData->getFTensorObjDStress(nb_gauss_pts);
608 auto t_obj_dstretch = topoData->getFTensorObjDStrain(nb_gauss_pts);
609
614
615 for (auto gg = 0; gg != nb_gauss_pts; ++gg) {
617 t_dstretch_dstress(i, j) =
618 ((t_obj_dstretch(k, l) || t_obj_dstretch(l, k)) / 2.) *
619 t_inv_D(k, l, i, j);
620
621 t_obj_dstress(i, j) += t_dstretch_dstress(i, j);
622
623 ++t_obj_dstress;
624 ++t_obj_dstretch;
625 ++t_inv_D;
626 }
627
629 };
630
631 switch (evalEnergyModel) {
632 case PYTHON_MODEL:
633 CHKERR evaluate_python_objective();
634 CHKERR conversion_of_biot_stress();
636 if ((features & variable_compliance_mask).none()) {
637 CHKERR conversion_of_stretch_to_stress_for_no_stretch(
638 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM, 0>(dataAtPts->matInvD));
639 } else {
640 CHKERR conversion_of_stretch_to_stress_for_no_stretch(
641 getFTensor4DdgFromMat<SPACE_DIM, SPACE_DIM>(dataAtPts->matInvD));
642 }
643 } else {
644 CHKERR conversion_of_stretch();
645 }
646 break;
647 case HENCKY_MODEL:
649 CHKERR evaluate_energy_of_hencky_model_nostreach();
650 CHKERR conversion_of_biot_stress();
651 } else {
652 CHKERR evaluate_energy_of_hencky_model();
653 }
654 break;
655 default:
656 SETERRQ(PETSC_COMM_SELF, MOFEM_DATA_INCONSISTENCY,
657 "Objective model type not handled");
658 }
659
661}
SmartPetscObj< Vec > gradient
SmartPetscObj< Vec > values
PetscInt size
#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.
const char features[]
@ R
FTensor::Index< 'i', SPACE_DIM > i
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
boost::shared_ptr< MatrixDouble > MatrixPtr
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 RotSelector rotSelector
static enum RotSelector gradApproximator
@ NO_STRETCH_NONLINEAR
No-stretch nonlinear formulation.

Member Data Documentation

◆ dataAtPts

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

Definition at line 349 of file EshelbianTopologicalDerivativeOperators.cpp.

◆ evalEnergyModel

ObjectiveModelType EshelbianPlasticity::OpTopologicalObjectivePythonImpl::evalEnergyModel = PYTHON_MODEL
private

Definition at line 348 of file EshelbianTopologicalDerivativeOperators.cpp.

◆ pythonPtr

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

Definition at line 351 of file EshelbianTopologicalDerivativeOperators.cpp.

◆ topoData

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

Definition at line 350 of file EshelbianTopologicalDerivativeOperators.cpp.


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