static char help[] =
"...\n\n";
GAUSS>::OpMixDivTimesScalar<2>;
PETSC>::LinearForm<GAUSS>::OpSource<1, 1>;
inline double sqr(
double x) {
return x * x; }
private:
double totErrorIndicator;
double maxErrorIndicator;
double thetaParam;
double indicTolerance;
int initOrder;
static double analyticalFunction(const double x, const double y,
const double z) {
return exp(-100. * (
sqr(x) +
sqr(y))) * cos(M_PI * x) * cos(M_PI * y);
}
static VectorDouble analyticalFunctionGrad(
const double x,
const double y,
const double z) {
res.resize(2);
res[0] = -exp(-100. * (
sqr(x) +
sqr(y))) *
(200. * x * cos(M_PI * x) + M_PI * sin(M_PI * x)) * cos(M_PI * y);
res[1] = -exp(-100. * (
sqr(x) +
sqr(y))) *
(200. * y * cos(M_PI * y) + M_PI * sin(M_PI * y)) * cos(M_PI * x);
return res;
}
static double sourceFunction(const double x, const double y, const double z) {
return -exp(-100. * (
sqr(x) +
sqr(y))) *
(400. * M_PI *
(x * cos(M_PI * y) * sin(M_PI * x) +
y * cos(M_PI * x) * sin(M_PI * y)) +
2. * (20000. * (
sqr(x) +
sqr(y)) - 200. -
sqr(M_PI)) *
cos(M_PI * x) * cos(M_PI * y));
}
const char *name, DataType
type,
Tag &tag_handle) {
int int_val = 0;
double double_val = 0;
case MB_TYPE_INTEGER:
name, 1,
type, tag_handle, MB_TAG_CREAT | MB_TAG_SPARSE, &int_val);
break;
case MB_TYPE_DOUBLE:
name, 1,
type, tag_handle, MB_TAG_CREAT | MB_TAG_SPARSE, &double_val);
break;
default:
"Wrong data type %d for tag",
type);
}
}
boost::shared_ptr<VectorDouble> approxVals;
boost::shared_ptr<MatrixDouble> approxValsGrad;
boost::shared_ptr<MatrixDouble> approxFlux;
double maxErrorIndicator;
enum VecElements {
ERROR_L2_NORM = 0,
ERROR_H1_SEMINORM,
ERROR_INDICATOR_TOTAL,
LAST_ELEMENT
};
};
boost::shared_ptr<CommonData> commonDataPtr;
boost::shared_ptr<CommonData> commonDataPtr;
OpError(boost::shared_ptr<CommonData> &common_data_ptr,
:
DomainEleOp(
"U", OPROW), commonDataPtr(common_data_ptr),
mField(m_field) {
std::fill(&doEntities[MBVERTEX], &doEntities[MBMAXTYPE], false);
doEntities[MBTRI] = doEntities[MBQUAD] = true;
}
};
};
}
}
int nb_quads = 0;
CHKERR mField.
get_moab().get_number_entities_by_type(0, MBQUAD, nb_quads);
if (nb_quads) {
}
thetaParam = 0.5;
indicTolerance = 1e-3;
PETSC_NULL);
initOrder = 2;
CHKERR mField.
get_moab().get_entities_by_dimension(0, 2, domainEntities);
Tag th_order;
CHKERR getTagHandle(mField,
"ORDER", MB_TYPE_INTEGER, th_order);
for (auto ent : domainEntities) {
}
}
auto rule = [](
int,
int,
int p) ->
int {
return 2 * p; };
}
commonDataPtr = boost::make_shared<CommonData>();
PetscInt ghosts[3] = {0, 1, 2};
commonDataPtr->petscVec =
else
commonDataPtr->petscVec =
commonDataPtr->approxVals = boost::make_shared<VectorDouble>();
commonDataPtr->approxValsGrad = boost::make_shared<MatrixDouble>();
commonDataPtr->approxFlux = boost::make_shared<MatrixDouble>();
}
auto unity = []() { return 1; };
new OpHdivU(
"Q",
"U", unity,
true));
auto source = [&](
const double x,
const double y,
const double z) {
return -sourceFunction(x, y, z);
};
}
CHKERR KSPSetFromOptions(solver);
auto dm = simpleInterface->
getDM();
CHKERR VecGhostUpdateBegin(
D, INSERT_VALUES, SCATTER_FORWARD);
CHKERR VecGhostUpdateEnd(
D, INSERT_VALUES, SCATTER_FORWARD);
}
Tag th_error_ind, th_order;
CHKERR getTagHandle(mField,
"ERROR_INDICATOR", MB_TYPE_DOUBLE, th_error_ind);
CHKERR getTagHandle(mField,
"ORDER", MB_TYPE_INTEGER, th_order);
std::vector<Range> refinement_levels;
refinement_levels.resize(iter_num + 1);
for (auto ent : domainEntities) {
double err_indic = 0;
CHKERR mField.
get_moab().tag_get_data(th_error_ind, &ent, 1, &err_indic);
if (err_indic > thetaParam * maxErrorIndicator) {
refined_ents.insert(ent);
moab::Interface::UNION);
refined_ents.merge(adj);
refinement_levels[new_order - initOrder].merge(refined_ents);
}
}
for (int ll = 1; ll < refinement_levels.size(); ll++) {
refinement_levels[ll]);
if (initOrder + ll > 8) {
<< "setting approximation order higher than 8 is not currently "
"supported"
<< endl;
} else {
initOrder + ll + 1);
}
}
}
int iter_num = 1;
while (fabs(indicTolerance) > DBL_EPSILON &&
totErrorIndicator > indicTolerance) {
MOFEM_LOG(
"EXAMPLE", Sev::inform) <<
"Refinement iteration " << iter_num;
CHKERR outputResults(iter_num);
iter_num++;
if (iter_num > 100)
"Too many refinement iterations");
}
}
{HDIV, L2});
commonDataPtr->approxValsGrad));
new OpError(commonDataPtr, mField));
commonDataPtr->maxErrorIndicator = 0;
CHKERR VecZeroEntries(commonDataPtr->petscVec);
CHKERR VecAssemblyBegin(commonDataPtr->petscVec);
CHKERR VecAssemblyEnd(commonDataPtr->petscVec);
CHKERR VecGhostUpdateBegin(commonDataPtr->petscVec, INSERT_VALUES,
SCATTER_FORWARD);
CHKERR VecGhostUpdateEnd(commonDataPtr->petscVec, INSERT_VALUES,
SCATTER_FORWARD);
MPI_Allreduce(&commonDataPtr->maxErrorIndicator, &maxErrorIndicator, 1,
MPI_DOUBLE, MPI_MAX, mField.
get_comm());
const double *array;
CHKERR VecGetArrayRead(commonDataPtr->petscVec, &array);
<< "Global error indicator (max): " << commonDataPtr->maxErrorIndicator;
<< "Global error indicator (total): "
<< std::sqrt(array[CommonData::ERROR_INDICATOR_TOTAL]);
<< "Global error L2 norm: "
<< std::sqrt(array[CommonData::ERROR_L2_NORM]);
<< "Global error H1 seminorm: "
<< std::sqrt(array[CommonData::ERROR_H1_SEMINORM]);
totErrorIndicator = std::sqrt(array[CommonData::ERROR_INDICATOR_TOTAL]);
CHKERR VecRestoreArrayRead(commonDataPtr->petscVec, &array);
std::vector<Tag> tag_handles;
tag_handles.resize(4);
CHKERR getTagHandle(mField,
"ERROR_L2_NORM", MB_TYPE_DOUBLE, tag_handles[0]);
CHKERR getTagHandle(mField,
"ERROR_H1_SEMINORM", MB_TYPE_DOUBLE,
tag_handles[1]);
CHKERR getTagHandle(mField,
"ERROR_INDICATOR", MB_TYPE_DOUBLE,
tag_handles[2]);
CHKERR getTagHandle(mField,
"ORDER", MB_TYPE_INTEGER, tag_handles[3]);
ParallelComm *pcomm =
if (pcomm == NULL)
tag_handles.push_back(pcomm->part_tag());
std::ostringstream strm;
strm << "error_" << iter_num << ".h5m";
"PARALLEL=WRITE_PART", 0, 0,
tag_handles.data(), tag_handles.size());
}
auto post_proc_fe = boost::make_shared<PostProcEle>(mField);
auto u_ptr = boost::make_shared<VectorDouble>();
auto flux_ptr = boost::make_shared<MatrixDouble>();
post_proc_fe->getOpPtrVector().push_back(
post_proc_fe->getOpPtrVector().push_back(
post_proc_fe->getOpPtrVector().push_back(
new OpPPMap(post_proc_fe->getPostProcMesh(),
post_proc_fe->getMapGaussPts(),
)
);
std::ostringstream strm;
strm << "out_" << iter_num << ".h5m";
CHKERR post_proc_fe->writeFile(strm.str().c_str());
}
const int nb_integration_pts = getGaussPts().size2();
const double area = getMeasure();
auto t_w = getFTensor0IntegrationWeight();
auto t_val_grad = getFTensor1FromMat<2>(*(
commonDataPtr->approxValsGrad));
auto t_flux = getFTensor1FromMat<3>(*(
commonDataPtr->approxFlux));
auto t_coords = getFTensor1CoordsAtGaussPts();
double error_l2 = 0;
double error_h1 = 0;
double error_ind = 0;
for (int gg = 0; gg != nb_integration_pts; ++gg) {
const double alpha = t_w * area;
t_coords(0), t_coords(1), t_coords(2));
error_l2 += alpha *
sqr(diff);
t_coords(0), t_coords(1), t_coords(2));
auto t_fun_grad = getFTensor1FromArray<2, 2>(vec);
t_diff(
i) = t_val_grad(
i) - t_fun_grad(
i);
error_h1 += alpha * t_diff(
i) * t_diff(
i);
t_diff(
i) = t_val_grad(
i) - t_flux(
i);
error_ind += alpha * t_diff(
i) * t_diff(
i);
++t_w;
++t_val;
++t_val_grad;
++t_flux;
++t_coords;
}
Tag th_error_l2, th_error_h1, th_error_ind;
th_error_l2);
th_error_h1);
th_error_ind);
double error_l2_norm = sqrt(error_l2);
double error_h1_seminorm = sqrt(error_h1);
double error_ind_local = sqrt(error_ind);
&error_h1_seminorm);
&error_ind_local);
constexpr std::array<int, CommonData::LAST_ELEMENT> indices = {
std::array<double, CommonData::LAST_ELEMENT> values;
values[0] = error_l2;
values[1] = error_h1;
values[2] = error_ind;
indices.data(), values.data(), ADD_VALUES);
}
int main(
int argc,
char *argv[]) {
const char param_file[] = "param_file.petsc";
auto core_log = logging::core::get();
core_log->add_sink(
LogManager::createSink(LogManager::getStrmWorld(), "EXAMPLE"));
LogManager::setLog("EXAMPLE");
try {
DMType dm_name = "DMMOFEM";
}
}