19int main(
int argc, 
char *argv[]) {
 
   25  moab::Core mb_instance;              
 
   26  moab::Interface &moab = mb_instance; 
 
   35    PetscBool flg = PETSC_TRUE;
 
   37    PetscBool test_jacobian = PETSC_FALSE;
 
   63    Range triangle_springs;
 
   65      if (it->getName().compare(0, 9, 
"SPRING_BC") == 0) {
 
   67                                                       triangle_springs, 
true);
 
   73                                           "MESH_NODE_POSITIONS");
 
   75        m_field, 
"SPATIAL_POSITION", 
"MESH_NODE_POSITIONS", triangle_springs);
 
   85    PetscRandomCreate(PETSC_COMM_WORLD, &rctx);
 
   87    auto set_coord = [&](
VectorAdaptor &&field_data, 
double *x, 
double *y,
 
   92      PetscRandomGetValue(rctx, &value);
 
   93      field_data[0] = (*x) + (value - 0.5) * 
scale;
 
   94      PetscRandomGetValue(rctx, &value);
 
   95      field_data[1] = (*y) + (value - 0.5) * 
scale;
 
   96      PetscRandomGetValue(rctx, &value);
 
   97      field_data[2] = (*z) + (value - 0.5) * 
scale;
 
  104        set_coord, 
"MESH_NODE_POSITIONS");
 
  106    PetscRandomDestroy(&rctx);
 
  108    boost::shared_ptr<NeumannForcesSurface> surfacePressure(
 
  111    boost::shared_ptr<NeumannForcesSurface::MyTriangleFE> fe_rhs_ptr(
 
  112        surfacePressure, &(surfacePressure->getLoopFe()));
 
  113    boost::shared_ptr<NeumannForcesSurface::MyTriangleFE> fe_lhs_ptr(
 
  114        surfacePressure, &(surfacePressure->getLoopFeLhs()));
 
  115    boost::shared_ptr<NeumannForcesSurface::MyTriangleFE> fe_mat_rhs_ptr(
 
  116        surfacePressure, &(surfacePressure->getLoopFeMatRhs()));
 
  117    boost::shared_ptr<NeumannForcesSurface::MyTriangleFE> fe_mat_lhs_ptr(
 
  118        surfacePressure, &(surfacePressure->getLoopFeMatLhs()));
 
  125    boost::shared_ptr<NeumannForcesSurface> surfaceForce(
 
  128    boost::shared_ptr<NeumannForcesSurface::MyTriangleFE>
 
  129        fe_rhs_surface_force_ptr(surfaceForce, &(surfaceForce->getLoopFe()));
 
  130    boost::shared_ptr<NeumannForcesSurface::MyTriangleFE>
 
  131        fe_lhs_surface_force_ptr(surfaceForce, &(surfaceForce->getLoopFeLhs()));
 
  132    boost::shared_ptr<NeumannForcesSurface::MyTriangleFE>
 
  133        fe_mat_rhs_surface_force_ptr(surfaceForce,
 
  134                                     &(surfaceForce->getLoopFeMatRhs()));
 
  135    boost::shared_ptr<NeumannForcesSurface::MyTriangleFE>
 
  136        fe_mat_lhs_surface_force_ptr(surfaceForce,
 
  137                                     &(surfaceForce->getLoopFeMatLhs()));
 
  149    CHKERR moab.get_entities_by_type(0, MBVERTEX, nodes, 
false);
 
  154    boost::shared_ptr<NeumannForcesSurface::DataAtIntegrationPts> dataAtPts =
 
  155        boost::make_shared<NeumannForcesSurface::DataAtIntegrationPts>();
 
  157    dataAtPts->forcesOnlyOnEntitiesRow = nodes;
 
  160      if (
bit->getName().compare(0, 8, 
"PRESSURE") == 0) {
 
  161        CHKERR surfacePressure->addPressure(
"SPATIAL_POSITION", PETSC_NULLPTR,
 
  162                                            bit->getMeshsetId(), 
true, 
true);
 
  163        CHKERR surfacePressure->addPressureAle(
 
  164            "SPATIAL_POSITION", 
"MESH_NODE_POSITIONS", dataAtPts,
 
  170    const string block_set_force_name(
"FORCE");
 
  174      CHKERR surfaceForce->addForce(
"SPATIAL_POSITION", PETSC_NULLPTR,
 
  175                                    (
bit->getMeshsetId()), 
true, 
false);
 
  176      CHKERR surfaceForce->addForceAle(
 
  177          "SPATIAL_POSITION", 
"MESH_NODE_POSITIONS", dataAtPts,
 
  183      if (it->getName().compare(0, block_set_force_name.length(),
 
  184                                block_set_force_name) == 0) {
 
  185        CHKERR surfaceForce->addForce(
"SPATIAL_POSITION", PETSC_NULLPTR,
 
  186                                      (it->getMeshsetId()), 
true, 
true);
 
  187        CHKERR surfaceForce->addForceAle(
 
  188            "SPATIAL_POSITION", 
"MESH_NODE_POSITIONS", dataAtPts,
 
  189            si->
getDomainFEName(), PETSC_NULLPTR, PETSC_NULLPTR, it->getMeshsetId(),
 
  196    boost::shared_ptr<FaceElementForcesAndSourcesCore> fe_spring_lhs_ptr(
 
  198    boost::shared_ptr<FaceElementForcesAndSourcesCore> fe_spring_rhs_ptr(
 
  201        m_field, fe_spring_lhs_ptr, fe_spring_rhs_ptr, 
"SPATIAL_POSITION",
 
  202        "MESH_NODE_POSITIONS");
 
  204    boost::shared_ptr<FaceElementForcesAndSourcesCore> fe_spring_lhs_ale_ptr_dx(
 
  206    boost::shared_ptr<FaceElementForcesAndSourcesCore> fe_spring_lhs_ale_ptr_dX(
 
  209    boost::shared_ptr<FaceElementForcesAndSourcesCore> fe_spring_rhs_ale_ptr(
 
  212    boost::shared_ptr<MetaSpringBC::DataAtIntegrationPtsSprings>
 
  214            boost::make_shared<MetaSpringBC::DataAtIntegrationPtsSprings>(
 
  217    Range spring_ale_nodes;
 
  218    CHKERR moab.get_connectivity(triangle_springs, spring_ale_nodes, 
true);
 
  220    data_at_spring_gp->forcesOnlyOnEntitiesRow = spring_ale_nodes;
 
  223        m_field, fe_spring_lhs_ale_ptr_dx, fe_spring_lhs_ale_ptr_dX,
 
  224        fe_spring_rhs_ale_ptr, data_at_spring_gp, 
"SPATIAL_POSITION",
 
  233                                  PETSC_NULLPTR, PETSC_NULLPTR);
 
  235                                  PETSC_NULLPTR, PETSC_NULLPTR);
 
  237                                  PETSC_NULLPTR, PETSC_NULLPTR);
 
  251                                  fe_lhs_surface_force_ptr, 
nullptr, 
nullptr);
 
  253                                  fe_rhs_surface_force_ptr, 
nullptr, 
nullptr);
 
  256                                  fe_mat_lhs_surface_force_ptr, 
nullptr,
 
  259                                  fe_mat_rhs_surface_force_ptr, 
nullptr,
 
  263    CHKERR DMCreateGlobalVector(dm, &x);
 
  264    CHKERR VecDuplicate(x, &f);
 
  265    CHKERR VecSetOption(f, VEC_IGNORE_NEGATIVE_INDICES, PETSC_TRUE);
 
  270    CHKERR MatDuplicate(
A, MAT_DO_NOT_COPY_VALUES, &fdA);
 
  272    if (test_jacobian == PETSC_TRUE) {
 
  273      char testing_options[] =
 
  274          "-snes_test_jacobian -snes_test_jacobian_display " 
  275          "-snes_no_convergence_test -snes_atol 0 -snes_rtol 0 -snes_max_it 1 ";
 
  277      CHKERR PetscOptionsInsertString(NULL, testing_options);
 
  279      char testing_options[] = 
"-snes_no_convergence_test -snes_atol 0 " 
  283      CHKERR PetscOptionsInsertString(NULL, testing_options);
 
  287    CHKERR SNESCreate(PETSC_COMM_WORLD, &snes);
 
  292    CHKERR SNESSetFromOptions(snes);
 
  294    CHKERR SNESSolve(snes, NULL, x);
 
  296    if (test_jacobian == PETSC_FALSE) {
 
  298      CHKERR MatNorm(
A, NORM_INFINITY, &nrm_A0);
 
  300      char testing_options_fd[] = 
"-snes_fd";
 
  301      CHKERR PetscOptionsInsertString(NULL, testing_options_fd);
 
  305      CHKERR SNESSetFromOptions(snes);
 
  307      CHKERR SNESSolve(snes, NULL, x);
 
  308      CHKERR MatAXPY(
A, -1, fdA, SUBSET_NONZERO_PATTERN);
 
  311      CHKERR MatNorm(
A, NORM_INFINITY, &nrm_A);
 
  312      PetscPrintf(PETSC_COMM_WORLD, 
"Matrix norms %3.4e %3.4e\n", nrm_A,
 
  316      const double tol = 1e-7;
 
  319                "Difference between hand-calculated tangent matrix and finite " 
  320                "difference matrix is too big");
 
  328    CHKERR SNESDestroy(&snes);