#include "mfem.hpp" #include #include using namespace std; using namespace mfem; //setup intial condition int problem = 3; // Initial condition real_t my_function(const Vector &x); // Mesh bounding box Vector bb_min, bb_max; int main(int argc, char *argv[]) { Mpi::Init(); int num_procs = Mpi::WorldSize(); int myid = Mpi::WorldRank(); // 1. Parse command-line options. const char *mesh_file = "../data/periodic-hexagon.mesh"; int order = 2; bool pa = false; bool fa = false; const char *device_config = "cpu"; bool visualization = true; bool algebraic_ceed = false; OptionsParser args(argc, argv); args.AddOption(&mesh_file, "-m", "--mesh", "Mesh file to use."); args.AddOption(&order, "-o", "--order", "Finite element order (polynomial degree) or -1 for" " isoparametric space."); args.AddOption(&pa, "-pa", "--partial-assembly", "-no-pa", "--no-partial-assembly", "Enable Partial Assembly."); args.AddOption(&fa, "-fa", "--full-assembly", "-no-fa", "--no-full-assembly", "Enable Full Assembly."); args.AddOption(&device_config, "-d", "--device", "Device configuration string, see Device::Configure()."); args.AddOption(&visualization, "-vis", "--visualization", "-no-vis", "--no-visualization", "Enable or disable GLVis visualization."); args.Parse(); if (!args.Good()) { if (Mpi::Root()) { args.PrintUsage(cout); } return 1; } if (Mpi::Root()) { args.PrintOptions(cout); } // 2. Enable hardware devices such as GPUs, and programming models such as // CUDA, OCCA, RAJA and OpenMP based on command line options. Device device(device_config); if (Mpi::Root()) { device.Print(); } // 3. Read the mesh from the given mesh file. We can handle triangular, // quadrilateral, tetrahedral, hexahedral, surface and volume meshes with // the same code. Mesh mesh(mesh_file, 1, 1); int dim = mesh.Dimension(); // 4. Refine the mesh to increase the resolution. In this example we do // 'ref_levels' of uniform refinement. We choose 'ref_levels' to be the // largest number that gives a final mesh with no more than 50,000 // elements. { int ref_levels = 1; //(int)floor(log(50000./mesh.GetNE())/log(2.)/dim); for (int l = 0; l < ref_levels; l++) { mesh.UniformRefinement(); } } ParMesh pmesh(MPI_COMM_WORLD, mesh); pmesh.GetBoundingBox(bb_min, bb_max, max(order, 1)); const int elem_index = 0; mfem::Element *el = pmesh.GetElement(elem_index); mfem::Geometry::Type geom = el->GetGeometryType(); //Create finite element space DG_FECollection fec(order, pmesh.Dimension()); ParFiniteElementSpace *pfespace = new ParFiniteElementSpace(&pmesh, &fec); //specify integration rule int intorder = (2*order-1); //IntegrationRules irGL(geom, Quadrature1D::GaussLobatto); const IntegrationRule *ir = &IntRules.Get(geom, 2*order); //Create QuadratureSpace QuadratureSpace qspace(pmesh, *ir); QuadratureFunction quadfun(qspace); std::cout<<"quadfun.Size() = "<GetNPoints()<GetNPoints(); q++) { const IntegrationPoint &ip = ir->IntPoint(q); Vector phys_point(pmesh.Dimension()); trans->Transform(ip, phys_point); // Map to physical coordinates quadfun(qf_idx++) = my_function(phys_point); } } { int precision = 8; cout.precision(precision); ofstream omesh("main.mesh"); omesh.precision(precision); pmesh.Print(omesh); ofstream oquad("intial.qf"); oquad.precision(precision); quadfun.Save(oquad); } // //Create visit file // { VisItDataCollection *pd = NULL; pd = new VisItDataCollection("quad_fun", &pmesh); pd->SetPrefixPath("Visit"); pd->RegisterQField("quad_field", &quadfun); pd->SetLevelsOfDetail(order); //pd->SetDataFormat(VTKFormat::BINARY); //pd->SetHighOrderOutput(true); pd->SetCycle(0); pd->SetTime(0.0); pd->Save(); delete pd; } // 14. Send the solution by socket to a GLVis server. if (visualization && false) { char vishost[] = "localhost"; int visport = 19916; socketstream sol_sock(vishost, visport); sol_sock.precision(8); sol_sock << "solution\n" << pmesh << quadfun << flush; } // 15. Free the used memory. return 0; } // Initial condition real_t my_function(const Vector &x) { int dim = x.Size(); // map to the reference [-1,1] domain Vector X(dim); for (int i = 0; i < dim; i++) { real_t center = (bb_min[i] + bb_max[i]) * 0.5; X(i) = 2 * (x(i) - center) / (bb_max[i] - bb_min[i]); } switch (problem) { case 0: case 1: { switch (dim) { case 1: return exp(-40.*pow(X(0)-0.5,2)); case 2: case 3: { real_t rx = 0.45, ry = 0.25, cx = 0., cy = -0.2, w = 10.; if (dim == 3) { const real_t s = (1. + 0.25*cos(2*M_PI*X(2))); rx *= s; ry *= s; } return ( std::erfc(w*(X(0)-cx-rx))*std::erfc(-w*(X(0)-cx+rx)) * std::erfc(w*(X(1)-cy-ry))*std::erfc(-w*(X(1)-cy+ry)) )/16; } } } case 2: { real_t x_ = X(0), y_ = X(1), rho, phi; rho = std::hypot(x_, y_); phi = atan2(y_, x_); return pow(sin(M_PI*rho),2)*sin(3*phi); } case 3: { const real_t f = M_PI; return 2 * sin(f*X(0))*sin(f*X(1)); } } return 0.0; }