1#ifndef __EPOPERATORS_HPP__
2#define __EPOPERATORS_HPP__
14using EntData = DataForcesAndSourcesCore::EntData;
84inline double get_J_fi(
const double u,
const double v,
const double w,
85 const double s)
const {
90inline double get_J_so(
const double u,
const double v,
const double w,
91 const double s)
const {
96inline double get_J_si(
const double u,
const double v,
const double w,
97 const double s)
const {
101inline double get_rhs_u(
const double u,
const double v,
const double w,
102 const double s)
const {
106inline double get_rhs_v(
const double u,
const double v,
const double w,
107 const double s)
const {
113inline double get_rhs_w(
const double u,
const double v,
const double w,
114 const double s)
const {
120inline double get_rhs_s(
const double u,
const double v,
const double w,
121 const double s)
const {
139 jac.resize(3, 3,
false);
175 int nb_dofs = data.getIndices().size();
183 int size2 = data.getN().size2();
184 if (3 * nb_dofs !=
static_cast<int>(data.getN().size2()))
186 "wrong number of dofs");
187 nN.resize(nb_dofs, nb_dofs,
false);
188 nF.resize(nb_dofs,
false);
192 auto t_row_tau = data.getFTensor1N<3>();
209 for (
int gg = 0; gg < nb_gauss_pts; gg++) {
211 nrm2 = sqrt(t_normal(
i) * t_normal(
i));
213 const double a = t_w * vol;
214 for (
int rr = 0; rr != nb_dofs; rr++) {
216 &data.getVectorN<3>(gg)(0,
HVEC0),
217 &data.getVectorN<3>(gg)(0,
HVEC1),
218 &data.getVectorN<3>(gg)(0,
HVEC2), 3);
220 for (
int cc = 0; cc != nb_dofs; cc++) {
221 nN(rr, cc) +=
a * (t_row_tau(
i) * t_normal(
i)) *
222 (t_col_tau(
i) * t_normal(
i)) / (nrm2 * nrm2);
230 nrm2 = sqrt(t_normal(
i) * t_normal(
i));
238 for (
auto &dof : data.getFieldDofs()) {
239 dof->getFieldData() =
nF[dof->getEntDofIdx()];
266 int nb_dofs = data.getFieldData().size();
277 int nb_dofs = data.getFieldData().size();
280 bool is_inner_side =
true;
283 if (nb_dofs !=
static_cast<int>(data.getN().size2()))
285 "wrong number of dofs");
286 nN.resize(nb_dofs, nb_dofs,
false);
287 nF.resize(nb_dofs,
false);
293 auto t_row_mass = data.getFTensor0N();
296 for (
int gg = 0; gg < nb_gauss_pts; gg++) {
297 const double a = t_w * vol;
298 for (
int rr = 0; rr != nb_dofs; rr++) {
299 auto t_col_mass = data.getFTensor0N(gg, 0);
301 for (
int cc = 0; cc != nb_dofs; cc++) {
302 nN(rr, cc) +=
a * t_row_mass * t_col_mass;
312 for (
auto &dof : data.getFieldDofs()) {
313 dof->getFieldData() =
nF[dof->getEntDofIdx()];
323 boost::shared_ptr<PreviousData> &data_v,
324 boost::shared_ptr<PreviousData> &data_w,
325 boost::shared_ptr<PreviousData> &data_s)
333 const int nb_dofs = data.getIndices().size();
336 if (nb_dofs !=
static_cast<int>(data.getN().size2()))
338 "wrong number of dofs");
341 vecF.resize(nb_dofs,
false);
342 mat.resize(nb_dofs, nb_dofs,
false);
345 const int nb_integration_pts =
getGaussPts().size2();
351 auto t_row_v_base = data.getFTensor0N();
355 bool is_u = ((nstep + 0) % 4) == 0;
356 bool is_v = ((nstep + 3) % 4) == 0;
357 bool is_w = ((nstep + 2) % 4) == 0;
358 bool is_s = ((nstep + 1) % 4) == 0;
361 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
362 const double a = vol * t_w;
373 for (
int rr = 0; rr != nb_dofs; ++rr) {
374 auto t_col_v_base = data.getFTensor0N(gg, 0);
377 vecF[rr] +=
a * rhs_u * t_row_v_base;
381 vecF[rr] +=
a * rhs_v * t_row_v_base;
385 vecF[rr] +=
a * rhs_w * t_row_v_base;
389 vecF[rr] +=
a * rhs_s * t_row_v_base;
392 for (
int cc = 0; cc != nb_dofs; ++cc) {
393 mat(rr, cc) +=
a * t_row_v_base * t_col_v_base;
416 cout <<
"nstep : " << nstep <<
" vecF : " <<
vecF << endl;
428 boost::shared_ptr<PreviousData>
dataU;
429 boost::shared_ptr<PreviousData>
dataV;
430 boost::shared_ptr<PreviousData>
dataW;
431 boost::shared_ptr<PreviousData>
dataS;
444 boost::shared_ptr<PreviousData> &data_v,
445 boost::shared_ptr<PreviousData> &data_w,
446 boost::shared_ptr<PreviousData> &data_s)
456 bool is_u = ((nstep + 0) % 4) == 0;
457 bool is_v = ((nstep + 3) % 4) == 0;
458 bool is_w = ((nstep + 2) % 4) == 0;
459 bool is_s = ((nstep + 1) % 4) == 0;
462 const int nb_dofs = data.getIndices().size();
464 vecF.resize(nb_dofs,
false);
467 const int nb_integration_pts =
getGaussPts().size2();
468 auto t_flux_u = getFTensor1FromMat<3>(
dataU->flux_values);
469 auto t_flux_v = getFTensor1FromMat<3>(
dataV->flux_values);
470 auto t_flux_w = getFTensor1FromMat<3>(
dataW->flux_values);
471 auto t_flux_s = getFTensor1FromMat<3>(
dataS->flux_values);
480 auto t_tau_base = data.getFTensor1N<3>();
482 auto t_tau_grad = data.getFTensor2DiffN<3, 3>();
487 for (
int gg = 0; gg < nb_integration_pts; ++gg) {
489 const double a = vol * t_w;
493 for (
int rr = 0; rr < nb_dofs; ++rr) {
494 double div_base = t_tau_grad(0, 0) + t_tau_grad(1, 1) + t_tau_grad(2, 2);
496 vecF[rr] += (K_inv * t_tau_base(
i) * t_flux_u(
i) -
497 div_base * t_val_u) *
a;
500 vecF[rr] += (K_inv * t_tau_base(
i) * t_flux_v(
i) -
501 div_base * t_val_v) *
a;
505 (K_inv * t_tau_base(
i) * t_flux_w(
i) - div_base * t_val_w) *
a;
508 vecF[rr] += (K_inv * t_tau_base(
i) * t_flux_s(
i) -
509 div_base * t_val_s) *
a;
538 boost::shared_ptr<PreviousData>
dataU;
539 boost::shared_ptr<PreviousData>
dataV;
540 boost::shared_ptr<PreviousData>
dataW;
541 boost::shared_ptr<PreviousData>
dataS;
549 boost::shared_ptr<PreviousData> &data_v,
550 boost::shared_ptr<PreviousData> &data_w,
551 boost::shared_ptr<PreviousData> &data_s)
558 const int nb_dofs = data.getIndices().size();
563 vecF.resize(nb_dofs,
false);
565 const int nb_integration_pts =
getGaussPts().size2();
576 auto t_row_v_base = data.getFTensor0N();
582 bool is_u = ((nstep + 0) % 4) == 0;
583 bool is_v = ((nstep + 3) % 4) == 0;
584 bool is_w = ((nstep + 2) % 4) == 0;
585 bool is_s = ((nstep + 1) % 4) == 0;
587 for (
int gg = 0; gg < nb_integration_pts; ++gg) {
588 const double a = vol * t_w;
590 for (
int rr = 0; rr < nb_dofs; ++rr) {
593 vecF[rr] += (t_row_v_base * (t_dot_u + t_div_u)) *
a;
595 vecF[rr] += (t_row_v_base * t_dot_v) *
a;
597 vecF[rr] += (t_row_v_base * t_dot_w) *
a;
599 vecF[rr] += (t_row_v_base * t_dot_s) *
a;
624 boost::shared_ptr<PreviousData>
dataU;
625 boost::shared_ptr<PreviousData>
dataV;
626 boost::shared_ptr<PreviousData>
dataW;
627 boost::shared_ptr<PreviousData>
dataS;
645 const int nb_row_dofs = row_data.getIndices().size();
646 const int nb_col_dofs = col_data.getIndices().size();
648 if (nb_row_dofs && nb_col_dofs) {
650 mat.resize(nb_row_dofs, nb_col_dofs,
false);
652 const int nb_integration_pts =
getGaussPts().size2();
654 auto t_row_tau_base = row_data.getFTensor1N<3>();
659 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
660 const double a = vol * t_w;
662 for (
int rr = 0; rr != nb_row_dofs; ++rr) {
663 auto t_col_tau_base = col_data.getFTensor1N<3>(gg, 0);
664 for (
int cc = 0; cc != nb_col_dofs; ++cc) {
665 mat(rr, cc) += (K_inv * t_row_tau_base(
i) * t_col_tau_base(
i)) *
a;
674 if (row_side != col_side || row_type != col_type) {
675 transMat.resize(nb_col_dofs, nb_row_dofs,
false);
701 const int nb_row_dofs = row_data.getIndices().size();
702 const int nb_col_dofs = col_data.getIndices().size();
704 if (nb_row_dofs && nb_col_dofs) {
706 mat.resize(nb_row_dofs, nb_col_dofs,
false);
708 const int nb_integration_pts =
getGaussPts().size2();
710 auto t_row_tau_base = row_data.getFTensor1N<3>();
712 auto t_row_tau_grad = row_data.getFTensor2DiffN<3, 3>();
716 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
717 const double a = vol * t_w;
718 for (
int rr = 0; rr != nb_row_dofs; ++rr) {
719 auto t_col_v_base = col_data.getFTensor0N(gg, 0);
720 for (
int cc = 0; cc != nb_col_dofs; ++cc) {
721 double div_row_base = t_row_tau_grad(0, 0) + t_row_tau_grad(1, 1) + t_row_tau_grad(2, 2);
722 mat(rr, cc) += - (div_row_base * t_col_v_base) *
a;
752 bool is_u = ((nstep + 0) % 4) == 0;
753 const int nb_row_dofs = row_data.getIndices().size();
754 const int nb_col_dofs = col_data.getIndices().size();
756 if (nb_row_dofs && nb_col_dofs) {
757 mat.resize(nb_row_dofs, nb_col_dofs,
false);
759 const int nb_integration_pts =
getGaussPts().size2();
761 auto t_row_v_base = row_data.getFTensor0N();
764 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
765 const double a = vol * t_w;
766 for (
int rr = 0; rr != nb_row_dofs; ++rr) {
767 auto t_col_tau_grad = col_data.getFTensor2DiffN<3, 3>(gg, 0);
768 for (
int cc = 0; cc != nb_col_dofs; ++cc) {
769 double div_col_base =
770 t_col_tau_grad(0, 0) + t_col_tau_grad(1, 1) + t_col_tau_grad(2, 2);
772 mat(rr, cc) += (t_row_v_base * div_col_base) *
a;
805 const int nb_row_dofs = row_data.getIndices().size();
806 const int nb_col_dofs = col_data.getIndices().size();
807 if (nb_row_dofs && nb_col_dofs) {
809 mat.resize(nb_row_dofs, nb_col_dofs,
false);
811 const int nb_integration_pts =
getGaussPts().size2();
813 auto t_row_v_base = row_data.getFTensor0N();
819 for (
int gg = 0; gg != nb_integration_pts; ++gg) {
820 const double a = vol * t_w;
822 for (
int rr = 0; rr != nb_row_dofs; ++rr) {
823 auto t_col_v_base = col_data.getFTensor0N(gg, 0);
824 for (
int cc = 0; cc != nb_col_dofs; ++cc) {
825 mat(rr, cc) += (ts_a * t_row_v_base * t_col_v_base) *
a;
835 if (row_side != col_side || row_type != col_type) {
836 transMat.resize(nb_col_dofs, nb_row_dofs,
false);
864 bool is_u_U = (((nstep + 0) % 4) == 0) && (
dataFieldName ==
"U");
865 bool is_u_V = (((nstep + 3) % 4) == 0) && (
dataFieldName ==
"V");
866 bool is_u_W = (((nstep + 2) % 4) == 0) && (
dataFieldName ==
"W");
867 bool is_u_S = (((nstep + 1) % 4) == 0) && (
dataFieldName ==
"S");
868 const int nb_row_dofs = row_data.getIndices().size();
869 const int nb_col_dofs = col_data.getIndices().size();
870 bool are_equal = (nb_row_dofs == nb_col_dofs);
871 if (nb_row_dofs && nb_col_dofs && are_equal) {
872 if ((nstep > 0) && (is_u_U || is_u_V || is_u_W || is_u_S)) {
873 for (
int ind = 0; ind < nb_row_dofs; ++ind) {
874 col_data.getFieldDofs()[ind]->getFieldData() =
875 row_data.getFieldData()[ind];
888 boost::shared_ptr<PostProcVolumeOnRefinedMesh> &post_proc)
894 bool is_u = ((
ts_step + 0) % 4) == 0;
898 int step = (int)((
ts_step) / 4);
901 "out_level_" + boost::lexical_cast<std::string>(
ts_step) +
".h5m");
909 boost::shared_ptr<PostProcVolumeOnRefinedMesh>
postProc;
void cholesky_solve(const TRIA &L, VEC &x, ublas::lower)
solve system L L^T x = b inplace
size_t cholesky_decompose(const MATRIX &A, TRIA &L)
decompose the symmetric positive definit matrix A into product L L^T.
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_DATA_INCONSISTENCY
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
PetscErrorCode DMoFEMLoopFiniteElements(DM dm, const char fe_name[], MoFEM::FEMethod *method, CacheTupleWeakPtr cache_ptr=CacheTupleSharedPtr())
Executes FEMethod for finite elements in DM.
const double v
phase velocity of light in medium (cm/ns)
double Heaviside(const double pt)
const int save_every_nth_step
FTensor::Index< 'i', 3 > i
DataForcesAndSourcesCore::EntData EntData
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
MoFEMErrorCode MatSetValues(Mat M, const EntitiesFieldData::EntData &row_data, const EntitiesFieldData::EntData &col_data, const double *ptr, InsertMode iora)
Assemble PETSc matrix.
static auto getFTensor0FromVec(ublas::vector< T, A > &data)
Get tensor rank 0 (scalar) form data vector.
MoFEMErrorCode VecSetValues(Vec V, const EntitiesFieldData::EntData &data, const double *ptr, InsertMode iora)
Assemble PETSc vector.
constexpr auto field_name
boost::shared_ptr< PostProcVolumeOnRefinedMesh > postProc
MoFEMErrorCode preProcess()
function is run at the beginning of loop
MoFEMErrorCode postProcess()
function is run at the end of loop
Monitor(MPI_Comm &comm, const int &rank, SmartPetscObj< DM > &dm, boost::shared_ptr< PostProcVolumeOnRefinedMesh > &post_proc)
MoFEMErrorCode operator()()
function is run for every finite element
MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type, EntityType col_type, EntData &row_data, EntData &col_data)
MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type, EntityType col_type, EntData &row_data, EntData &col_data)
MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type, EntityType col_type, EntData &row_data, EntData &col_data)
MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type, EntityType col_type, EntData &row_data, EntData &col_data)
boost::shared_ptr< PreviousData > dataU
boost::shared_ptr< PreviousData > dataW
boost::shared_ptr< PreviousData > dataV
boost::shared_ptr< PreviousData > dataS
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
OpAssembleSlowRhsV(boost::shared_ptr< PreviousData > &data_u, boost::shared_ptr< PreviousData > &data_v, boost::shared_ptr< PreviousData > &data_w, boost::shared_ptr< PreviousData > &data_s)
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
boost::shared_ptr< PreviousData > dataU
boost::shared_ptr< PreviousData > dataW
boost::shared_ptr< PreviousData > dataS
boost::shared_ptr< PreviousData > dataV
OpAssembleStiffRhsTau(boost::shared_ptr< PreviousData > &data_u, boost::shared_ptr< PreviousData > &data_v, boost::shared_ptr< PreviousData > &data_w, boost::shared_ptr< PreviousData > &data_s)
boost::shared_ptr< PreviousData > dataU
boost::shared_ptr< PreviousData > dataS
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
boost::shared_ptr< PreviousData > dataW
boost::shared_ptr< PreviousData > dataV
OpAssembleStiffRhsV(boost::shared_ptr< PreviousData > &data_u, boost::shared_ptr< PreviousData > &data_v, boost::shared_ptr< PreviousData > &data_w, boost::shared_ptr< PreviousData > &data_s)
MoFEMErrorCode doWork(int row_side, int col_side, EntityType row_type, EntityType col_type, EntData &row_data, EntData &col_data)
std::string dataFieldName
OpDamp_dofs_to_field_data(std::string data_field_name)
Range & essential_bd_ents
OpEssentialBC(Range &essential_bd_ents)
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
MoFEMErrorCode doWork(int side, EntityType type, EntData &data)
MoFEMErrorCode solveInitial(EntData &data)
OpInitialMass(std::string field_name, Range &inner_surface, double &inits)
double get_rhs_u(const double u, const double v, const double w, const double s) const
double get_rhs_s(const double u, const double v, const double w, const double s) const
double get_v_inf(const double u) const
double get_tau_0(const double u) const
double get_tau_s(const double u) const
double get_J_so(const double u, const double v, const double w, const double s) const
double get_w_inf(const double u) const
double get_tau_so(const double u) const
double get_tau_vMinus(const double u) const
double get_J_fi(const double u, const double v, const double w, const double s) const
double get_rhs_v(const double u, const double v, const double w, const double s) const
double get_tau_wMinus(const double u) const
double get_J_si(const double u, const double v, const double w, const double s) const
double get_rhs_w(const double u, const double v, const double w, const double s) const
bool sYmm
If true assume that matrix is symmetric structure.
structure for User Loop Methods on finite elements
default operator for TRI element
MatrixDouble & getNormalsAtGaussPts()
if higher order geometry return normals at Gauss pts.
VectorDouble & getNormal()
get triangle normal
EntityHandle getFEEntityHandle() const
Return finite element entity handle.
auto getFTensor1CoordsAtGaussPts()
Get coordinates at integration points assuming linear geometry.
auto getFTensor0IntegrationWeight()
Get integration weights.
double getMeasure() const
get measure of element
@ 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.
MatrixDouble & getGaussPts()
matrix of integration (Gauss) points for Volume Element
intrusive_ptr for managing petsc objects
PetscReal ts_a
shift for U_t (see PETSc Time Solver)
PetscInt ts_step
time step number
Volume finite element base.