Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b442aaa349 | ||
|
|
cbc4632fb8 | ||
|
|
0186022c01 | ||
|
|
dd8f8f2124 | ||
|
|
6640970f50 | ||
|
|
f5ab281afa | ||
|
|
d665bbf5b7 | ||
|
|
31b838f103 | ||
|
|
046d01c30e | ||
|
|
c688a208d6 | ||
|
|
eafb5c8ba0 | ||
|
|
bb8345e76c |
@@ -0,0 +1,340 @@
|
||||
// Compile with: make drl_shock_wave
|
||||
//
|
||||
// drl_shock_wave -o 2 -m ../data/inline-quad.mesh
|
||||
// for multi agent local, set the mesh to use 20x20 grid because that is what
|
||||
// was used for training.
|
||||
|
||||
#include "mfem.hpp"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include "multi_agent_local_refiner.hpp"
|
||||
|
||||
#define MFEM_USE_RLLIB
|
||||
#ifdef MFEM_USE_RLLIB
|
||||
#include <Python.h>
|
||||
#include "numpy/arrayobject.h"
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
#define alpha 2.0/3.0
|
||||
|
||||
double exact_vel(const Vector &x)
|
||||
{
|
||||
double xv = x(0), yv = x(1);
|
||||
double rv = xv*xv + yv*yv;
|
||||
if (rv > 0) { rv = pow(rv, 0.5); };
|
||||
double theta = atan2(yv, xv);
|
||||
if (theta < 0.0) { theta += 2*M_PI; }
|
||||
return pow(rv, alpha)*sin(alpha*theta);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// 1. Parse command-line options.
|
||||
const char *mesh_file = "lshape.mesh";
|
||||
int order = 2;
|
||||
bool pa = false;
|
||||
const char *device_config = "cpu";
|
||||
bool visualization = true;
|
||||
int jobid = 0;
|
||||
double error_threshold = 0.10;
|
||||
double max_elem_error = 5.0e-3;
|
||||
int refinement_levels = 2;
|
||||
|
||||
|
||||
#ifdef MFEM_USE_RLLIB
|
||||
Py_Initialize();
|
||||
import_array(); // numpy init
|
||||
#endif
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&mesh_file, "-m", "--mesh",
|
||||
"Mesh file to use.");
|
||||
args.AddOption(&order, "-o", "--order",
|
||||
"Finite element order (polynomial degree).");
|
||||
args.AddOption(&pa, "-pa", "--partial-assembly", "-no-pa",
|
||||
"--no-partial-assembly", "Enable Partial 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.AddOption(&jobid, "-j", "--jobid",
|
||||
"slurb_jobid.");
|
||||
args.AddOption(&error_threshold, "-err", "--err",
|
||||
"Total error fraction for zz or max_elem_error for policy.");
|
||||
args.AddOption(&refinement_levels, "-r", "--ref",
|
||||
"Refinement levels");
|
||||
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
args.PrintUsage(cout);
|
||||
return 1;
|
||||
}
|
||||
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);
|
||||
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();
|
||||
int sdim = mesh.SpaceDimension();
|
||||
|
||||
mesh.SetCurvature(2);
|
||||
|
||||
// 4. Since a NURBS mesh can currently only be refined uniformly, we need to
|
||||
// convert it to a piecewise-polynomial curved mesh. First we refine the
|
||||
// NURBS mesh a bit more and then project the curvature to quadratic Nodes.
|
||||
if (mesh.NURBSext)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
mesh.UniformRefinement();
|
||||
}
|
||||
mesh.SetCurvature(2);
|
||||
}
|
||||
else {
|
||||
// mesh.UniformRefinement();
|
||||
//mesh.UniformRefinement();
|
||||
for (int i = 0; i < refinement_levels; i++)
|
||||
{
|
||||
mesh.UniformRefinement();
|
||||
}
|
||||
mesh.EnsureNCMesh();
|
||||
}
|
||||
|
||||
// 5. Define a finite element space on the mesh. The polynomial order is
|
||||
// one (linear) by default, but this can be changed on the command line.
|
||||
H1_FECollection fec(order, dim);
|
||||
FiniteElementSpace fespace(&mesh, &fec);
|
||||
|
||||
// Create 0-order L2 gridfunction to hold errors
|
||||
L2_FECollection fec0(0, dim);
|
||||
FiniteElementSpace fes0(&mesh, &fec0);
|
||||
GridFunction err(&fes0);
|
||||
|
||||
// 6. As in Example 1, we set up bilinear and linear forms corresponding to
|
||||
// the Laplace problem -\Delta u = 1. We don't assemble the discrete
|
||||
// problem yet, this will be done in the main loop.
|
||||
BilinearForm a(&fespace);
|
||||
if (pa)
|
||||
{
|
||||
a.SetAssemblyLevel(AssemblyLevel::PARTIAL);
|
||||
a.SetDiagonalPolicy(Operator::DIAG_ONE);
|
||||
}
|
||||
LinearForm b(&fespace);
|
||||
|
||||
ConstantCoefficient rhs(0.0);
|
||||
ConstantCoefficient one(1.0);
|
||||
FunctionCoefficient exact(exact_vel);
|
||||
|
||||
BilinearFormIntegrator *integ = new DiffusionIntegrator(one);
|
||||
a.AddDomainIntegrator(integ);
|
||||
int int_order = 8;
|
||||
int geom_type = mesh.GetElementBaseGeometry(0);
|
||||
DomainLFIntegrator* dlfi = new DomainLFIntegrator(rhs);
|
||||
dlfi->SetIntRule(&IntRules.Get(geom_type, int_order));
|
||||
b.AddDomainIntegrator(dlfi);
|
||||
|
||||
// 7. The solution vector x and the associated finite element grid function
|
||||
// will be maintained over the AMR iterations. We initialize it to zero.
|
||||
GridFunction x(&fespace);
|
||||
x = 0.0;
|
||||
|
||||
// 8. All boundary attributes will be used for essential (Dirichlet) BC.
|
||||
MFEM_VERIFY(mesh.bdr_attributes.Size() > 0,
|
||||
"Boundary attributes required in the mesh.");
|
||||
Array<int> ess_bdr(mesh.bdr_attributes.Max());
|
||||
ess_bdr = 1;
|
||||
|
||||
// 9. Connect to GLVis.
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
socketstream sol_sock;
|
||||
socketstream err_sock;
|
||||
if (visualization)
|
||||
{
|
||||
sol_sock.open(vishost, visport);
|
||||
err_sock.open(vishost, visport);
|
||||
}
|
||||
|
||||
// 10. Set up an error estimator. Here we use the Zienkiewicz-Zhu estimator
|
||||
// that uses the ComputeElementFlux method of the DiffusionIntegrator to
|
||||
// recover a smoothed flux (gradient) that is subtracted from the element
|
||||
// flux to get an error indicator. We need to supply the space for the
|
||||
// smoothed flux: an (H1)^sdim (i.e., vector-valued) space is used here.
|
||||
FiniteElementSpace flux_fespace(&mesh, &fec, sdim);
|
||||
ZienkiewiczZhuEstimator estimator(*integ, x, flux_fespace);
|
||||
//KellyErrorEstimator estimator2(*integ, x, flux_fespace);
|
||||
//estimator.SetAnisotropic();
|
||||
|
||||
// 11. A refiner selects and refines elements based on a refinement strategy.
|
||||
// The strategy here is to refine elements with errors larger than a
|
||||
// fraction of the maximum element error. Other strategies are possible.
|
||||
// The refiner will call the given error estimator.
|
||||
|
||||
bool zz = false;
|
||||
#if 0
|
||||
ThresholdRefiner refiner(estimator);
|
||||
refiner.SetTotalErrorFraction(error_threshold);
|
||||
zz = true;
|
||||
#else
|
||||
MAL_DRLRefiner refiner(x, error_threshold);
|
||||
#endif
|
||||
|
||||
bool derefine = false;
|
||||
ThresholdDerefiner derefiner(estimator);
|
||||
derefiner.SetThreshold(0.05);
|
||||
derefiner.SetNCLimit(0);
|
||||
|
||||
string errorfilename;
|
||||
errorfilename = to_string(jobid) + "_lshape_error.txt";
|
||||
ofstream myfile;
|
||||
myfile.open(errorfilename, ofstream::in | ofstream::out | ofstream::app);
|
||||
|
||||
|
||||
// 12. The main AMR loop. In each iteration we solve the problem on the
|
||||
// current mesh, visualize the solution, and refine the mesh.
|
||||
const int max_dofs = 200000;
|
||||
for (int it = 0; it < 6; it++)
|
||||
{
|
||||
int cdofs = fespace.GetTrueVSize();
|
||||
cout << "\nAMR iteration " << it << endl;
|
||||
cout << "Number of unknowns: " << cdofs << endl;
|
||||
|
||||
// 13. Assemble the right-hand side.
|
||||
b.Assemble();
|
||||
|
||||
// 14. Set Dirichlet boundary values in the GridFunction x.
|
||||
// Determine the list of Dirichlet true DOFs in the linear system.
|
||||
Array<int> ess_tdof_list;
|
||||
x.ProjectBdrCoefficient(exact, ess_bdr);
|
||||
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
|
||||
|
||||
// 15. Assemble the stiffness matrix.
|
||||
a.Assemble();
|
||||
|
||||
// 16. Create the linear system: eliminate boundary conditions, constrain
|
||||
// hanging nodes and possibly apply other transformations. The system
|
||||
// will be solved for true (unconstrained) DOFs only.
|
||||
OperatorPtr A;
|
||||
Vector B, X;
|
||||
|
||||
const int copy_interior = 1;
|
||||
a.FormLinearSystem(ess_tdof_list, x, b, A, X, B, copy_interior);
|
||||
|
||||
// 17. Solve the linear system A X = B.
|
||||
if (!pa)
|
||||
{
|
||||
#ifndef MFEM_USE_SUITESPARSE
|
||||
// Use a simple symmetric Gauss-Seidel preconditioner with PCG.
|
||||
GSSmoother M((SparseMatrix&)(*A));
|
||||
PCG(*A, M, B, X, 3, 200, 1e-12, 0.0);
|
||||
#else
|
||||
// If MFEM was compiled with SuiteSparse, use UMFPACK to solve the system.
|
||||
UMFPackSolver umf_solver;
|
||||
umf_solver.Control[UMFPACK_ORDERING] = UMFPACK_ORDERING_METIS;
|
||||
umf_solver.SetOperator(*A);
|
||||
umf_solver.Mult(B, X);
|
||||
#endif
|
||||
}
|
||||
else // Diagonal preconditioning in partial assembly mode.
|
||||
{
|
||||
OperatorJacobiSmoother M(a, ess_tdof_list);
|
||||
PCG(*A, M, B, X, 3, 2000, 1e-12, 0.0);
|
||||
}
|
||||
|
||||
// 18. After solving the linear system, reconstruct the solution as a
|
||||
// finite element GridFunction. Constrained nodes are interpolated
|
||||
// from true DOFs (it may therefore happen that x.Size() >= X.Size()).
|
||||
a.RecoverFEMSolution(X, b, x);
|
||||
|
||||
// Compute error against exact solution
|
||||
|
||||
x.ComputeElementL2Errors(exact, err);
|
||||
int int_order = std::max(20 - it, 2*order+1);
|
||||
double error;
|
||||
error = err.Norml2();
|
||||
|
||||
if (derefine) {
|
||||
myfile << error_threshold << " " << cdofs << " " << error << endl;
|
||||
}
|
||||
else {
|
||||
myfile << -error_threshold << " " << cdofs << " " << error << endl;
|
||||
}
|
||||
|
||||
// 19. Send solution by socket to the GLVis server.
|
||||
if (visualization && sol_sock.good())
|
||||
{
|
||||
sol_sock.precision(8);
|
||||
sol_sock << "solution\n" << mesh << x << flush;
|
||||
}
|
||||
if (visualization && err_sock.good())
|
||||
{
|
||||
err_sock.precision(8);
|
||||
err_sock << "solution\n" << mesh << err << flush;
|
||||
}
|
||||
|
||||
if (cdofs > max_dofs)
|
||||
{
|
||||
cout << "Reached the maximum number of dofs. Stop." << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
// 20. Call the refiner to modify the mesh. The refiner calls the error
|
||||
// estimator to obtain element errors, then it selects elements to be
|
||||
// refined and finally it modifies the mesh. The Stop() method can be
|
||||
// used to determine if a stopping criterion was met.
|
||||
|
||||
refiner.Apply(mesh);
|
||||
if (refiner.Stop())
|
||||
{
|
||||
cout << "Stopping criterion satisfied. Stop." << endl;
|
||||
break;
|
||||
}
|
||||
fespace.Update();fes0.Update();x.Update();err.Update();
|
||||
a.Update();b.Update();
|
||||
|
||||
if (derefine) {
|
||||
derefiner.Apply(mesh);
|
||||
fespace.Update();fes0.Update();x.Update();err.Update();
|
||||
a.Update();b.Update();
|
||||
}
|
||||
e
|
||||
{
|
||||
string solname = to_string(jobid) + "_lshape_amr" + to_string(it) + ".gf";
|
||||
ofstream sol_ofs(solname);
|
||||
x.Save(sol_ofs);
|
||||
}
|
||||
|
||||
{
|
||||
string meshname = to_string(jobid) + "_lshape_amr" + to_string(it) + ".mesh";
|
||||
ofstream mesh_ofs(meshname);
|
||||
mesh_ofs.precision(14);
|
||||
mesh.Print(mesh_ofs);
|
||||
}
|
||||
}
|
||||
myfile.close();
|
||||
|
||||
|
||||
{
|
||||
ofstream sol_ofs("lshape_amr.gf");
|
||||
x.Save(sol_ofs);
|
||||
}
|
||||
|
||||
{
|
||||
ofstream mesh_ofs("lshape_amr.mesh");
|
||||
mesh_ofs.precision(14);
|
||||
mesh.Print(mesh_ofs);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,330 @@
|
||||
// Compile with: make drl_shock_wave
|
||||
//
|
||||
// drl_shock_wave -o 2 -m ../data/inline-quad.mesh
|
||||
// for multi agent local, set the mesh to use 20x20 grid because that is what
|
||||
// was used for training.
|
||||
|
||||
#include "mfem.hpp"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include "drl_shock_wave.hpp"
|
||||
#include "multi_agent_local_refiner.hpp"
|
||||
|
||||
#define MFEM_USE_RLLIB
|
||||
#ifdef MFEM_USE_RLLIB
|
||||
#include <Python.h>
|
||||
#include "numpy/arrayobject.h"
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
double bdry_function(const Vector& x)
|
||||
{
|
||||
return 0.0; // default
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// 1. Parse command-line options.
|
||||
const char *mesh_file = "../data/inline-quad.mesh";
|
||||
int order = 2;
|
||||
bool pa = false;
|
||||
const char *device_config = "cpu";
|
||||
bool visualization = true;
|
||||
int jobid = 0;
|
||||
|
||||
#ifdef MFEM_USE_RLLIB
|
||||
Py_Initialize();
|
||||
import_array(); // numpy init
|
||||
#endif
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&mesh_file, "-m", "--mesh",
|
||||
"Mesh file to use.");
|
||||
args.AddOption(&order, "-o", "--order",
|
||||
"Finite element order (polynomial degree).");
|
||||
args.AddOption(&pa, "-pa", "--partial-assembly", "-no-pa",
|
||||
"--no-partial-assembly", "Enable Partial 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.AddOption(&jobid, "-j", "--jobid",
|
||||
"slurb_jobid.");
|
||||
args.Parse();
|
||||
if (!args.Good())
|
||||
{
|
||||
args.PrintUsage(cout);
|
||||
return 1;
|
||||
}
|
||||
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);
|
||||
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();
|
||||
int sdim = mesh.SpaceDimension();
|
||||
|
||||
mesh.SetCurvature(2);
|
||||
|
||||
// 4. Since a NURBS mesh can currently only be refined uniformly, we need to
|
||||
// convert it to a piecewise-polynomial curved mesh. First we refine the
|
||||
// NURBS mesh a bit more and then project the curvature to quadratic Nodes.
|
||||
if (mesh.NURBSext)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
mesh.UniformRefinement();
|
||||
}
|
||||
mesh.SetCurvature(2);
|
||||
}
|
||||
else {
|
||||
// mesh.UniformRefinement();
|
||||
//mesh.UniformRefinement();
|
||||
mesh.EnsureNCMesh();
|
||||
}
|
||||
|
||||
// 5. Define a finite element space on the mesh. The polynomial order is
|
||||
// one (linear) by default, but this can be changed on the command line.
|
||||
H1_FECollection fec(order, dim);
|
||||
FiniteElementSpace fespace(&mesh, &fec);
|
||||
|
||||
// Create 0-order L2 gridfunction to hold errors
|
||||
L2_FECollection fec0(0, dim);
|
||||
FiniteElementSpace fes0(&mesh, &fec0);
|
||||
GridFunction err(&fes0);
|
||||
|
||||
// 6. As in Example 1, we set up bilinear and linear forms corresponding to
|
||||
// the Laplace problem -\Delta u = 1. We don't assemble the discrete
|
||||
// problem yet, this will be done in the main loop.
|
||||
BilinearForm a(&fespace);
|
||||
if (pa)
|
||||
{
|
||||
a.SetAssemblyLevel(AssemblyLevel::PARTIAL);
|
||||
a.SetDiagonalPolicy(Operator::DIAG_ONE);
|
||||
}
|
||||
LinearForm b(&fespace);
|
||||
|
||||
FunctionCoefficient bdry(bdry_function);
|
||||
FunctionCoefficient rhs(layer2_laplace);
|
||||
FunctionCoefficient exact(layer2_exsol);
|
||||
ConstantCoefficient one(1.0);
|
||||
|
||||
BilinearFormIntegrator *integ = new DiffusionIntegrator(one);
|
||||
a.AddDomainIntegrator(integ);
|
||||
int int_order = 8;
|
||||
int geom_type = mesh.GetElementBaseGeometry(0);
|
||||
DomainLFIntegrator* dlfi = new DomainLFIntegrator(rhs);
|
||||
dlfi->SetIntRule(&IntRules.Get(geom_type, int_order));
|
||||
b.AddDomainIntegrator(dlfi);
|
||||
|
||||
// 7. The solution vector x and the associated finite element grid function
|
||||
// will be maintained over the AMR iterations. We initialize it to zero.
|
||||
GridFunction x(&fespace);
|
||||
x = 0.0;
|
||||
|
||||
// 8. All boundary attributes will be used for essential (Dirichlet) BC.
|
||||
MFEM_VERIFY(mesh.bdr_attributes.Size() > 0,
|
||||
"Boundary attributes required in the mesh.");
|
||||
Array<int> ess_bdr(mesh.bdr_attributes.Max());
|
||||
ess_bdr = 1;
|
||||
|
||||
// 9. Connect to GLVis.
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
socketstream sol_sock;
|
||||
socketstream err_sock;
|
||||
if (visualization)
|
||||
{
|
||||
sol_sock.open(vishost, visport);
|
||||
err_sock.open(vishost, visport);
|
||||
}
|
||||
|
||||
// 10. Set up an error estimator. Here we use the Zienkiewicz-Zhu estimator
|
||||
// that uses the ComputeElementFlux method of the DiffusionIntegrator to
|
||||
// recover a smoothed flux (gradient) that is subtracted from the element
|
||||
// flux to get an error indicator. We need to supply the space for the
|
||||
// smoothed flux: an (H1)^sdim (i.e., vector-valued) space is used here.
|
||||
FiniteElementSpace flux_fespace(&mesh, &fec, sdim);
|
||||
ZienkiewiczZhuEstimator estimator(*integ, x, flux_fespace);
|
||||
//KellyErrorEstimator estimator2(*integ, x, flux_fespace);
|
||||
//estimator.SetAnisotropic();
|
||||
|
||||
// 11. A refiner selects and refines elements based on a refinement strategy.
|
||||
// The strategy here is to refine elements with errors larger than a
|
||||
// fraction of the maximum element error. Other strategies are possible.
|
||||
// The refiner will call the given error estimator.
|
||||
|
||||
#if 0
|
||||
ThresholdRefiner refiner(estimator);
|
||||
refiner.SetTotalErrorFraction(0.10);
|
||||
#else
|
||||
MAL_DRLRefiner refiner(x);
|
||||
//DRLRefiner refiner(x);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
x.ProjectCoefficient(exact);
|
||||
refiner.Apply(mesh);
|
||||
fespace.Update();
|
||||
fes0.Update();
|
||||
x.Update();
|
||||
x.ProjectCoefficient(exact);
|
||||
refiner.Apply(mesh);
|
||||
fespace.Update();
|
||||
fes0.Update();
|
||||
x.Update();
|
||||
{
|
||||
ofstream sol_ofs("sol.gf");
|
||||
x.Save(sol_ofs);
|
||||
}
|
||||
{
|
||||
ofstream mesh_ofs("amr.mesh");
|
||||
mesh_ofs.precision(14);
|
||||
mesh.Print(mesh_ofs);
|
||||
}
|
||||
MFEM_ABORT(" ");
|
||||
#endif
|
||||
|
||||
// 12. The main AMR loop. In each iteration we solve the problem on the
|
||||
// current mesh, visualize the solution, and refine the mesh.
|
||||
const int max_dofs = 20000;
|
||||
for (int it = 0; it < 4; it++)
|
||||
{
|
||||
int cdofs = fespace.GetTrueVSize();
|
||||
cout << "\nAMR iteration " << it << endl;
|
||||
cout << "Number of unknowns: " << cdofs << endl;
|
||||
|
||||
// 13. Assemble the right-hand side.
|
||||
b.Assemble();
|
||||
|
||||
// 14. Set Dirichlet boundary values in the GridFunction x.
|
||||
// Determine the list of Dirichlet true DOFs in the linear system.
|
||||
Array<int> ess_tdof_list;
|
||||
x.ProjectBdrCoefficient(exact, ess_bdr);
|
||||
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
|
||||
|
||||
// 15. Assemble the stiffness matrix.
|
||||
a.Assemble();
|
||||
|
||||
// 16. Create the linear system: eliminate boundary conditions, constrain
|
||||
// hanging nodes and possibly apply other transformations. The system
|
||||
// will be solved for true (unconstrained) DOFs only.
|
||||
OperatorPtr A;
|
||||
Vector B, X;
|
||||
|
||||
const int copy_interior = 1;
|
||||
a.FormLinearSystem(ess_tdof_list, x, b, A, X, B, copy_interior);
|
||||
|
||||
// 17. Solve the linear system A X = B.
|
||||
if (!pa)
|
||||
{
|
||||
#ifndef MFEM_USE_SUITESPARSE
|
||||
// Use a simple symmetric Gauss-Seidel preconditioner with PCG.
|
||||
GSSmoother M((SparseMatrix&)(*A));
|
||||
PCG(*A, M, B, X, 3, 200, 1e-12, 0.0);
|
||||
#else
|
||||
// If MFEM was compiled with SuiteSparse, use UMFPACK to solve the system.
|
||||
UMFPackSolver umf_solver;
|
||||
umf_solver.Control[UMFPACK_ORDERING] = UMFPACK_ORDERING_METIS;
|
||||
umf_solver.SetOperator(*A);
|
||||
umf_solver.Mult(B, X);
|
||||
#endif
|
||||
}
|
||||
else // Diagonal preconditioning in partial assembly mode.
|
||||
{
|
||||
OperatorJacobiSmoother M(a, ess_tdof_list);
|
||||
PCG(*A, M, B, X, 3, 2000, 1e-12, 0.0);
|
||||
}
|
||||
|
||||
// 18. After solving the linear system, reconstruct the solution as a
|
||||
// finite element GridFunction. Constrained nodes are interpolated
|
||||
// from true DOFs (it may therefore happen that x.Size() >= X.Size()).
|
||||
a.RecoverFEMSolution(X, b, x);
|
||||
|
||||
// Compute error against exact solution
|
||||
|
||||
x.ComputeElementL2Errors(exact, err);
|
||||
|
||||
// 19. Send solution by socket to the GLVis server.
|
||||
if (visualization && sol_sock.good())
|
||||
{
|
||||
sol_sock.precision(8);
|
||||
sol_sock << "solution\n" << mesh << x << flush;
|
||||
}
|
||||
if (visualization && err_sock.good())
|
||||
{
|
||||
err_sock.precision(8);
|
||||
err_sock << "solution\n" << mesh << err << flush;
|
||||
}
|
||||
|
||||
if (cdofs > max_dofs || it == 3)
|
||||
{
|
||||
cout << "Reached the maximum number of dofs. Stop." << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
// 20. Call the refiner to modify the mesh. The refiner calls the error
|
||||
// estimator to obtain element errors, then it selects elements to be
|
||||
// refined and finally it modifies the mesh. The Stop() method can be
|
||||
// used to determine if a stopping criterion was met.
|
||||
|
||||
refiner.Apply(mesh);
|
||||
if (refiner.Stop())
|
||||
{
|
||||
cout << "Stopping criterion satisfied. Stop." << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
// 21. Update the space to reflect the new state of the mesh. Also,
|
||||
// interpolate the solution x so that it lies in the new space but
|
||||
// represents the same function. This saves solver iterations later
|
||||
// since we'll have a good initial guess of x in the next step.
|
||||
// Internally, FiniteElementSpace::Update() calculates an
|
||||
// interpolation matrix which is then used by GridFunction::Update().
|
||||
fespace.Update();
|
||||
fes0.Update();
|
||||
x.Update();
|
||||
err.Update();
|
||||
|
||||
{
|
||||
string solname = to_string(jobid) + "_amrsol" + to_string(it) + ".gf";
|
||||
ofstream sol_ofs(solname);
|
||||
x.Save(sol_ofs);
|
||||
}
|
||||
|
||||
{
|
||||
string meshname = to_string(jobid) + "_amr" + to_string(it) + ".mesh";
|
||||
ofstream mesh_ofs(meshname);
|
||||
mesh_ofs.precision(14);
|
||||
mesh.Print(mesh_ofs);
|
||||
}
|
||||
|
||||
// 22. Inform also the bilinear and linear forms that the space has
|
||||
// changed.
|
||||
a.Update();
|
||||
b.Update();
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
ofstream sol_ofs("amrsol.gf");
|
||||
x.Save(sol_ofs);
|
||||
}
|
||||
|
||||
{
|
||||
ofstream mesh_ofs("amr.mesh");
|
||||
mesh_ofs.precision(14);
|
||||
mesh.Print(mesh_ofs);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
#include "mfem.hpp"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
using namespace mfem;
|
||||
using namespace std;
|
||||
|
||||
const double alpha = 200.0; // standard params
|
||||
const double center = -0.05;
|
||||
const double radius = 0.7;
|
||||
template<typename T> T sqr(T x) { return x*x; }
|
||||
double layer2_exsol(Vector &p)
|
||||
{
|
||||
double x = p(0), y = p(1);
|
||||
double r = sqrt(sqr(x - center) + sqr(y - center));
|
||||
return atan(alpha * (r - radius));
|
||||
}
|
||||
|
||||
void layer2_exgrad(const Vector &p, Vector &grad)
|
||||
{
|
||||
double x = p(0), y = p(1);
|
||||
double r = sqrt(sqr(x - center) + sqr(y - center));
|
||||
double u = r * (sqr(alpha) * sqr(r - radius) + 1);
|
||||
grad(0) = alpha * (x - center) / u;
|
||||
grad(1) = alpha * (y - center) / u;
|
||||
}
|
||||
|
||||
double layer2_laplace(Vector &p)
|
||||
{
|
||||
double x = p(0), y = p(1);
|
||||
double r = sqr(y - center) + sqr(x - center);
|
||||
double u = sqr(alpha) * sqr(sqrt(r) - radius) + 1;
|
||||
|
||||
return 2 * pow(alpha,3) * (sqrt(r) - radius) * sqr(y - center) / (r * sqr(u))
|
||||
+ alpha * sqr(y - center) / (pow(r, 1.5) * u)
|
||||
- 2 * alpha / (sqrt(r) * u)
|
||||
+ 2 * pow(alpha,3) * (sqrt(r) - radius) * sqr(x - center) / (r * sqr(u))
|
||||
+ alpha * sqr(x - center) / (pow(r, 1.5) * u);
|
||||
}
|
||||
|
||||
static double safeSqrt(double x)
|
||||
{
|
||||
if (x < 0.0)
|
||||
return -sqrt(-x);
|
||||
else
|
||||
return sqrt(x);
|
||||
}
|
||||
|
||||
double CalculateH10Error(GridFunction *sol, VectorCoefficient *exgrad,
|
||||
Array<double> *elemError, Array<int> *elemRef,
|
||||
int intOrder)
|
||||
{
|
||||
const FiniteElementSpace *fes = sol->FESpace();
|
||||
Mesh* mesh = fes->GetMesh();
|
||||
|
||||
Vector e_grad, a_grad, el_dofs, q_grad;
|
||||
DenseMatrix dshape, dshapet, Jinv;
|
||||
Array<int> vdofs;
|
||||
const FiniteElement *fe;
|
||||
ElementTransformation *transf;
|
||||
|
||||
int dim = mesh->Dimension();
|
||||
e_grad.SetSize(dim);
|
||||
a_grad.SetSize(dim);
|
||||
q_grad.SetSize(dim);
|
||||
Jinv.SetSize(dim);
|
||||
|
||||
double error = 0.0;
|
||||
if (elemError) elemError->SetSize(mesh->GetNE());
|
||||
if (elemRef) elemRef->SetSize(mesh->GetNE());
|
||||
|
||||
for (int i = 0; i < mesh->GetNE(); i++)
|
||||
{
|
||||
fe = fes->GetFE(i);
|
||||
int fdof = fe->GetDof();
|
||||
transf = mesh->GetElementTransformation(i);
|
||||
el_dofs.SetSize(fdof);
|
||||
dshape.SetSize(fdof, dim);
|
||||
dshapet.SetSize(fdof, dim);
|
||||
|
||||
fes->GetElementVDofs(i, vdofs);
|
||||
for (int k = 0; k < fdof; k++)
|
||||
if (vdofs[k] >= 0)
|
||||
el_dofs(k) = (*sol)(vdofs[k]);
|
||||
else
|
||||
el_dofs(k) = -(*sol)(-1-vdofs[k]);
|
||||
|
||||
const IntegrationRule &ir = IntRules.Get(fe->GetGeomType(), intOrder);
|
||||
|
||||
double el_err = 0.0, a_dxyz[3] = { 0, 0, 0 };
|
||||
for (int j = 0; j < ir.GetNPoints(); j++)
|
||||
{
|
||||
const IntegrationPoint &ip = ir.IntPoint(j);
|
||||
|
||||
transf->SetIntPoint(&ip);
|
||||
CalcInverse(transf->Jacobian(), Jinv);
|
||||
double w = ip.weight * transf->Weight();
|
||||
|
||||
exgrad->Eval(e_grad, *transf, ip);
|
||||
|
||||
fe->CalcDShape(ip, dshape);
|
||||
Mult(dshape, Jinv, dshapet);
|
||||
dshapet.MultTranspose(el_dofs, a_grad);
|
||||
|
||||
e_grad -= a_grad;
|
||||
el_err += w * (e_grad * e_grad);
|
||||
|
||||
transf->Jacobian().MultTranspose(e_grad, q_grad);
|
||||
for (int k = 0; k < dim; k++)
|
||||
{
|
||||
a_dxyz[k] += w * (q_grad[k] * q_grad[k]);
|
||||
}
|
||||
}
|
||||
|
||||
error += el_err;
|
||||
if (elemError)
|
||||
(*elemError)[i] = sqrt(fabs(el_err));
|
||||
|
||||
if (elemRef)
|
||||
{
|
||||
double sum = 0;
|
||||
for (int k = 0; k < dim; k++)
|
||||
sum += a_dxyz[k];
|
||||
|
||||
const double thresh = 0.2 * 3/dim;
|
||||
int ref = 0;
|
||||
for (int k = 0; k < dim; k++)
|
||||
if (a_dxyz[k] / sum > thresh)
|
||||
ref |= (1 << k);
|
||||
|
||||
(*elemRef)[i] = ref;
|
||||
}
|
||||
}
|
||||
|
||||
return safeSqrt(error);
|
||||
}
|
||||
+177
-7
@@ -43,21 +43,159 @@
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#define MFEM_USE_RLLIB
|
||||
#ifdef MFEM_USE_RLLIB
|
||||
#include <Python.h>
|
||||
#include "numpy/arrayobject.h"
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
using namespace mfem;
|
||||
|
||||
int problem; // problem number, controls source term and bdry condition
|
||||
|
||||
// Returns either rhs function f, or exact solution u.
|
||||
|
||||
double rhs_function(const Vector &x, bool exact = false)
|
||||
{
|
||||
int dim = x.Size();
|
||||
|
||||
if (0 == problem) {
|
||||
|
||||
// NIST: "Peak 2D" problem
|
||||
// u = e^(-alpha*(x^2+y^2)), alpha = 1e3 or alpha = 1e5
|
||||
|
||||
double xc = 0.5;
|
||||
double yc = 0.5;
|
||||
|
||||
double x0 = x(0)-xc;
|
||||
double y0 = x(1)-yc;
|
||||
|
||||
double alpha = 1000;
|
||||
|
||||
double xx = x0*x0;
|
||||
double yy = y0*y0;
|
||||
|
||||
if (exact) {
|
||||
|
||||
double u = exp(-alpha*(xx+yy));
|
||||
|
||||
return u;
|
||||
}
|
||||
else {
|
||||
|
||||
double f =
|
||||
alpha*(4.*alpha*xx -2.0)*exp(-alpha*(xx+yy)) +
|
||||
alpha*(4.*alpha*yy -2.0)*exp(-alpha*(xx+yy));
|
||||
|
||||
return -f;
|
||||
}
|
||||
}
|
||||
if (1 == problem) {
|
||||
|
||||
// NIST "arctan circular wavefront" problem, w/ minor
|
||||
// modifications.
|
||||
|
||||
double r0 = 0.25;
|
||||
double a = 100.0;
|
||||
double h = 1./3.;
|
||||
double c = 0.5;
|
||||
|
||||
double x0 = 0.5;
|
||||
double y0 = 0.5;
|
||||
|
||||
double dx = x(0)-x0;
|
||||
double dy = x(1)-y0;
|
||||
double dxdx = dx*dx;
|
||||
double dydy = dy*dy;
|
||||
double r = sqrt(dxdx+dydy);
|
||||
|
||||
if (exact) {
|
||||
double u = c +h*atan(a*(r-r0));
|
||||
return u;
|
||||
}
|
||||
else {
|
||||
double aa = a*a;
|
||||
double dr = r-r0;
|
||||
double drdr = dr*dr;
|
||||
double rr = r*r;
|
||||
double t = 1+aa*drdr;
|
||||
double tt = t*t;
|
||||
|
||||
double fx =
|
||||
a/(t*r) -
|
||||
a*dxdx/(t*rr*r) -
|
||||
2*aa*a*dxdx*dr/(tt*rr);
|
||||
|
||||
double fy =
|
||||
a/(t*r) -
|
||||
a*dydy/(t*rr*r) -
|
||||
2*aa*a*dydy*dr/(tt*rr);
|
||||
|
||||
return -h*(fx+fy);
|
||||
}
|
||||
}
|
||||
if (2 == problem) {
|
||||
|
||||
// cross-shaped source
|
||||
|
||||
double x0 = x(0)-0.5;
|
||||
double y0 = x(1)-0.5;
|
||||
|
||||
double w1 = 0.04;
|
||||
double w2 = 0.20;
|
||||
|
||||
if (x(0) > 0.5-w1 && x(0) < 0.5+w1 &&
|
||||
x(1) > 0.5-w2 && x(1) < 0.5+w2 ) {
|
||||
return 100.0;
|
||||
}
|
||||
if (x(1) > 0.5-w1 && x(1) < 0.5+w1 &&
|
||||
x(0) > 0.5-w2 && x(0) < 0.5+w2 ) {
|
||||
return 100.0;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return 1.0; // default
|
||||
}
|
||||
|
||||
double exact_soln(const Vector& x)
|
||||
{
|
||||
return rhs_function(x, true);
|
||||
}
|
||||
|
||||
double bdry_function(const Vector& x)
|
||||
{
|
||||
if (problem == 0) {
|
||||
return 0.0;
|
||||
}
|
||||
if (problem == 1) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
return 0.0; // default
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// 1. Parse command-line options.
|
||||
problem = 0;
|
||||
const char *mesh_file = "../data/star.mesh";
|
||||
int order = 1;
|
||||
bool pa = false;
|
||||
const char *device_config = "cpu";
|
||||
bool visualization = true;
|
||||
|
||||
#ifdef MFEM_USE_RLLIB
|
||||
Py_Initialize();
|
||||
import_array(); // numpy init
|
||||
#endif
|
||||
|
||||
OptionsParser args(argc, argv);
|
||||
args.AddOption(&mesh_file, "-m", "--mesh",
|
||||
"Mesh file to use.");
|
||||
args.AddOption(&problem, "-p", "--problem",
|
||||
"Problem setup to use. See options in rhs_function().");
|
||||
args.AddOption(&order, "-o", "--order",
|
||||
"Finite element order (polynomial degree).");
|
||||
args.AddOption(&pa, "-pa", "--partial-assembly", "-no-pa",
|
||||
@@ -98,12 +236,22 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
mesh.SetCurvature(2);
|
||||
}
|
||||
else {
|
||||
// mesh.UniformRefinement();
|
||||
//mesh.UniformRefinement();
|
||||
mesh.EnsureNCMesh();
|
||||
}
|
||||
|
||||
// 5. Define a finite element space on the mesh. The polynomial order is
|
||||
// one (linear) by default, but this can be changed on the command line.
|
||||
H1_FECollection fec(order, dim);
|
||||
FiniteElementSpace fespace(&mesh, &fec);
|
||||
|
||||
// Create 0-order L2 gridfunction to hold errors
|
||||
L2_FECollection fec0(0, dim);
|
||||
FiniteElementSpace fes0(&mesh, &fec0);
|
||||
GridFunction err(&fes0);
|
||||
|
||||
// 6. As in Example 1, we set up bilinear and linear forms corresponding to
|
||||
// the Laplace problem -\Delta u = 1. We don't assemble the discrete
|
||||
// problem yet, this will be done in the main loop.
|
||||
@@ -115,12 +263,14 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
LinearForm b(&fespace);
|
||||
|
||||
FunctionCoefficient rhs(rhs_function);
|
||||
FunctionCoefficient exact(exact_soln);
|
||||
FunctionCoefficient bdry(bdry_function);
|
||||
ConstantCoefficient one(1.0);
|
||||
ConstantCoefficient zero(0.0);
|
||||
|
||||
BilinearFormIntegrator *integ = new DiffusionIntegrator(one);
|
||||
a.AddDomainIntegrator(integ);
|
||||
b.AddDomainIntegrator(new DomainLFIntegrator(one));
|
||||
b.AddDomainIntegrator(new DomainLFIntegrator(rhs));
|
||||
|
||||
// 7. The solution vector x and the associated finite element grid function
|
||||
// will be maintained over the AMR iterations. We initialize it to zero.
|
||||
@@ -137,9 +287,11 @@ int main(int argc, char *argv[])
|
||||
char vishost[] = "localhost";
|
||||
int visport = 19916;
|
||||
socketstream sol_sock;
|
||||
socketstream err_sock;
|
||||
if (visualization)
|
||||
{
|
||||
sol_sock.open(vishost, visport);
|
||||
err_sock.open(vishost, visport);
|
||||
}
|
||||
|
||||
// 10. Set up an error estimator. Here we use the Zienkiewicz-Zhu estimator
|
||||
@@ -149,18 +301,24 @@ int main(int argc, char *argv[])
|
||||
// smoothed flux: an (H1)^sdim (i.e., vector-valued) space is used here.
|
||||
FiniteElementSpace flux_fespace(&mesh, &fec, sdim);
|
||||
ZienkiewiczZhuEstimator estimator(*integ, x, flux_fespace);
|
||||
estimator.SetAnisotropic();
|
||||
//KellyErrorEstimator estimator2(*integ, x, flux_fespace);
|
||||
//estimator.SetAnisotropic();
|
||||
|
||||
// 11. A refiner selects and refines elements based on a refinement strategy.
|
||||
// The strategy here is to refine elements with errors larger than a
|
||||
// fraction of the maximum element error. Other strategies are possible.
|
||||
// The refiner will call the given error estimator.
|
||||
|
||||
#if 1
|
||||
ThresholdRefiner refiner(estimator);
|
||||
refiner.SetTotalErrorFraction(0.7);
|
||||
refiner.SetTotalErrorFraction(0.10);
|
||||
#else
|
||||
DRLRefiner refiner(x);
|
||||
#endif
|
||||
|
||||
// 12. The main AMR loop. In each iteration we solve the problem on the
|
||||
// current mesh, visualize the solution, and refine the mesh.
|
||||
const int max_dofs = 50000;
|
||||
const int max_dofs = 1000;
|
||||
for (int it = 0; ; it++)
|
||||
{
|
||||
int cdofs = fespace.GetTrueVSize();
|
||||
@@ -173,7 +331,7 @@ int main(int argc, char *argv[])
|
||||
// 14. Set Dirichlet boundary values in the GridFunction x.
|
||||
// Determine the list of Dirichlet true DOFs in the linear system.
|
||||
Array<int> ess_tdof_list;
|
||||
x.ProjectBdrCoefficient(zero, ess_bdr);
|
||||
x.ProjectBdrCoefficient(bdry, ess_bdr);
|
||||
fespace.GetEssentialTrueDofs(ess_bdr, ess_tdof_list);
|
||||
|
||||
// 15. Assemble the stiffness matrix.
|
||||
@@ -214,14 +372,23 @@ int main(int argc, char *argv[])
|
||||
// from true DOFs (it may therefore happen that x.Size() >= X.Size()).
|
||||
a.RecoverFEMSolution(X, b, x);
|
||||
|
||||
// Compute error against exact solution
|
||||
|
||||
x.ComputeElementL2Errors(exact, err);
|
||||
|
||||
// 19. Send solution by socket to the GLVis server.
|
||||
if (visualization && sol_sock.good())
|
||||
{
|
||||
sol_sock.precision(8);
|
||||
sol_sock << "solution\n" << mesh << x << flush;
|
||||
}
|
||||
if (visualization && err_sock.good())
|
||||
{
|
||||
err_sock.precision(8);
|
||||
err_sock << "solution\n" << mesh << err << flush;
|
||||
}
|
||||
|
||||
if (cdofs > max_dofs)
|
||||
if (cdofs > max_dofs || it == 3)
|
||||
{
|
||||
cout << "Reached the maximum number of dofs. Stop." << endl;
|
||||
break;
|
||||
@@ -231,6 +398,7 @@ int main(int argc, char *argv[])
|
||||
// estimator to obtain element errors, then it selects elements to be
|
||||
// refined and finally it modifies the mesh. The Stop() method can be
|
||||
// used to determine if a stopping criterion was met.
|
||||
|
||||
refiner.Apply(mesh);
|
||||
if (refiner.Stop())
|
||||
{
|
||||
@@ -245,7 +413,9 @@ int main(int argc, char *argv[])
|
||||
// Internally, FiniteElementSpace::Update() calculates an
|
||||
// interpolation matrix which is then used by GridFunction::Update().
|
||||
fespace.Update();
|
||||
fes0.Update();
|
||||
x.Update();
|
||||
err.Update();
|
||||
|
||||
// 22. Inform also the bilinear and linear forms that the space has
|
||||
// changed.
|
||||
|
||||
@@ -0,0 +1,640 @@
|
||||
MFEM mesh v1.1
|
||||
|
||||
#
|
||||
# MFEM Geometry Types (see mesh/geom.hpp):
|
||||
#
|
||||
# POINT = 0
|
||||
# SEGMENT = 1
|
||||
# TRIANGLE = 2
|
||||
# SQUARE = 3
|
||||
# TETRAHEDRON = 4
|
||||
# CUBE = 5
|
||||
# PRISM = 6
|
||||
#
|
||||
|
||||
dimension
|
||||
2
|
||||
|
||||
elements
|
||||
84
|
||||
1 3 0 21 53 24
|
||||
1 3 21 8 22 53
|
||||
1 3 53 22 18 23
|
||||
1 3 24 53 23 11
|
||||
1 3 8 25 54 22
|
||||
1 3 25 1 26 54
|
||||
1 3 54 26 9 27
|
||||
1 3 22 54 27 18
|
||||
1 3 18 65 92 68
|
||||
1 3 68 92 67 30
|
||||
1 3 92 66 55 67
|
||||
1 3 65 27 66 92
|
||||
1 3 27 9 28 55
|
||||
1 3 55 69 93 72
|
||||
1 3 69 28 70 93
|
||||
1 3 93 70 4 71
|
||||
1 3 72 93 71 29
|
||||
1 3 95 72 29 73
|
||||
1 3 74 95 73 10
|
||||
1 3 30 67 95 74
|
||||
1 3 67 55 72 95
|
||||
1 3 11 23 56 32
|
||||
1 3 23 18 30 56
|
||||
1 3 56 30 10 31
|
||||
1 3 32 56 31 3
|
||||
1 3 3 31 57 35
|
||||
1 3 31 10 33 57
|
||||
1 3 57 33 19 34
|
||||
1 3 35 57 34 14
|
||||
1 3 10 73 96 75
|
||||
1 3 75 96 77 33
|
||||
1 3 96 76 58 77
|
||||
1 3 73 29 76 96
|
||||
1 3 29 71 97 76
|
||||
1 3 71 94 108 98
|
||||
1 3 94 110 114 109
|
||||
1 3 110 4 111 114
|
||||
1 3 114 111 99 112
|
||||
1 3 109 114 112 108
|
||||
1 3 108 99 78 100
|
||||
1 3 98 108 100 97
|
||||
1 3 97 78 36 79
|
||||
1 3 76 97 79 58
|
||||
1 3 58 79 101 82
|
||||
1 3 79 36 80 101
|
||||
1 3 101 80 12 81
|
||||
1 3 82 101 81 37
|
||||
1 3 33 58 37 19
|
||||
1 3 19 37 59 40
|
||||
1 3 37 12 38 59
|
||||
1 3 59 38 7 39
|
||||
1 3 40 59 39 13
|
||||
1 3 14 34 60 42
|
||||
1 3 34 19 40 60
|
||||
1 3 60 40 13 41
|
||||
1 3 42 60 41 6
|
||||
1 3 4 103 113 99
|
||||
1 3 103 83 104 113
|
||||
1 3 113 104 102 105
|
||||
1 3 99 113 105 78
|
||||
1 3 78 102 85 36
|
||||
1 3 102 84 61 85
|
||||
1 3 83 43 84 102
|
||||
1 3 43 86 106 84
|
||||
1 3 86 15 87 106
|
||||
1 3 106 87 44 88
|
||||
1 3 84 106 88 61
|
||||
1 3 61 44 20 45
|
||||
1 3 36 61 45 12
|
||||
1 3 15 89 107 87
|
||||
1 3 87 107 91 44
|
||||
1 3 107 90 62 91
|
||||
1 3 89 46 90 107
|
||||
1 3 46 5 47 62
|
||||
1 3 62 47 16 48
|
||||
1 3 44 62 48 20
|
||||
1 3 20 48 63 51
|
||||
1 3 48 16 49 63
|
||||
1 3 63 49 2 50
|
||||
1 3 51 63 50 17
|
||||
1 3 12 45 64 38
|
||||
1 3 45 20 51 64
|
||||
1 3 64 51 17 52
|
||||
1 3 38 64 52 7
|
||||
|
||||
boundary
|
||||
37
|
||||
1 1 0 21
|
||||
1 1 24 0
|
||||
1 1 21 8
|
||||
1 1 11 24
|
||||
1 1 8 25
|
||||
1 1 25 1
|
||||
1 1 1 26
|
||||
1 1 26 9
|
||||
1 1 9 28
|
||||
1 1 28 70
|
||||
1 1 70 4
|
||||
1 1 32 11
|
||||
1 1 3 32
|
||||
1 1 35 3
|
||||
1 1 14 35
|
||||
1 1 7 39
|
||||
1 1 39 13
|
||||
1 1 42 14
|
||||
1 1 13 41
|
||||
1 1 41 6
|
||||
1 1 6 42
|
||||
1 1 4 103
|
||||
1 1 103 83
|
||||
1 1 83 43
|
||||
1 1 43 86
|
||||
1 1 86 15
|
||||
1 1 15 89
|
||||
1 1 89 46
|
||||
1 1 46 5
|
||||
1 1 5 47
|
||||
1 1 47 16
|
||||
1 1 16 49
|
||||
1 1 49 2
|
||||
1 1 2 50
|
||||
1 1 50 17
|
||||
1 1 17 52
|
||||
1 1 52 7
|
||||
|
||||
vertex_parents
|
||||
50
|
||||
65 18 27
|
||||
66 27 55
|
||||
67 30 55
|
||||
68 18 30
|
||||
69 28 55
|
||||
70 4 28
|
||||
71 4 29
|
||||
72 29 55
|
||||
73 10 29
|
||||
74 10 30
|
||||
75 10 33
|
||||
76 29 58
|
||||
77 33 58
|
||||
78 4 36
|
||||
79 36 58
|
||||
80 12 36
|
||||
81 12 37
|
||||
82 37 58
|
||||
83 4 43
|
||||
84 43 61
|
||||
85 36 61
|
||||
86 15 43
|
||||
87 15 44
|
||||
88 44 61
|
||||
89 15 46
|
||||
90 46 62
|
||||
91 44 62
|
||||
92 65 67
|
||||
93 69 71
|
||||
94 4 71
|
||||
95 67 73
|
||||
96 73 77
|
||||
97 71 79
|
||||
98 71 97
|
||||
99 4 78
|
||||
100 78 97
|
||||
101 79 81
|
||||
102 83 85
|
||||
103 4 83
|
||||
104 83 102
|
||||
105 78 102
|
||||
106 86 88
|
||||
107 89 91
|
||||
108 94 100
|
||||
109 94 108
|
||||
110 4 94
|
||||
111 4 99
|
||||
112 99 108
|
||||
113 103 105
|
||||
114 110 112
|
||||
|
||||
coarse_elements
|
||||
12
|
||||
3 8 11 10 9
|
||||
3 13 14 15 16
|
||||
3 19 20 17 18
|
||||
3 29 32 31 30
|
||||
3 35 36 37 38
|
||||
3 34 88 39 40
|
||||
3 33 89 41 42
|
||||
3 43 44 45 46
|
||||
3 56 57 58 59
|
||||
3 92 62 61 60
|
||||
3 63 64 65 66
|
||||
3 69 72 71 70
|
||||
|
||||
vertices
|
||||
115
|
||||
|
||||
nodes
|
||||
FiniteElementSpace
|
||||
FiniteElementCollection: H1_2D_P2
|
||||
VDim: 2
|
||||
Ordering: 1
|
||||
|
||||
-1 -1
|
||||
0 -1
|
||||
1 1
|
||||
-1 0
|
||||
0 0
|
||||
1 0
|
||||
-1 1
|
||||
0 1
|
||||
-0.5 -1
|
||||
0 -0.5
|
||||
-0.5 0
|
||||
-1 -0.5
|
||||
0 0.5
|
||||
-0.5 1
|
||||
-1 0.5
|
||||
0.5 0
|
||||
1 0.5
|
||||
0.5 1
|
||||
-0.5 -0.5
|
||||
-0.5 0.5
|
||||
0.5 0.5
|
||||
-0.75 -1
|
||||
-0.5 -0.75
|
||||
-0.75 -0.5
|
||||
-1 -0.75
|
||||
-0.25 -1
|
||||
0 -0.75
|
||||
-0.25 -0.5
|
||||
0 -0.25
|
||||
-0.25 0
|
||||
-0.5 -0.25
|
||||
-0.75 0
|
||||
-1 -0.25
|
||||
-0.5 0.25
|
||||
-0.75 0.5
|
||||
-1 0.25
|
||||
0 0.25
|
||||
-0.25 0.5
|
||||
0 0.75
|
||||
-0.25 1
|
||||
-0.5 0.75
|
||||
-0.75 1
|
||||
-1 0.75
|
||||
0.25 0
|
||||
0.5 0.25
|
||||
0.25 0.5
|
||||
0.75 0
|
||||
1 0.25
|
||||
0.75 0.5
|
||||
1 0.75
|
||||
0.75 1
|
||||
0.5 0.75
|
||||
0.25 1
|
||||
-0.75 -0.75
|
||||
-0.25 -0.75
|
||||
-0.25 -0.25
|
||||
-0.75 -0.25
|
||||
-0.75 0.25
|
||||
-0.25 0.25
|
||||
-0.25 0.75
|
||||
-0.75 0.75
|
||||
0.25 0.25
|
||||
0.75 0.25
|
||||
0.75 0.75
|
||||
0.25 0.75
|
||||
-0.375 -0.5
|
||||
-0.25 -0.375
|
||||
-0.375 -0.25
|
||||
-0.5 -0.375
|
||||
-0.125 -0.25
|
||||
0 -0.125
|
||||
-0.125 0
|
||||
-0.25 -0.125
|
||||
-0.375 0
|
||||
-0.5 -0.125
|
||||
-0.5 0.125
|
||||
-0.25 0.125
|
||||
-0.375 0.25
|
||||
0 0.125
|
||||
-0.125 0.25
|
||||
0 0.375
|
||||
-0.125 0.5
|
||||
-0.25 0.375
|
||||
0.125 0
|
||||
0.25 0.125
|
||||
0.125 0.25
|
||||
0.375 0
|
||||
0.5 0.125
|
||||
0.375 0.25
|
||||
0.625 0
|
||||
0.75 0.125
|
||||
0.625 0.25
|
||||
-0.375 -0.375
|
||||
-0.125 -0.125
|
||||
-0.0625 0
|
||||
-0.375 -0.125
|
||||
-0.375 0.125
|
||||
-0.125 0.125
|
||||
-0.125 0.0625
|
||||
0 0.0625
|
||||
-0.0625 0.125
|
||||
-0.125 0.375
|
||||
0.125 0.125
|
||||
0.0625 0
|
||||
0.125 0.0625
|
||||
0.0625 0.125
|
||||
0.375 0.125
|
||||
0.625 0.125
|
||||
-0.0625 0.0625
|
||||
-0.0625 0.03125
|
||||
-0.03125 0
|
||||
0 0.03125
|
||||
-0.03125 0.0625
|
||||
0.0625 0.0625
|
||||
-0.03125 0.03125
|
||||
-0.875 -1
|
||||
-0.75 -0.875
|
||||
-0.875 -0.75
|
||||
-1 -0.875
|
||||
-0.625 -1
|
||||
-0.5 -0.875
|
||||
-0.625 -0.75
|
||||
-0.5 -0.625
|
||||
-0.625 -0.5
|
||||
-0.75 -0.625
|
||||
-0.875 -0.5
|
||||
-1 -0.625
|
||||
-0.375 -1
|
||||
-0.25 -0.875
|
||||
-0.375 -0.75
|
||||
-0.125 -1
|
||||
0 -0.875
|
||||
-0.125 -0.75
|
||||
0 -0.625
|
||||
-0.125 -0.5
|
||||
-0.25 -0.625
|
||||
-0.375 -0.5
|
||||
-0.4375 -0.5
|
||||
-0.375 -0.4375
|
||||
-0.4375 -0.375
|
||||
-0.5 -0.4375
|
||||
-0.375 -0.3125
|
||||
-0.4375 -0.25
|
||||
-0.5 -0.3125
|
||||
-0.3125 -0.375
|
||||
-0.25 -0.3125
|
||||
-0.3125 -0.25
|
||||
-0.3125 -0.5
|
||||
-0.25 -0.4375
|
||||
0 -0.375
|
||||
-0.125 -0.25
|
||||
-0.25 -0.375
|
||||
-0.1875 -0.25
|
||||
-0.125 -0.1875
|
||||
-0.1875 -0.125
|
||||
-0.25 -0.1875
|
||||
-0.0625 -0.25
|
||||
0 -0.1875
|
||||
-0.0625 -0.125
|
||||
0 -0.0625
|
||||
-0.0625 0
|
||||
-0.125 -0.0625
|
||||
-0.1875 0
|
||||
-0.25 -0.0625
|
||||
-0.3125 -0.125
|
||||
-0.3125 0
|
||||
-0.375 -0.0625
|
||||
-0.4375 -0.125
|
||||
-0.4375 0
|
||||
-0.5 -0.0625
|
||||
-0.375 -0.1875
|
||||
-0.5 -0.1875
|
||||
-0.75 -0.375
|
||||
-0.875 -0.25
|
||||
-1 -0.375
|
||||
-0.5 -0.375
|
||||
-0.625 -0.25
|
||||
-0.5 -0.125
|
||||
-0.625 0
|
||||
-0.75 -0.125
|
||||
-0.875 0
|
||||
-1 -0.125
|
||||
-0.75 0.125
|
||||
-0.875 0.25
|
||||
-1 0.125
|
||||
-0.5 0.125
|
||||
-0.625 0.25
|
||||
-0.5 0.375
|
||||
-0.625 0.5
|
||||
-0.75 0.375
|
||||
-0.875 0.5
|
||||
-1 0.375
|
||||
-0.375 0.0625
|
||||
-0.4375 0.125
|
||||
-0.5 0.0625
|
||||
-0.375 0.1875
|
||||
-0.4375 0.25
|
||||
-0.5 0.1875
|
||||
-0.3125 0.125
|
||||
-0.25 0.1875
|
||||
-0.3125 0.25
|
||||
-0.25 0.0625
|
||||
-0.125 0.0625
|
||||
-0.1875 0.125
|
||||
-0.09375 0
|
||||
-0.0625 0.03125
|
||||
-0.09375 0.0625
|
||||
-0.125 0.03125
|
||||
-0.046875 0
|
||||
-0.03125 0.015625
|
||||
-0.046875 0.03125
|
||||
-0.0625 0.015625
|
||||
-0.015625 0
|
||||
0 0.015625
|
||||
-0.015625 0.03125
|
||||
0 0.046875
|
||||
-0.015625 0.0625
|
||||
-0.03125 0.046875
|
||||
-0.046875 0.0625
|
||||
-0.0625 0.046875
|
||||
-0.03125 0.0625
|
||||
0 0.09375
|
||||
-0.03125 0.125
|
||||
-0.0625 0.09375
|
||||
-0.09375 0.125
|
||||
-0.125 0.09375
|
||||
-0.0625 0.125
|
||||
0 0.1875
|
||||
-0.0625 0.25
|
||||
-0.125 0.1875
|
||||
-0.1875 0.25
|
||||
-0.125 0.3125
|
||||
-0.1875 0.375
|
||||
-0.25 0.3125
|
||||
0 0.3125
|
||||
-0.0625 0.375
|
||||
0 0.4375
|
||||
-0.0625 0.5
|
||||
-0.125 0.4375
|
||||
-0.1875 0.5
|
||||
-0.25 0.4375
|
||||
-0.375 0.25
|
||||
-0.25 0.375
|
||||
-0.375 0.5
|
||||
-0.25 0.625
|
||||
-0.375 0.75
|
||||
-0.5 0.625
|
||||
-0.125 0.5
|
||||
0 0.625
|
||||
-0.125 0.75
|
||||
0 0.875
|
||||
-0.125 1
|
||||
-0.25 0.875
|
||||
-0.375 1
|
||||
-0.5 0.875
|
||||
-0.75 0.625
|
||||
-0.875 0.75
|
||||
-1 0.625
|
||||
-0.625 0.75
|
||||
-0.625 1
|
||||
-0.75 0.875
|
||||
-0.875 1
|
||||
-1 0.875
|
||||
0.03125 0
|
||||
0.0625 0.03125
|
||||
0.03125 0.0625
|
||||
0 0.03125
|
||||
0.09375 0
|
||||
0.125 0.03125
|
||||
0.09375 0.0625
|
||||
0.125 0.09375
|
||||
0.09375 0.125
|
||||
0.0625 0.09375
|
||||
0.03125 0.125
|
||||
0.0625 0.125
|
||||
0.125 0.1875
|
||||
0.0625 0.25
|
||||
0.1875 0.125
|
||||
0.25 0.1875
|
||||
0.1875 0.25
|
||||
0.1875 0
|
||||
0.25 0.0625
|
||||
0.125 0.0625
|
||||
0.3125 0
|
||||
0.375 0.0625
|
||||
0.3125 0.125
|
||||
0.4375 0
|
||||
0.5 0.0625
|
||||
0.4375 0.125
|
||||
0.5 0.1875
|
||||
0.4375 0.25
|
||||
0.375 0.1875
|
||||
0.3125 0.25
|
||||
0.375 0.25
|
||||
0.5 0.375
|
||||
0.375 0.5
|
||||
0.25 0.375
|
||||
0.125 0.25
|
||||
0.125 0.5
|
||||
0 0.375
|
||||
0.5625 0
|
||||
0.625 0.0625
|
||||
0.5625 0.125
|
||||
0.625 0.1875
|
||||
0.5625 0.25
|
||||
0.6875 0.125
|
||||
0.75 0.1875
|
||||
0.6875 0.25
|
||||
0.6875 0
|
||||
0.75 0.0625
|
||||
0.875 0
|
||||
1 0.125
|
||||
0.875 0.25
|
||||
0.75 0.125
|
||||
1 0.375
|
||||
0.875 0.5
|
||||
0.75 0.375
|
||||
0.625 0.25
|
||||
0.625 0.5
|
||||
0.75 0.625
|
||||
0.625 0.75
|
||||
0.5 0.625
|
||||
1 0.625
|
||||
0.875 0.75
|
||||
1 0.875
|
||||
0.875 1
|
||||
0.75 0.875
|
||||
0.625 1
|
||||
0.5 0.875
|
||||
0.25 0.625
|
||||
0.125 0.75
|
||||
0.375 0.75
|
||||
0.375 1
|
||||
0.25 0.875
|
||||
0.125 1
|
||||
-0.875 -0.875
|
||||
-0.625 -0.875
|
||||
-0.625 -0.625
|
||||
-0.875 -0.625
|
||||
-0.375 -0.875
|
||||
-0.125 -0.875
|
||||
-0.125 -0.625
|
||||
-0.375 -0.625
|
||||
-0.4375 -0.4375
|
||||
-0.4375 -0.3125
|
||||
-0.3125 -0.3125
|
||||
-0.3125 -0.4375
|
||||
-0.125 -0.375
|
||||
-0.1875 -0.1875
|
||||
-0.0625 -0.1875
|
||||
-0.0625 -0.0625
|
||||
-0.1875 -0.0625
|
||||
-0.3125 -0.0625
|
||||
-0.4375 -0.0625
|
||||
-0.4375 -0.1875
|
||||
-0.3125 -0.1875
|
||||
-0.875 -0.375
|
||||
-0.625 -0.375
|
||||
-0.625 -0.125
|
||||
-0.875 -0.125
|
||||
-0.875 0.125
|
||||
-0.625 0.125
|
||||
-0.625 0.375
|
||||
-0.875 0.375
|
||||
-0.4375 0.0625
|
||||
-0.4375 0.1875
|
||||
-0.3125 0.1875
|
||||
-0.3125 0.0625
|
||||
-0.1875 0.0625
|
||||
-0.09375 0.03125
|
||||
-0.046875 0.015625
|
||||
-0.015625 0.015625
|
||||
-0.015625 0.046875
|
||||
-0.046875 0.046875
|
||||
-0.03125 0.09375
|
||||
-0.09375 0.09375
|
||||
-0.0625 0.1875
|
||||
-0.1875 0.1875
|
||||
-0.1875 0.3125
|
||||
-0.0625 0.3125
|
||||
-0.0625 0.4375
|
||||
-0.1875 0.4375
|
||||
-0.375 0.375
|
||||
-0.375 0.625
|
||||
-0.125 0.625
|
||||
-0.125 0.875
|
||||
-0.375 0.875
|
||||
-0.875 0.625
|
||||
-0.625 0.625
|
||||
-0.625 0.875
|
||||
-0.875 0.875
|
||||
0.03125 0.03125
|
||||
0.09375 0.03125
|
||||
0.09375 0.09375
|
||||
0.03125 0.09375
|
||||
0.0625 0.1875
|
||||
0.1875 0.1875
|
||||
0.1875 0.0625
|
||||
0.3125 0.0625
|
||||
0.4375 0.0625
|
||||
0.4375 0.1875
|
||||
0.3125 0.1875
|
||||
0.375 0.375
|
||||
0.125 0.375
|
||||
0.5625 0.0625
|
||||
0.5625 0.1875
|
||||
0.6875 0.1875
|
||||
0.6875 0.0625
|
||||
0.875 0.125
|
||||
0.875 0.375
|
||||
0.625 0.375
|
||||
0.625 0.625
|
||||
0.875 0.625
|
||||
0.875 0.875
|
||||
0.625 0.875
|
||||
0.125 0.625
|
||||
0.375 0.625
|
||||
0.375 0.875
|
||||
0.125 0.875
|
||||
@@ -0,0 +1,188 @@
|
||||
|
||||
import commentjson
|
||||
from ray.rllib.agents.registry import get_agent_class
|
||||
import amr_env
|
||||
import gym
|
||||
from gym import spaces
|
||||
import ray
|
||||
import ray.rllib.agents.ppo as ppo
|
||||
import tensorflow as tf
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
import argparse
|
||||
import random
|
||||
from amr import models
|
||||
import pytest
|
||||
import os
|
||||
import copy
|
||||
from math import sqrt, nan, inf, isnan
|
||||
from ray.rllib.models import ModelCatalog
|
||||
from amr.models.cnn import CNNSmall
|
||||
|
||||
# rllib requires you to give the policy an env with the same action
|
||||
# and observation spaces as used in training. The rest of it can be
|
||||
# "fake" if you provide your own observation data some other way.
|
||||
|
||||
# USER INPUT - solution, 20x20 mesh, sine,tanh,steps,steps2, norm-diff reward with random threshold
|
||||
#866764
|
||||
#checkpoint_folder = "/p/lustre1/mittal3/local_deref/PPO/PPO_LocalAMR-v0_5b99d_00000_0_2021-06-07_12-12-52/"
|
||||
#checkpoint_number = 900
|
||||
|
||||
# USER INPUT - solution, 20x20 mesh, sine,tanh,steps,steps2, binary reward with random threshold
|
||||
#866762
|
||||
# checkpoint_folder = "/p/lustre1/mittal3/local_deref/PPO/PPO_LocalAMR-v0_8d234_00000_0_2021-06-07_12-07-06/"
|
||||
# checkpoint_number = 900
|
||||
|
||||
# solution, 20x20, steps2,sine,tanh,bumps, binary with random
|
||||
# 880258 - fixed threshold 1.e-5
|
||||
checkpoint_folder = "/p/lustre1/mittal3/local_deref/PPO/PPO_LocalAMR-v0_cc8cb_00000_0_2021-06-16_13-38-25"
|
||||
checkpoint_number = 1400
|
||||
|
||||
# 880259 - random threshold [1.e-2, 1.e-6]
|
||||
checkpoint_folder = "/p/lustre1/mittal3/local_deref/PPO/PPO_LocalAMR-v0_e1561_00000_0_2021-06-16_13-31-50"
|
||||
checkpoint_number = 900
|
||||
# with 1.e-3 - the second and third refinements are really good. still more than needed in first
|
||||
# with 1.e-2 - picks the right amount of elements.
|
||||
|
||||
#880328 - fixed threshold 1.e-2
|
||||
#checkpoint_folder = "/p/lustre1/mittal3/local_deref/PPO/PPO_LocalAMR-v0_3a8a0_00000_0_2021-06-16_16-18-58"
|
||||
#checkpoint_number = 300
|
||||
#refines 15 elements at first iteration.. not good with 300.
|
||||
|
||||
# solution, 10x10, steps2,sine,tanh,bumps, binary with random [1.e-2, 1.e-6]
|
||||
# slurm-880260.out
|
||||
#checkpoint_folder = "/p/lustre1/mittal3/local_deref/PPO/PPO_LocalAMR-v0_cc8cb_00000_0_2021-06-16_13-38-25/"
|
||||
#checkpoint_number = 1500
|
||||
#1.e-3 -> right region but first iteration has too many
|
||||
#1.e-2 is almost perfect
|
||||
|
||||
|
||||
|
||||
|
||||
#this has the policy without error threshold
|
||||
#checkpoint_folder = "/p/lustre1/mittal3/local_deref/PPO/PPO_LocalAMR-v0_c6ca5_00000_0_2021-05-24_16-07-13/"
|
||||
|
||||
# END OF USER INPUT
|
||||
|
||||
# Read info from json file used for training.
|
||||
full_checkpoint_path = checkpoint_folder + '/checkpoint_' + str(checkpoint_number)+ '/checkpoint-' + str(checkpoint_number)
|
||||
path_env_config_file = checkpoint_folder + '/params.json'
|
||||
with open(path_env_config_file) as json_file:
|
||||
env_trainer_config = commentjson.load(json_file)
|
||||
|
||||
trainer_config = env_trainer_config
|
||||
trainer_config['env_config']['mesh_params']['nx'] = 1
|
||||
trainer_config['env_config']['mesh_params']['ny'] = 1
|
||||
local_sample = env_trainer_config['env_config']['local_sample']
|
||||
local_context = env_trainer_config['env_config']['local_context']
|
||||
reward_params = env_trainer_config['env_config']['reward_function_params']
|
||||
|
||||
#set some default params
|
||||
observe_error = False
|
||||
observe_values = True
|
||||
observe_grads = False
|
||||
|
||||
#get observing quantities
|
||||
observe_values = env_trainer_config['env_config']['observe_values']
|
||||
observe_depth = env_trainer_config['env_config']['observe_depth']
|
||||
observe_jacobian = env_trainer_config['env_config']['observe_jacobian']
|
||||
observe_ar = env_trainer_config['env_config']['observe_ar']
|
||||
observe_grads = env_trainer_config['env_config']['observe_grads']
|
||||
normalization = env_trainer_config['env_config']['normalization']
|
||||
|
||||
#get reward_params
|
||||
reward_params = env_trainer_config['env_config']['reward_function_params']
|
||||
reward_params_name = reward_params['name']
|
||||
if reward_params_name == "random_penalized_norm_diff":
|
||||
observe_error = True
|
||||
if reward_params_name == "random_binary":
|
||||
observe_error = True
|
||||
|
||||
class DummyEnv(gym.Env):
|
||||
|
||||
def __init__(self, config): # the config param is required by rllib
|
||||
|
||||
# image size is 42x42 (a size which uses CNN by default in rllib)
|
||||
self.obsx = local_sample+2*local_context
|
||||
self.obsy = self.obsx
|
||||
|
||||
# Either do nothing (0) or refine (1)
|
||||
self.action_space = spaces.Discrete(2)
|
||||
|
||||
n_channels = 1
|
||||
n_channels = observe_values + observe_depth + observe_grads
|
||||
|
||||
low = -np.inf
|
||||
|
||||
high = np.inf
|
||||
self.observation_space = spaces.Dict({
|
||||
"scalar_info": spaces.Box(low=low, high=high, shape=(1 + observe_jacobian + observe_error, ), dtype=np.float32),
|
||||
"obs_data": spaces.Box(low=low, high=high,
|
||||
shape=(self.obsx,
|
||||
self.obsy,
|
||||
n_channels), dtype=np.float32)
|
||||
})
|
||||
|
||||
self.state = None
|
||||
|
||||
def step(self, action):
|
||||
pass
|
||||
def reset(self):
|
||||
pass
|
||||
def render(self):
|
||||
pass
|
||||
|
||||
class Evaluator():
|
||||
|
||||
def __init__(self):
|
||||
|
||||
print("starting ray...")
|
||||
ray.shutdown()
|
||||
ray.init()
|
||||
print("ray up...")
|
||||
|
||||
ModelCatalog.register_custom_model("cnn_small", CNNSmall)
|
||||
trainer = ppo.PPOTrainer(config=trainer_config,env=DummyEnv)
|
||||
trainer.restore(full_checkpoint_path)
|
||||
|
||||
trainer_config['evaluation_num_workers'] = 1
|
||||
trainer_config['evaluation_interval'] = 0
|
||||
trainer_config['num_workers'] = 0
|
||||
trainer_config['num_envs_per_worker'] = 1
|
||||
|
||||
self.agent = ppo.PPOTrainer(config=trainer_config,env=DummyEnv)
|
||||
self.agent.restore(full_checkpoint_path)
|
||||
|
||||
self.env = DummyEnv({})
|
||||
|
||||
def eval(self,obso,scalar):
|
||||
if observe_values and normalization:
|
||||
obso -= np.mean(obso)
|
||||
|
||||
obs = {
|
||||
"obs_data" : obso,
|
||||
"scalar_info" : scalar
|
||||
}
|
||||
|
||||
pick = self.agent.compute_action(obs, explore=False)
|
||||
return pick
|
||||
|
||||
def get_local_sample(self):
|
||||
return local_sample
|
||||
|
||||
def get_local_context(self):
|
||||
return local_context
|
||||
|
||||
def get_observe_error(self):
|
||||
return observe_error
|
||||
|
||||
def get_observe_jacobian(self):
|
||||
return observe_jacobian
|
||||
|
||||
def get_observe_values(self):
|
||||
return observe_values
|
||||
|
||||
def get_observe_gradient(self):
|
||||
return observe_grads
|
||||
@@ -0,0 +1,419 @@
|
||||
#include "mfem.hpp"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
using namespace mfem;
|
||||
using namespace std;
|
||||
|
||||
class MAL_DRLRefiner : public MeshOperator
|
||||
{
|
||||
protected:
|
||||
GridFunction& u;
|
||||
|
||||
Array<Refinement> marked_elements;
|
||||
long current_sequence;
|
||||
|
||||
int imgsz;
|
||||
int local_sample;
|
||||
int local_context;
|
||||
bool observe_jacobian;
|
||||
bool observe_error;
|
||||
bool observe_values;
|
||||
bool observe_gradient;
|
||||
|
||||
int nc_limit;
|
||||
|
||||
PyObject* eval_method;
|
||||
PyObject* get_local_sample_method;
|
||||
PyObject* get_local_context_method;
|
||||
PyObject* get_observe_error_method;
|
||||
PyObject* get_observe_jacobian_method;
|
||||
PyObject* get_observe_values_method;
|
||||
PyObject* get_observe_gradient_method;
|
||||
|
||||
FindPointsGSLIB *gslib;
|
||||
|
||||
/** @brief Apply the operator to the mesh.
|
||||
@return STOP if a stopping criterion is satisfied or no elements were
|
||||
marked for refinement; REFINED + CONTINUE otherwise. */
|
||||
virtual int ApplyImpl(Mesh &mesh);
|
||||
|
||||
public:
|
||||
|
||||
/// Construct a MAL_DRLRefiner that will operate on u.
|
||||
MAL_DRLRefiner(GridFunction &u);
|
||||
|
||||
// default destructor (virtual)
|
||||
|
||||
/** @brief Set the maximum ratio of refinement levels of adjacent elements
|
||||
(0 = unlimited). */
|
||||
void SetNCLimit(int nc_limit)
|
||||
{
|
||||
MFEM_ASSERT(nc_limit >= 0, "Invalid NC limit");
|
||||
this->nc_limit = nc_limit;
|
||||
}
|
||||
|
||||
virtual void Reset();
|
||||
};
|
||||
|
||||
MAL_DRLRefiner::MAL_DRLRefiner(GridFunction& u_) : u(u_)
|
||||
{
|
||||
int ret = _import_array();
|
||||
if (ret < 0) {
|
||||
printf("problem with import_array\n");
|
||||
}
|
||||
|
||||
PyRun_SimpleString("import sys");
|
||||
PyRun_SimpleString("sys.path.append('.')");
|
||||
|
||||
// This is a workaround for something in tensorflow that dies without it.
|
||||
PyRun_SimpleString("if not hasattr(sys, 'argv'):\n"
|
||||
" sys.argv = ['']");
|
||||
|
||||
PyObject* eval_mod = PyImport_ImportModule("mal_rllib_eval");
|
||||
if (eval_mod == 0) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
PyObject* eval_class = PyObject_GetAttrString(eval_mod, "Evaluator");
|
||||
if (eval_class == 0) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
Py_DECREF(eval_mod);
|
||||
|
||||
PyObject* args = Py_BuildValue("()");
|
||||
if (args == 0) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
PyObject* eval_obj = PyEval_CallObject(eval_class, args);
|
||||
if (eval_obj == NULL) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
eval_method = PyObject_GetAttrString(eval_obj, "eval");
|
||||
if (eval_method == 0) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
get_local_sample_method = PyObject_GetAttrString(eval_obj, "get_local_sample");
|
||||
get_local_context_method = PyObject_GetAttrString(eval_obj, "get_local_context");
|
||||
get_observe_error_method = PyObject_GetAttrString(eval_obj, "get_observe_error");
|
||||
get_observe_jacobian_method = PyObject_GetAttrString(eval_obj, "get_observe_jacobian");
|
||||
get_observe_values_method = PyObject_GetAttrString(eval_obj, "get_observe_values");
|
||||
get_observe_gradient_method = PyObject_GetAttrString(eval_obj, "get_observe_gradient");
|
||||
|
||||
PyObject* local_sample_p = PyObject_CallFunctionObjArgs(
|
||||
get_local_sample_method, nullptr);
|
||||
PyObject* local_context_p = PyObject_CallFunctionObjArgs(
|
||||
get_local_context_method, nullptr);
|
||||
PyObject* observe_jacobian_p = PyObject_CallFunctionObjArgs(
|
||||
get_observe_jacobian_method, nullptr);
|
||||
PyObject* observe_error_p = PyObject_CallFunctionObjArgs(
|
||||
get_observe_error_method, nullptr);
|
||||
PyObject* observe_values_p = PyObject_CallFunctionObjArgs(
|
||||
get_observe_values_method, nullptr);
|
||||
PyObject* observe_gradient_p = PyObject_CallFunctionObjArgs(
|
||||
get_observe_gradient_method, nullptr);
|
||||
|
||||
PyArg_Parse(local_sample_p, "i", &local_sample);
|
||||
PyArg_Parse(local_context_p, "i", &local_context);
|
||||
int observe_jacobian_i, observe_error_i, observe_values_i, observe_gradient_i;
|
||||
PyArg_Parse(observe_jacobian_p, "i", &observe_jacobian_i);
|
||||
PyArg_Parse(observe_error_p, "i", &observe_error_i);
|
||||
PyArg_Parse(observe_values_p, "i", &observe_values_i);
|
||||
PyArg_Parse(observe_gradient_p, "i", &observe_gradient_i);
|
||||
|
||||
observe_jacobian = bool(observe_jacobian_i);
|
||||
observe_error = bool(observe_error_i);
|
||||
observe_values = bool(observe_values_i);
|
||||
observe_gradient = bool(observe_gradient_i);
|
||||
|
||||
#ifdef MFEM_USE_GSLIB
|
||||
// setup gslib
|
||||
gslib = new FindPointsGSLIB();
|
||||
std::cout << " initialize findpts\n";
|
||||
#endif
|
||||
}
|
||||
|
||||
int MAL_DRLRefiner::ApplyImpl(Mesh &mesh)
|
||||
{
|
||||
#ifdef MFEM_USE_GSLIB
|
||||
// setup gslib
|
||||
gslib->FreeData();
|
||||
gslib->Setup(mesh);
|
||||
#endif
|
||||
double u_min = u.Min();
|
||||
double u_max = u.Max();
|
||||
// u -= u_min;
|
||||
// u /= (u_max-u_min);
|
||||
|
||||
marked_elements.SetSize(0);
|
||||
imgsz = local_sample + 2 * local_context;
|
||||
|
||||
GridFunction ugrad(u.FESpace());
|
||||
GridFunction ugradmag(u.FESpace());
|
||||
|
||||
if (observe_gradient) {
|
||||
const int s = ugrad.Size();
|
||||
|
||||
for (int d = 0; d < 2; d++)
|
||||
{
|
||||
u.GetDerivative(1, d, ugrad);
|
||||
for (int i = 0; i < s; i++)
|
||||
{
|
||||
ugradmag(i) += pow(ugrad(i), 2.0);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < s; i++)
|
||||
{
|
||||
ugradmag(i) = sqrt(ugradmag(i) + 1e-12);
|
||||
}
|
||||
}
|
||||
|
||||
for (int k = 0; k < mesh.GetNE(); k++) {
|
||||
|
||||
// get scalar info
|
||||
const int scalar_size = 1 + observe_error + observe_jacobian;
|
||||
double* scalar_obs1 = new double[scalar_size];
|
||||
scalar_obs1[0] = 1;
|
||||
bool boundary = false;
|
||||
Array<int> fcs, cor;
|
||||
int e1, e2, inf1, inf2, ncf;
|
||||
mesh.GetElementEdges(k, fcs, cor);
|
||||
for (int f = 0; f < fcs.Size() && boundary == false; f++) {
|
||||
mesh.GetFaceElements(fcs[f], &e1, &e2);
|
||||
mesh.GetFaceInfos(fcs[f], &inf1, &inf2, &ncf);
|
||||
if (e2 < 0 && inf2 < 0 && ncf == -1) {
|
||||
boundary = true;
|
||||
}
|
||||
}
|
||||
if (!boundary) {
|
||||
scalar_obs1[0] = 2;
|
||||
}
|
||||
|
||||
|
||||
double error_threshold = 1.0e-2;
|
||||
if (observe_jacobian && observe_error) {
|
||||
scalar_obs1[1] = mesh.GetElementVolume(k);
|
||||
scalar_obs1[2] = error_threshold;
|
||||
}
|
||||
else if (observe_jacobian) {
|
||||
scalar_obs1[1] = mesh.GetElementVolume(k);
|
||||
}
|
||||
else if (observe_error) {
|
||||
scalar_obs1[1] = error_threshold;
|
||||
}
|
||||
|
||||
// assemble matrix of sample points, ref_space -> phys_space
|
||||
ElementTransformation* trk = mesh.GetElementTransformation(k);
|
||||
IntegrationPoint ipk;
|
||||
Vector xk(2);
|
||||
DenseMatrix m(2,imgsz*imgsz);
|
||||
int c = 0;
|
||||
double r_init = 0.001,
|
||||
r_final = 1.0-r_init;
|
||||
for (int j = 0; j < imgsz; ++j) {
|
||||
for (int i = 0; i < imgsz; ++i) {
|
||||
if (!boundary) {
|
||||
ipk.y = (j - local_context + 0.5)/local_sample;
|
||||
ipk.x = (i - local_context + 0.5)/local_sample;
|
||||
}
|
||||
else {
|
||||
ipk.y = (r_init + j*(r_final-r_init))/(imgsz-1);
|
||||
ipk.x = (r_init + i*(r_final-r_init))/(imgsz-1);
|
||||
}
|
||||
|
||||
trk->Transform(ipk, xk);
|
||||
m.SetCol(c++,xk);
|
||||
}
|
||||
}
|
||||
|
||||
// phys_space -> elements, ips
|
||||
Array<int> elems(imgsz*imgsz);
|
||||
Array<IntegrationPoint> ips(imgsz*imgsz);
|
||||
int n;
|
||||
bool complete;
|
||||
Vector ui;
|
||||
double* obs1 = new double[imgsz*imgsz];
|
||||
#ifdef MFEM_USE_GSLIB
|
||||
DenseMatrix mt(imgsz*imgsz, 2);
|
||||
mt.Transpose(m);
|
||||
Vector xyz(mt.GetData(), imgsz*imgsz*2);
|
||||
ui.SetDataAndSize(obs1, imgsz*imgsz);
|
||||
gslib->Interpolate(xyz, u, ui);
|
||||
#else
|
||||
n = mesh.FindPoints(m, elems, ips, false);
|
||||
|
||||
// Build observation from GridFunction using elements, ips
|
||||
n = 0;
|
||||
complete = true;
|
||||
for (int j = 0; j < imgsz; ++j) {
|
||||
for (int i = 0; i < imgsz; ++i) {
|
||||
int el = elems[n];
|
||||
if (el == -1) {
|
||||
obs1[i*imgsz+j] = 0.0;
|
||||
complete = false;
|
||||
}
|
||||
else {
|
||||
IntegrationPoint& ip = ips[n];
|
||||
if (observe_gradient) {
|
||||
//std::cout << i << " " << j << " k10getgradmag\n";
|
||||
obs1[i*imgsz+j] = ugradmag.GetValue(el, ip);
|
||||
obs1[i*imgsz+j] = u.GetValue(el, ip);
|
||||
}
|
||||
else {
|
||||
obs1[i*imgsz+j] = u.GetValue(el, ip);
|
||||
}
|
||||
}
|
||||
n++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO: More efficient way to do the below mirroring
|
||||
// invert i
|
||||
double* obs2 = new double[imgsz*imgsz];
|
||||
n = 0;
|
||||
complete = true;
|
||||
for (int j = 0; j < imgsz; ++j) {
|
||||
for (int i = imgsz-1; i >= 0; --i) {
|
||||
// int el = elems[n];
|
||||
// if (el == -1) {
|
||||
// obs2[i*imgsz+j] = 0.0;
|
||||
// complete = false;
|
||||
// }
|
||||
// else {
|
||||
// IntegrationPoint& ip = ips[n];
|
||||
// obs2[i*imgsz+j] = u.GetValue(el, ip);
|
||||
// }
|
||||
obs2[i*imgsz+j] = obs1[n];
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
// invert j
|
||||
double* obs3 = new double[imgsz*imgsz];
|
||||
n = 0;
|
||||
complete = true;
|
||||
for (int j = imgsz-1; j >= 0; --j) {
|
||||
for (int i = 0; i < imgsz; ++i) {
|
||||
// int el = elems[n];
|
||||
// if (el == -1) {
|
||||
// obs3[i*imgsz+j] = 0.0;
|
||||
// complete = false;
|
||||
// }
|
||||
// else {
|
||||
// IntegrationPoint& ip = ips[n];
|
||||
// obs3[i*imgsz+j] = u.GetValue(el, ip);
|
||||
// }
|
||||
obs3[i*imgsz+j] = obs1[n];
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
// invert i and j
|
||||
double* obs4 = new double[imgsz*imgsz];
|
||||
n = 0;
|
||||
complete = true;
|
||||
for (int j = imgsz-1; j >= 0; --j) {
|
||||
for (int i = imgsz-1; i >= 0; --i) {
|
||||
// int el = elems[n];
|
||||
// if (el == -1) {
|
||||
// obs4[i*imgsz+j] = 0.0;
|
||||
// complete = false;
|
||||
// }
|
||||
// else {
|
||||
// IntegrationPoint& ip = ips[n];
|
||||
// obs4[i*imgsz+j] = u.GetValue(el, ip);
|
||||
// }
|
||||
obs4[i*imgsz+j] = obs1[n];
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// apply policy: state -> action
|
||||
bool refine = false;
|
||||
if (complete) {
|
||||
|
||||
// convert to numpy array
|
||||
npy_intp dims[3];
|
||||
dims[0] = imgsz;
|
||||
dims[1] = imgsz;
|
||||
dims[2] = 1;
|
||||
|
||||
npy_intp scalar_dims[1];
|
||||
scalar_dims[0] = scalar_size;
|
||||
|
||||
PyObject *pArray1 = PyArray_SimpleNewFromData(
|
||||
3, dims, NPY_DOUBLE, reinterpret_cast<void*>(obs1));
|
||||
PyObject *pArray2 = PyArray_SimpleNewFromData(
|
||||
3, dims, NPY_DOUBLE, reinterpret_cast<void*>(obs2));
|
||||
PyObject *pArray3 = PyArray_SimpleNewFromData(
|
||||
3, dims, NPY_DOUBLE, reinterpret_cast<void*>(obs3));
|
||||
PyObject *pArray4 = PyArray_SimpleNewFromData(
|
||||
3, dims, NPY_DOUBLE, reinterpret_cast<void*>(obs4));
|
||||
PyObject *sArray1 = PyArray_SimpleNewFromData(
|
||||
1, scalar_dims, NPY_DOUBLE, reinterpret_cast<void*>(scalar_obs1));
|
||||
if (pArray1 == NULL) printf("pArray1 NULL!\n");
|
||||
|
||||
PyObject* action1 = PyObject_CallFunctionObjArgs(
|
||||
eval_method, pArray1, sArray1, nullptr);
|
||||
PyObject* action2 = PyObject_CallFunctionObjArgs(
|
||||
eval_method, pArray2, sArray1, nullptr);
|
||||
PyObject* action3 = PyObject_CallFunctionObjArgs(
|
||||
eval_method, pArray3, sArray1, nullptr);
|
||||
PyObject* action4 = PyObject_CallFunctionObjArgs(
|
||||
eval_method, pArray4, sArray1, nullptr);
|
||||
|
||||
if (action1 == 0 || action2 == 0) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// parse integer return value
|
||||
int action1_val;
|
||||
PyArg_Parse(action1, "i", &action1_val);
|
||||
int action2_val;
|
||||
PyArg_Parse(action2, "i", &action2_val);
|
||||
int action3_val;
|
||||
PyArg_Parse(action3, "i", &action3_val);
|
||||
int action4_val;
|
||||
PyArg_Parse(action4, "i", &action4_val);
|
||||
refine =
|
||||
bool(action1_val) ||
|
||||
bool(action2_val) ||
|
||||
bool(action3_val) ||
|
||||
bool(action4_val);
|
||||
}
|
||||
|
||||
delete scalar_obs1;
|
||||
delete obs1;
|
||||
delete obs2;
|
||||
delete obs3;
|
||||
delete obs4;
|
||||
|
||||
if (refine) {
|
||||
marked_elements.Append(Refinement(k));
|
||||
}
|
||||
}
|
||||
|
||||
long int num_marked_elements = mesh.ReduceInt(marked_elements.Size());
|
||||
printf("marked %d elements\n",num_marked_elements);
|
||||
if (num_marked_elements == 0) { return STOP; }
|
||||
|
||||
bool nonconforming = true;
|
||||
mesh.GeneralRefinement(marked_elements, nonconforming, nc_limit);
|
||||
return CONTINUE + REFINED;
|
||||
}
|
||||
|
||||
void MAL_DRLRefiner::Reset()
|
||||
{
|
||||
current_sequence = -1;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
|
||||
|
||||
import gym
|
||||
from gym import spaces
|
||||
import ray
|
||||
import ray.rllib.agents.ppo as ppo
|
||||
import tensorflow as tf
|
||||
|
||||
import numpy as np
|
||||
|
||||
# rllib requires you to give the policy an env with the same action
|
||||
# and observation spaces as used in training. The rest of it can be
|
||||
# "fake" if you provide your own observation data some other way.
|
||||
|
||||
class DummyEnv(gym.Env):
|
||||
|
||||
def __init__(self, config): # the config param is required by rllib
|
||||
|
||||
# image size is 42x42 (a size which uses CNN by default in rllib)
|
||||
self.obsx = 42
|
||||
self.obsy = 42
|
||||
|
||||
# Either do nothing (0) or refine (1)
|
||||
self.action_space = spaces.Discrete(2)
|
||||
self.observation_space = spaces.Box(-1.0, 2.0, shape=(self.obsx,self.obsy,1))
|
||||
|
||||
self.state = None
|
||||
|
||||
def step(self, action):
|
||||
pass
|
||||
def reset(self):
|
||||
pass
|
||||
def render(self):
|
||||
pass
|
||||
|
||||
class Evaluator():
|
||||
|
||||
def __init__(self):
|
||||
|
||||
print("starting ray...")
|
||||
ray.shutdown()
|
||||
ray.init()
|
||||
print("ray up...")
|
||||
|
||||
config = ppo.DEFAULT_CONFIG.copy()
|
||||
config["log_level"] = "WARN"
|
||||
|
||||
# Create agent from checkpoint
|
||||
self.agent = ppo.PPOTrainer(config,env=DummyEnv)
|
||||
self.agent.restore("DRLRefinePolicy/checkpoint_210/checkpoint-210")
|
||||
|
||||
self.env = DummyEnv({})
|
||||
|
||||
def eval(self,obs):
|
||||
pick = self.agent.compute_action(obs, explore=False)
|
||||
return pick
|
||||
|
||||
#evaluator = Evaluator()
|
||||
#obs = np.ones((42,42,1))
|
||||
#ref = evaluator.eval(obs)
|
||||
#evaluator.show_logits(obs)
|
||||
# evaluator.eval(np.random.rand(8))
|
||||
# evaluator.eval(np.random.rand(8))
|
||||
|
||||
@@ -234,6 +234,9 @@ ifeq ($(MFEM_USE_CUDA),YES)
|
||||
endif
|
||||
endif
|
||||
|
||||
MFEM_CXX += $(shell /usr/bin/python3-config --includes)
|
||||
#ALL_LIBS += $(shell /usr/bin/python3-config --ldflags)
|
||||
|
||||
# HIP configuration
|
||||
ifeq ($(MFEM_USE_HIP),YES)
|
||||
ifeq ($(MFEM_USE_MPI),YES)
|
||||
@@ -311,6 +314,8 @@ $(foreach dep,$(MFEM_DEPENDENCIES),$(eval $(call mfem_add_dependency,$(dep))))
|
||||
$(foreach dep,$(MFEM_LEGACY_DEPENDENCIES),$(eval $(call \
|
||||
mfem_add_legacy_dependency,$(dep))))
|
||||
|
||||
ALL_LIBS += $(shell /usr/bin/python3-config --ldflags)
|
||||
|
||||
# Timer option
|
||||
ifeq ($(MFEM_TIMER_TYPE),2)
|
||||
ALL_LIBS += $(POSIX_CLOCKS_LIB)
|
||||
|
||||
@@ -145,6 +145,242 @@ void ThresholdRefiner::Reset()
|
||||
// marked_elements.SetSize(0); // not necessary
|
||||
}
|
||||
|
||||
DRLRefiner::DRLRefiner(GridFunction& u_) : u(u_)
|
||||
{
|
||||
int ret = _import_array();
|
||||
if (ret < 0) {
|
||||
printf("problem with import_array\n");
|
||||
}
|
||||
|
||||
obs_x = 42;
|
||||
obs_y = 42;
|
||||
|
||||
PyRun_SimpleString("import sys");
|
||||
PyRun_SimpleString("sys.path.append('.')");
|
||||
|
||||
// This is a workaround for something in tensorflow that dies without it.
|
||||
PyRun_SimpleString("if not hasattr(sys, 'argv'):\n"
|
||||
" sys.argv = ['']");
|
||||
|
||||
PyObject* eval_mod = PyImport_ImportModule("rllib_eval");
|
||||
if (eval_mod == 0) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
PyObject* eval_class = PyObject_GetAttrString(eval_mod, "Evaluator");
|
||||
if (eval_class == 0) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
Py_DECREF(eval_mod);
|
||||
|
||||
PyObject* args = Py_BuildValue("()");
|
||||
if (args == 0) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
PyObject* eval_obj = PyEval_CallObject(eval_class, args);
|
||||
if (eval_obj == NULL) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
eval_method = PyObject_GetAttrString(eval_obj, "eval");
|
||||
if (eval_method == 0) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int DRLRefiner::ApplyImpl(Mesh &mesh)
|
||||
{
|
||||
marked_elements.SetSize(0);
|
||||
|
||||
const int imgsz = 42;
|
||||
|
||||
double ref_w = 2.0;
|
||||
assert(obs_x == obs_y);
|
||||
int ref_n = obs_x;
|
||||
double ref_lo = 0.0 -ref_w;
|
||||
double ref_hi = 1.0 +ref_w;
|
||||
double ref_dx = (ref_hi -ref_lo)/ref_n;
|
||||
|
||||
for (int k = 0; k < mesh.GetNE(); k++) {
|
||||
|
||||
// assemble matrix of sample points, ref_space -> phys_space
|
||||
ElementTransformation* trk = mesh.GetElementTransformation(k);
|
||||
IntegrationPoint ipk;
|
||||
Vector xk(2);
|
||||
DenseMatrix m(2,imgsz*imgsz);
|
||||
int c = 0;
|
||||
for (int j = 0; j < obs_y; ++j) {
|
||||
ipk.y = ref_lo +(j+0.5)*ref_dx;
|
||||
for (int i = 0; i < obs_x; ++i) {
|
||||
ipk.x = ref_lo +(i+0.5)*ref_dx;
|
||||
trk->Transform(ipk, xk);
|
||||
m.SetCol(c++,xk);
|
||||
}
|
||||
}
|
||||
|
||||
// phys_space -> elements, ips
|
||||
Array<int> elems;
|
||||
Array<IntegrationPoint> ips;
|
||||
int n = mesh.FindPoints(m, elems, ips, false);
|
||||
|
||||
// Build observation from GridFunction using elements, ips
|
||||
double* obs1 = new double[imgsz*imgsz];
|
||||
n = 0;
|
||||
bool complete = true;
|
||||
for (int j = 0; j < obs_y; ++j) {
|
||||
for (int i = 0; i < obs_x; ++i) {
|
||||
int el = elems[n];
|
||||
if (el == -1) {
|
||||
obs1[i*imgsz+j] = 0.0;
|
||||
complete = false;
|
||||
}
|
||||
else {
|
||||
IntegrationPoint& ip = ips[n];
|
||||
obs1[i*imgsz+j] = u.GetValue(el, ip);
|
||||
}
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: More efficient way to do the below mirroring
|
||||
|
||||
// invert i
|
||||
double* obs2 = new double[imgsz*imgsz];
|
||||
n = 0;
|
||||
complete = true;
|
||||
for (int j = 0; j < obs_y; ++j) {
|
||||
for (int i = obs_x-1; i >= 0; --i) {
|
||||
int el = elems[n];
|
||||
if (el == -1) {
|
||||
obs2[i*imgsz+j] = 0.0;
|
||||
complete = false;
|
||||
}
|
||||
else {
|
||||
IntegrationPoint& ip = ips[n];
|
||||
obs2[i*imgsz+j] = u.GetValue(el, ip);
|
||||
}
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
// invert j
|
||||
double* obs3 = new double[imgsz*imgsz];
|
||||
n = 0;
|
||||
complete = true;
|
||||
for (int j = obs_y-1; j >= 0; --j) {
|
||||
for (int i = 0; i < obs_x; ++i) {
|
||||
int el = elems[n];
|
||||
if (el == -1) {
|
||||
obs3[i*imgsz+j] = 0.0;
|
||||
complete = false;
|
||||
}
|
||||
else {
|
||||
IntegrationPoint& ip = ips[n];
|
||||
obs3[i*imgsz+j] = u.GetValue(el, ip);
|
||||
}
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
// invert i and j
|
||||
double* obs4 = new double[imgsz*imgsz];
|
||||
n = 0;
|
||||
complete = true;
|
||||
for (int j = obs_y-1; j >= 0; --j) {
|
||||
for (int i = obs_x-1; i >= 0; --i) {
|
||||
int el = elems[n];
|
||||
if (el == -1) {
|
||||
obs4[i*imgsz+j] = 0.0;
|
||||
complete = false;
|
||||
}
|
||||
else {
|
||||
IntegrationPoint& ip = ips[n];
|
||||
obs4[i*imgsz+j] = u.GetValue(el, ip);
|
||||
}
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
// apply policy: state -> action
|
||||
bool refine = false;
|
||||
if (complete) {
|
||||
|
||||
// convert to numpy array
|
||||
npy_intp dims[3];
|
||||
dims[0] = imgsz;
|
||||
dims[1] = imgsz;
|
||||
dims[2] = 1;
|
||||
|
||||
PyObject *pArray1 = PyArray_SimpleNewFromData(
|
||||
3, dims, NPY_DOUBLE, reinterpret_cast<void*>(obs1));
|
||||
if (pArray1 == NULL) printf("pArray1 NULL!\n");
|
||||
|
||||
PyObject *pArray2 = PyArray_SimpleNewFromData(
|
||||
3, dims, NPY_DOUBLE, reinterpret_cast<void*>(obs2));
|
||||
if (pArray2 == NULL) printf("pArray2 NULL!\n");
|
||||
|
||||
PyObject *pArray3 = PyArray_SimpleNewFromData(
|
||||
3, dims, NPY_DOUBLE, reinterpret_cast<void*>(obs3));
|
||||
if (pArray3 == NULL) printf("pArray3 NULL!\n");
|
||||
|
||||
PyObject *pArray4 = PyArray_SimpleNewFromData(
|
||||
3, dims, NPY_DOUBLE, reinterpret_cast<void*>(obs4));
|
||||
if (pArray4 == NULL) printf("pArray4 NULL!\n");
|
||||
|
||||
PyObject* action1 = PyObject_CallFunctionObjArgs(
|
||||
eval_method, pArray1, nullptr);
|
||||
PyObject* action2 = PyObject_CallFunctionObjArgs(
|
||||
eval_method, pArray2, nullptr);
|
||||
PyObject* action3 = PyObject_CallFunctionObjArgs(
|
||||
eval_method, pArray3, nullptr);
|
||||
PyObject* action4 = PyObject_CallFunctionObjArgs(
|
||||
eval_method, pArray4, nullptr);
|
||||
|
||||
if (action1 == 0 || action2 == 0) {
|
||||
PyErr_Print();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// parse integer return value
|
||||
int action1_val;
|
||||
PyArg_Parse(action1, "i", &action1_val);
|
||||
int action2_val;
|
||||
PyArg_Parse(action2, "i", &action2_val);
|
||||
int action3_val;
|
||||
PyArg_Parse(action3, "i", &action3_val);
|
||||
int action4_val;
|
||||
PyArg_Parse(action4, "i", &action4_val);
|
||||
refine =
|
||||
bool(action1_val) ||
|
||||
bool(action2_val) ||
|
||||
bool(action3_val) ||
|
||||
bool(action4_val);
|
||||
}
|
||||
|
||||
if (refine) {
|
||||
marked_elements.Append(Refinement(k));
|
||||
}
|
||||
}
|
||||
|
||||
long int num_marked_elements = mesh.ReduceInt(marked_elements.Size());
|
||||
printf("marked %d elements\n",num_marked_elements);
|
||||
if (num_marked_elements == 0) { return STOP; }
|
||||
|
||||
bool nonconforming = true;
|
||||
mesh.GeneralRefinement(marked_elements, nonconforming, nc_limit);
|
||||
return CONTINUE + REFINED;
|
||||
}
|
||||
|
||||
void DRLRefiner::Reset()
|
||||
{
|
||||
current_sequence = -1;
|
||||
}
|
||||
|
||||
int ThresholdDerefiner::ApplyImpl(Mesh &mesh)
|
||||
{
|
||||
|
||||
@@ -19,6 +19,12 @@
|
||||
|
||||
#include <limits>
|
||||
|
||||
#define MFEM_USE_RLLIB
|
||||
#ifdef MFEM_USE_RLLIB
|
||||
#include <Python.h>
|
||||
#include "numpy/arrayobject.h"
|
||||
#endif
|
||||
|
||||
namespace mfem
|
||||
{
|
||||
|
||||
@@ -254,6 +260,48 @@ public:
|
||||
virtual void Reset();
|
||||
};
|
||||
|
||||
/** @brief Mesh refinement operator using a DRL policy from rllib.
|
||||
|
||||
*/
|
||||
|
||||
class DRLRefiner : public MeshOperator
|
||||
{
|
||||
protected:
|
||||
GridFunction& u;
|
||||
|
||||
Array<Refinement> marked_elements;
|
||||
long current_sequence;
|
||||
|
||||
int obs_x;
|
||||
int obs_y;
|
||||
|
||||
int nc_limit;
|
||||
|
||||
PyObject* eval_method;
|
||||
|
||||
/** @brief Apply the operator to the mesh.
|
||||
@return STOP if a stopping criterion is satisfied or no elements were
|
||||
marked for refinement; REFINED + CONTINUE otherwise. */
|
||||
virtual int ApplyImpl(Mesh &mesh);
|
||||
|
||||
public:
|
||||
|
||||
/// Construct a DRLRefiner that will operate on u.
|
||||
DRLRefiner(GridFunction &u);
|
||||
|
||||
// default destructor (virtual)
|
||||
|
||||
/** @brief Set the maximum ratio of refinement levels of adjacent elements
|
||||
(0 = unlimited). */
|
||||
void SetNCLimit(int nc_limit)
|
||||
{
|
||||
MFEM_ASSERT(nc_limit >= 0, "Invalid NC limit");
|
||||
this->nc_limit = nc_limit;
|
||||
}
|
||||
|
||||
virtual void Reset();
|
||||
};
|
||||
|
||||
// TODO: BulkRefiner to refine a portion of the global error
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user