Using PipelineManager interface calculate the curl of base functions, and integral of the vector tangent vector with normal on the boundary. Since the h-curl space is used, volume integral and boundary integral should give the same result, as a result, as we are applying Stokes theorem on h-curl space.
static char help[] =
"...\n\n";
"HCURL", UserDataOperator::OPROW),
tCurl(t_curl) {}
};
tCurl(t_curl) {}
};
int main(
int argc,
char *argv[]) {
try {
enum bases { AINSWORTH, DEMKOWICZ,
LASTOP };
const char *list[] = {"ainsworth", "demkowicz"};
PetscBool flg;
PetscInt choise_value = AINSWORTH;
&choise_value, &flg);
if (flg != PETSC_TRUE) {
}
PetscBool ho_geometry = PETSC_FALSE;
PETSC_NULL);
DMType dm_name = "DMMOFEM";
PipelineManager *pipeline_mng = m_field.
getInterface<PipelineManager>();
CHKERR simple_interface->getOptions();
CHKERR simple_interface->loadFile(
"");
switch (choise_value) {
case AINSWORTH:
CHKERR simple_interface->addDomainField(
"HCURL",
HCURL,
CHKERR simple_interface->addBoundaryField(
"HCURL",
HCURL,
break;
case DEMKOWICZ:
CHKERR simple_interface->addDomainField(
"HCURL",
HCURL,
CHKERR simple_interface->addBoundaryField(
"HCURL",
HCURL,
break;
}
if (ho_geometry == PETSC_TRUE)
CHKERR simple_interface->addDataField(
"MESH_NODE_POSITIONS",
H1,
CHKERR simple_interface->setFieldOrder(
"HCURL",
order);
if (ho_geometry == PETSC_TRUE)
CHKERR simple_interface->setFieldOrder(
"MESH_NODE_POSITIONS", 2);
CHKERR simple_interface->setUp();
auto integration_rule = [](
int,
int,
int p_data) {
return 2 * p_data; };
CHKERR pipeline_mng->setDomainRhsIntegrationRule(integration_rule);
CHKERR pipeline_mng->setBoundaryRhsIntegrationRule(integration_rule);
pipeline_mng->getOpDomainRhsPipeline().push_back(
pipeline_mng->getOpBoundaryRhsPipeline().push_back(
if (ho_geometry == PETSC_TRUE) {
Projection10NodeCoordsOnField ent_method(m_field, "MESH_NODE_POSITIONS");
}
CHKERR pipeline_mng->loopFiniteElements();
std::cout.precision(12);
std::cout << "curl_vol " << t_curl_vol << std::endl;
std::cout << "curl_skin " << t_curl_skin << std::endl;
t_curl_vol(
i) -= t_curl_skin(
i);
double nrm2 = sqrt(t_curl_vol(
i) * t_curl_vol(
i));
constexpr
double eps = 1e-8;
"Curl operator not passed test\n");
}
}
if (data.getFieldData().size() == 0)
const unsigned int nb_gauss_pts = data.getDiffN().size1();
const unsigned int nb_dofs = data.getFieldData().size();
unsigned int gg = 0;
for (; gg < nb_gauss_pts; gg++) {
double w = getGaussPts()(3, gg) * getVolume();
if (getHoGaussPtsDetJac().size() == nb_gauss_pts) {
w *= getHoGaussPtsDetJac()(gg);
}
CHKERR getCurlOfHCurlBaseFunctions(side,
type, data, gg, curl_mat);
&curl_mat(0, 2), 3);
for (
unsigned int dd = 0;
dd != nb_dofs;
dd++) {
tCurl(
i) +=
w * t_curl(
i);
++t_curl;
}
}
}
int nb_dofs = data.getFieldData().size();
if (nb_dofs == 0)
int nb_gauss_pts = data.getN().size1();
auto t_curl_base = data.getFTensor1N<3>();
double n0 = getNormal()[0] * 0.5;
double n1 = getNormal()[1] * 0.5;
double n2 = getNormal()[2] * 0.5;
for (int gg = 0; gg < nb_gauss_pts; gg++) {
for (
int dd = 0;
dd < nb_dofs;
dd++) {
double w = getGaussPts()(2, gg);
if (getNormalsAtGaussPts().size1() == (
unsigned int)nb_gauss_pts) {
n0 = getNormalsAtGaussPts(gg)[0] * 0.5;
n1 = getNormalsAtGaussPts(gg)[1] * 0.5;
n2 = getNormalsAtGaussPts(gg)[2] * 0.5;
}
tCurl(0) += (n1 * t_curl_base(2) - n2 * t_curl_base(1)) *
w;
tCurl(1) += (n2 * t_curl_base(0) - n0 * t_curl_base(2)) *
w;
tCurl(2) += (n0 * t_curl_base(1) - n1 * t_curl_base(0)) *
w;
++t_curl_base;
}
}
}
ForcesAndSourcesCore::UserDataOperator UserDataOperator
#define CATCH_ERRORS
Catch errors.
@ AINSWORTH_LEGENDRE_BASE
Ainsworth Cole (Legendre) approx. base .
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
@ HCURL
field with continuous tangents
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
@ MOFEM_ATOM_TEST_INVALID
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
#define CHKERR
Inline error check.
PetscErrorCode DMRegister_MoFEM(const char sname[])
Register MoFEM problem.
virtual MoFEMErrorCode loop_dofs(const Problem *problem_ptr, const std::string &field_name, RowColData rc, DofMethod &method, int lower_rank, int upper_rank, int verb=DEFAULT_VERBOSITY)=0
Make a loop over dofs.
int main(int argc, char *argv[])
FTensor::Index< 'j', 3 > j
FTensor::Index< 'i', 3 > i
const Tensor2_symmetric_Expr< const ddTensor0< T, Dim, i, j >, typename promote< T, double >::V, Dim, i, j > dd(const Tensor0< T * > &a, const Index< i, Dim > index1, const Index< j, Dim > index2, const Tensor1< int, Dim > &d_ijk, const Tensor1< double, Dim > &d_xyz)
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
ublas::matrix< double, ublas::row_major, DoubleAllocator > MatrixDouble
implementation of Data Operators for Forces and Sources
PetscErrorCode PetscOptionsGetBool(PetscOptions *, const char pre[], const char name[], PetscBool *bval, PetscBool *set)
PetscErrorCode PetscOptionsGetEList(PetscOptions *, const char pre[], const char name[], const char *const *list, PetscInt next, PetscInt *value, PetscBool *set)
DeprecatedCoreInterface Interface
DataForcesAndSourcesCore::EntData EntData
static MoFEMErrorCode Initialize(int *argc, char ***args, const char file[], const char help[])
Initializes the MoFEM database PETSc, MOAB and MPI.
static MoFEMErrorCode Finalize()
Checks for options to be called at the conclusion of the program.
Deprecated interface functions.
MoFEMErrorCode getInterface(const MOFEMuuid &uuid, IFACE *&iface) const
Get interface by uuid and return reference to pointer of interface.
VolumeElementForcesAndSourcesCoreBase::UserDataOperator UserDataOperator
MoFEMErrorCode doWork(int side, EntityType type, DataForcesAndSourcesCore::EntData &data)
MoFEMErrorCode doWork(int side, EntityType type, DataForcesAndSourcesCore::EntData &data)
Operator for linear form, usually to calculate values on right hand side.