Compare commits

...
4 Commits
7 changed files with 697 additions and 3 deletions
+3
View File
@@ -199,10 +199,13 @@ miniapps/performance/sol.*
miniapps/tools/display-basis
miniapps/tools/load-dc
miniapps/tools/coef-fact
miniapps/tools/convert-dc
miniapps/tools/lor-transfer
miniapps/tools/get-values
miniapps/tools/coef-fact.inp
miniapps/toys/automata
miniapps/toys/life
miniapps/toys/mandel
+340
View File
@@ -10,6 +10,7 @@
// CONTRIBUTING.md for details.
#include "fem_extras.hpp"
#include "../../general/text.hpp"
using namespace std;
@@ -56,6 +57,345 @@ RT_FESpace::~RT_FESpace()
delete FEC_;
}
CoefFactory::~CoefFactory()
{
for (int i=0; i<sCoefs.Size(); i++)
{
delete sCoefs[i];
}
for (int i=0; i<vCoefs.Size(); i++)
{
delete vCoefs[i];
}
for (int i=0; i<mCoefs.Size(); i++)
{
delete mCoefs[i];
}
}
Coefficient * CoefFactory::GetScalarCoef(std::istream &input)
{
string buff;
skip_comment_lines(input, '#');
input >> buff;
return this->GetScalarCoef(buff, input);
}
VectorCoefficient * CoefFactory::GetVectorCoef(std::istream &input)
{
string buff;
skip_comment_lines(input, '#');
input >> buff;
return this->GetVectorCoef(buff, input);
}
MatrixCoefficient * CoefFactory::GetMatrixCoef(std::istream &input)
{
string buff;
skip_comment_lines(input, '#');
input >> buff;
return this->GetMatrixCoef(buff, input);
}
Coefficient * CoefFactory::GetScalarCoef(std::string &name,
std::istream &input)
{
int c = -1;
if (name == "ConstantCoefficient")
{
double val;
input >> val;
c = sCoefs.Append(new ConstantCoefficient(val));
}
else if (name == "PWConstCoefficient")
{
int nvals;
input >> nvals;
Vector vals(nvals);
for (int i=0; i<nvals; i++)
{
input >> vals[i];
}
c = sCoefs.Append(new PWConstCoefficient(vals));
}
else if (name == "FunctionCoefficient")
{
int type, index;
input >> type >> index;
MFEM_VERIFY(type >=0 && type <= 1,
"Invalid Function type read by CoefFactory");
if (type == 0)
{
MFEM_VERIFY(index >=0 && index < ext_sfn.Size(),
"Invalid Function index read by CoefFactory");
}
else
{
MFEM_VERIFY(index >=0 && index < ext_stfn.Size(),
"Invalid Time dependent Function index "
"read by CoefFactory");
}
c = sCoefs.Append((type == 0) ?
new FunctionCoefficient(ext_sfn[index]) :
new FunctionCoefficient(ext_stfn[index]));
}
else if (name == "GridFunctionCoefficient")
{
int index, comp;
input >> index >> comp;
MFEM_VERIFY(index >=0 && index < ext_gf.Size(),
"Invalid GridFunction index read by CoefFactory");
c = sCoefs.Append(new GridFunctionCoefficient(ext_gf[index], comp));
}
else if (name == "DivergenceGridFunctionCoefficient")
{
int index;
input >> index;
MFEM_VERIFY(index >=0 && index < ext_gf.Size(),
"Invalid GridFunction index for "
"DivergenceGridFunctionCoefficient read by CoefFactory");
c = sCoefs.Append(new DivergenceGridFunctionCoefficient(ext_gf[index]));
}
else if (name == "DeltaCofficient")
{
int dim;
input >> dim;
MFEM_VERIFY(dim >=1 && dim <= 3,
"Invalid dimension for DeltaCoefficient "
"read by CoefFactory");
double x, y, z, s;
input >> x;
if (dim > 1) { input >> y; }
if (dim > 2) { input >> z; }
input >> s;
if (dim == 1)
{
c = sCoefs.Append(new DeltaCoefficient(x, s));
}
else if (dim == 2)
{
c = sCoefs.Append(new DeltaCoefficient(x, y, s));
}
else
{
c = sCoefs.Append(new DeltaCoefficient(x, y, z, s));
}
}
else if (name == "RestrictedCoefficient")
{
Coefficient * rc = this->GetScalarCoef(input);
int nattr;
input >> nattr;
Array<int> attr(nattr);
for (int i=0; i<nattr; i++)
{
input >> attr[i];
}
c = sCoefs.Append(new RestrictedCoefficient(*rc, attr));
}
else
{
return NULL;
}
return sCoefs[--c];
}
VectorCoefficient * CoefFactory::GetVectorCoef(std::string &name,
std::istream &input)
{
int c = -1;
if (name == "VectorConstantCoefficient")
{
int dim;
input >> dim;
Vector val(dim);
for (int i=0; i<dim; i++) { input >> val[i]; }
c = vCoefs.Append(new VectorConstantCoefficient(val));
}
else if (name == "VectorFunctionCoefficient")
{
int dim, type, index;
input >> dim >> type >> index;
MFEM_VERIFY(type >=0 && type <= 1,
"Invalid Function type read by VecCoefFactory");
if (type == 0)
{
MFEM_VERIFY(index >=0 && index < ext_vfn.Size(),
"Invalid Vector Function index read by CoefFactory");
}
else
{
MFEM_VERIFY(index >=0 && index < ext_vtfn.Size(),
"Invalid Time dependent Vector Function index "
"read by CoefFactory");
}
c = vCoefs.Append((type==0) ?
new VectorFunctionCoefficient(dim, ext_vfn[index]) :
new VectorFunctionCoefficient(dim, ext_vtfn[index]));
}
else if (name == "VectorArrayCoefficient")
{
int dim;
input >> dim;
MFEM_VERIFY(dim > 0,
"Invalid dimension for VectorArrayCoefficient "
"read by CoefFactory");
VectorArrayCoefficient * vCoef = new VectorArrayCoefficient(dim);
for (int i=0; i<dim; i++)
{
Coefficient *sCoef = this->GetScalarCoef(input);
vCoef->Set(i, sCoef, false);
}
c = vCoefs.Append(vCoef);
}
else if (name == "VectorGridFunctionCoefficient")
{
int index;
input >> index;
MFEM_VERIFY(index >=0 && index < ext_gf.Size(),
"Invalid GridFunction index read by CoefFactory");
c = vCoefs.Append(new VectorGridFunctionCoefficient(ext_gf[index]));
}
else if (name == "GradientGridFunctionCoefficient")
{
int index;
input >> index;
MFEM_VERIFY(index >=0 && index < ext_gf.Size(),
"Invalid GridFunction index for "
"GradientGridFunctionCoefficient read by CoefFactory");
c = vCoefs.Append(new GradientGridFunctionCoefficient(ext_gf[index]));
}
else if (name == "CurlGridFunctionCoefficient")
{
int index;
input >> index;
MFEM_VERIFY(index >=0 && index < ext_gf.Size(),
"Invalid GridFunction index for "
"CurlGridFunctionCoefficient read by CoefFactory");
c = vCoefs.Append(new CurlGridFunctionCoefficient(ext_gf[index]));
}
else if (name == "VectorDeltaCofficient")
{
int dim;
input >> dim;
MFEM_VERIFY(dim >=1 && dim <= 3,
"Invalid dimension for DeltaCoefficient "
"read by CoefFactory");
Vector dir(dim);
for (int i=0; i<dim; i++) { input >> dir[i]; }
double x, y, z, s;
input >> x;
if (dim > 1) { input >> y; }
if (dim > 2) { input >> z; }
input >> s;
if (dim == 1)
{
c = vCoefs.Append(new VectorDeltaCoefficient(dir, x, s));
}
else if (dim == 2)
{
c = vCoefs.Append(new VectorDeltaCoefficient(dir, x, y, s));
}
else
{
c = vCoefs.Append(new VectorDeltaCoefficient(dir, x, y, z, s));
}
}
else if (name == "VectorRestrictedCoefficient")
{
VectorCoefficient * rc = this->GetVectorCoef(input);
int nattr;
input >> nattr;
Array<int> attr(nattr);
for (int i=0; i<nattr; i++)
{
input >> attr[i];
}
c = vCoefs.Append(new VectorRestrictedCoefficient(*rc, attr));
}
else
{
return NULL;
}
return vCoefs[--c];
}
MatrixCoefficient * CoefFactory::GetMatrixCoef(std::string &name,
std::istream &input)
{
int c = -1;
if (name == "MatrixConstantCoefficient")
{
int h, w;
input >> h >> w;
DenseMatrix val(h, w);
for (int i=0; i<h; i++)
for (int j=0; j<w; j++)
{ input >> val(i, j); }
c = mCoefs.Append(new MatrixConstantCoefficient(val));
}
else if (name == "MatrixFunctionCoefficient")
{
int type;
input >> type;
MFEM_VERIFY(type >=0 && type <= 2,
"Invalid Function type read by MatCoefFactory");
if (type < 2)
{
int dim, index;
input >> dim >> index;
if (type == 0)
{
MFEM_VERIFY(index >=0 && index < ext_mfn.Size(),
"Invalid Matrix Function index read by MatCoefFactory");
}
else
{
MFEM_VERIFY(index >=0 && index < ext_mtfn.Size(),
"Invalid Time dependent Matrix Function index "
"read by MatCoefFactory");
}
c = mCoefs.Append((type==0) ?
new MatrixFunctionCoefficient(dim, ext_mfn[index]) :
new MatrixFunctionCoefficient(dim, ext_mtfn[index]));
}
else
{
int h, w;
input >> h >> w;
DenseMatrix val(h, w);
for (int i=0; i<h; i++)
for (int j=0; j<w; j++)
{ input >> val(i, j); }
Coefficient * sCoef = this->GetScalarCoef(input);
c = mCoefs.Append(new MatrixFunctionCoefficient(val, *sCoef));
}
}
else if (name == "MatrixRestrictedCoefficient")
{
MatrixCoefficient * rc = this->GetMatrixCoef(input);
int nattr;
input >> nattr;
Array<int> attr(nattr);
for (int i=0; i<nattr; i++)
{
input >> attr[i];
}
c = mCoefs.Append(new MatrixRestrictedCoefficient(*rc, attr));
}
else
{
return NULL;
}
return mCoefs[--c];
}
void VisualizeMesh(socketstream &sock, const char *vishost, int visport,
Mesh &mesh, const char *title,
int x, int y, int w, int h, const char * keys, bool vec)
+55
View File
@@ -66,6 +66,61 @@ private:
};
class CoefFactory
{
protected:
Array<Coefficient*> sCoefs; ///< Owned
Array<VectorCoefficient*> vCoefs; ///< Owned
Array<MatrixCoefficient*> mCoefs; ///< Owned
Array<GridFunction*> ext_gf; ///< Not owned
Array<double (*)(const Vector &)> ext_sfn; ///< Not owned
Array<double (*)(const Vector &, double)> ext_stfn; ///< Not owned
Array<void (*)(const Vector &, Vector &)> ext_vfn; ///< Not owned
Array<void (*)(const Vector &, double, Vector &)> ext_vtfn; ///< Not owned
Array<void (*)(const Vector &, DenseMatrix &)> ext_mfn; ///< Not owned
Array<void (*)(const Vector &, double, DenseMatrix &)> ext_mtfn;
public:
CoefFactory() {}
virtual ~CoefFactory();
int AddExternalGridFunction(GridFunction &gf) { return ext_gf.Append(&gf); }
int AddExternalFunction(double (*fn)(const Vector &))
{ return ext_sfn.Append(fn); }
int AddExternalFunction(double (*fn)(const Vector &, double))
{ return ext_stfn.Append(fn); }
int AddExternalFunction(void (*fn)(const Vector &, Vector &))
{ return ext_vfn.Append(fn); }
int AddExternalFunction(void (*fn)(const Vector &, double, Vector &))
{ return ext_vtfn.Append(fn); }
int AddExternalFunction(void (*fn)(const Vector &, DenseMatrix &))
{ return ext_mfn.Append(fn); }
int AddExternalFunction(void (*fn)(const Vector &, double, DenseMatrix &))
{ return ext_mtfn.Append(fn); }
virtual Coefficient * GetScalarCoef(std::istream &input);
virtual Coefficient * GetScalarCoef(std::string &coef_name,
std::istream &input);
virtual VectorCoefficient * GetVectorCoef(std::istream &input);
virtual VectorCoefficient * GetVectorCoef(std::string &coef_name,
std::istream &input);
virtual MatrixCoefficient * GetMatrixCoef(std::istream &input);
virtual MatrixCoefficient * GetMatrixCoef(std::string &coef_name,
std::istream &input);
};
/// Visualize the given mesh object, using a GLVis server on the
/// specified host and port. Set the visualization window title, and optionally,
/// its geometry.
+5
View File
@@ -14,6 +14,11 @@ add_mfem_miniapp(display-basis
${MFEM_MINIAPPS_COMMON_HEADERS}
LIBRARIES mfem mfem-common)
add_mfem_miniapp(coef-fact
MAIN coef-fact.cpp
${MFEM_MINIAPPS_COMMON_HEADERS}
LIBRARIES mfem mfem-common)
add_mfem_miniapp(get-values
MAIN get-values.cpp
${MFEM_MINIAPPS_COMMON_HEADERS}
+234
View File
@@ -0,0 +1,234 @@
// Copyright (c) 2010-2020, Lawrence Livermore National Security, LLC. Produced
// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
// LICENSE and NOTICE for details. LLNL-CODE-806117.
//
// This file is part of the MFEM library. For more information and source code
// availability visit https://mfem.org.
//
// MFEM is free software; you can redistribute it and/or modify it under the
// terms of the BSD-3 license. We welcome feedback and contributions, see file
// CONTRIBUTING.md for details.
//
// -------------------------------------------------------------------
// Coef Fact Miniapp: Visualize Coefficient fields
// -------------------------------------------------------------------
//
// ./coef-fact
// ./coef-fact -c coef-fact.inp
//
#include "mfem.hpp"
#include "../common/fem_extras.hpp"
#include "../../general/text.hpp"
using namespace std;
using namespace mfem;
using namespace mfem::common;
double MyScalarFunc(const Vector &x)
{
return x * x;
}
void MyVectorFunc(const Vector &x, Vector &v)
{
v.SetSize(x.Size());
v.Set(-2.0, x);
}
class MyCoefficient : public Coefficient
{
private:
Vector k;
mutable Vector x;
public:
MyCoefficient(const Vector & _k) : k(_k), x(_k.Size()) {}
double Eval(ElementTransformation &T, const IntegrationPoint &ip)
{ T.Transform(ip, x); return sin(k * x); }
};
class MyVectorCoefficient : public VectorCoefficient
{
private:
double a;
Vector b;
mutable Vector x;
public:
MyVectorCoefficient(double _a, const Vector & _b)
: VectorCoefficient(_b.Size()), a(_a), b(_b), x(_b.Size()) {}
void Eval(Vector & v, ElementTransformation &T, const IntegrationPoint &ip)
{ T.Transform(ip, x); v = b; v.Add(a, x); }
};
class MyCoefFactory : public CoefFactory
{
public:
MyCoefFactory() {}
using CoefFactory::GetScalarCoef;
using CoefFactory::GetVectorCoef;
using CoefFactory::GetMatrixCoef;
Coefficient * GetScalarCoef(string &name, istream &input)
{
int c = -1;
if (name == "MyCoefficient")
{
int dim;
input >> dim;
MFEM_VERIFY(dim >=1 && dim <= 3,
"Invalid dimension for MyCoefficient "
"read by MyCoefFactory");
Vector val(dim);
for (int i=0; i<dim; i++) { input >> val[i]; }
c = sCoefs.Append(new MyCoefficient(val));
}
else
{
return CoefFactory::GetScalarCoef(name, input);
}
return sCoefs[--c];
}
VectorCoefficient * GetVectorCoef(string &name, istream &input)
{
int c = -1;
if (name == "MyVectorCoefficient")
{
int dim;
input >> dim;
MFEM_VERIFY(dim >=1 && dim <= 3,
"Invalid dimension for MyVectorCoefficient "
"read by MyCoefFactory");
double a;
input >> a;
Vector val(dim);
for (int i=0; i<dim; i++) { input >> val[i]; }
c = vCoefs.Append(new MyVectorCoefficient(a, val));
}
else
{
return CoefFactory::GetVectorCoef(name, input);
}
return vCoefs[--c];
}
};
const char coef_str[] =
"scalar_coef\nConstantCoefficient\n3.14\nvector_coef\nVectorConstantCoefficient\n2 2.0 1.0\nscalar_coef\nFunctionCoefficient\n0 0\nvector_coef\nVectorFunctionCoefficient\n2 0 0\nscalar_coef\nMyCoefficient\n2 2.0 1.0\nvector_coef\nMyVectorCoefficient\n2 3.0 2.0 1.0\n";
int main(int argc, char *argv[])
{
#ifdef MFEM_USE_MPI
MPI_Session mpi;
if (!mpi.Root()) { mfem::out.Disable(); mfem::err.Disable(); }
#endif
// Parse command-line options.
const char *mesh_file = "../../data/star.mesh";
const char *coef_file = "";
int order = 1;
bool visualization = true;
OptionsParser args(argc, argv);
args.AddOption(&mesh_file, "-m", "--mesh",
"Mesh file to use.");
args.AddOption(&coef_file, "-c", "--coef-file",
"Set the coefficient file name.");
args.AddOption(&order, "-o", "--order",
"Finite element order (polynomial degree).");
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
"--no-visualization",
"Enable or disable GLVis visualization.");
args.Parse();
if (!args.Good())
{
args.PrintUsage(mfem::out);
return 1;
}
args.PrintOptions(mfem::out);
// 4. Read the (serial) mesh from the given mesh file on all processors. 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();
// 5. Refine the serial mesh on all processors 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 10,000 elements.
{
int ref_levels =
(int)floor(log(10000./mesh.GetNE())/log(2.)/dim);
for (int l = 0; l < ref_levels; l++)
{
mesh.UniformRefinement();
}
}
H1_FESpace fespace_h1(&mesh, order, mesh.Dimension());
ND_FESpace fespace_nd(&mesh, order, mesh.Dimension());
GridFunction sgf(&fespace_h1);
GridFunction vgf(&fespace_nd);
MyCoefFactory coefFact;
coefFact.AddExternalFunction(MyScalarFunc);
coefFact.AddExternalFunction(MyVectorFunc);
istream * iss = NULL;
if (strncmp(coef_file,"",1) != 0)
{
iss = new ifstream(coef_file);
}
else
{
iss = new istringstream(coef_str);
}
skip_comment_lines(*iss, '#');
char vishost[] = "localhost";
int visport = 19916;
socketstream s_sock, v_sock;
string buff;
while (*iss >> buff)
{
if (buff == "scalar_coef")
{
Coefficient * sc = coefFact.GetScalarCoef(*iss);
sgf.ProjectCoefficient(*sc);
if (visualization)
{
VisualizeField(s_sock, vishost, visport, sgf, "Scalar Coef",
0, 0, 275, 250);
}
}
else if (buff == "vector_coef")
{
VectorCoefficient * vc = coefFact.GetVectorCoef(*iss);
vgf.ProjectCoefficient(*vc);
if (visualization)
{
VisualizeField(v_sock, vishost, visport, vgf, "Vector Coef",
275 + 3, 0, 275, 250);
}
}
skip_comment_lines(*iss, '#');
char c;
cout << "press (q)uit or (c)ontinue --> " << flush;
cin >> c;
if (c != 'c')
{
break;
}
}
return 0;
}
+53
View File
@@ -0,0 +1,53 @@
##############################################################################
# For the ConstantCoefficient the argument is the constant value
##############################################################################
scalar_coef
ConstantCoefficient
3.14
vector_coef
##############################################################################
# For the VectorConstantCoefficient the arguments are the dimension of the
# vector and it components.
##############################################################################
VectorConstantCoefficient
2 2.0 1.0
scalar_coef
##############################################################################
# For the FunctionCoefficient the first integer specifies the type of
# constructor to be used (based on a simple function of position in this case)
# and the second is the index into an array of simple functions provided
# in the calling application via CoefFactory::AddExternalFunction.
##############################################################################
FunctionCoefficient
0 0
vector_coef
##############################################################################
# For the VectorFunctionCoefficient the first integer argument is the
# dimension of the vector and the second specifies the type of
# constructor to be used (based on a simple function of position in this case)
# and the second is the index into an array of simple vector-valued functions
# provided in the calling application via CoefFactory::AddExternalFunction.
##############################################################################
VectorFunctionCoefficient
2 0 0
scalar_coef
##############################################################################
# Application specific (or user supplied) Coefficients can be added by
# implementing a Factory class which derives from CoefFactory and recognizes
# the new Coefficient types.
##############################################################################
MyCoefficient
2 2.0 1.0
vector_coef
##############################################################################
# Application specific (or user supplied) VectorCoefficients can be added by
# implementing a Factory class which derives from CoefFactory and recognizes
# the new VectorCoefficient types.
##############################################################################
MyVectorCoefficient
2 3.0 2.0 1.0
+7 -3
View File
@@ -25,7 +25,7 @@ include $(DEFAULTS_MK)
MFEM_LIB_FILE = mfem_is_not_built
-include $(CONFIG_MK)
SEQ_MINIAPPS = display-basis load-dc convert-dc get-values lor-transfer
SEQ_MINIAPPS = display-basis load-dc coef-fact convert-dc get-values lor-transfer
PAR_MINIAPPS =
ifeq ($(MFEM_USE_MPI),NO)
MINIAPPS = $(SEQ_MINIAPPS)
@@ -60,6 +60,10 @@ display-basis: %: $(SRC)%.cpp $(MFEM_LIB_FILE) $(CONFIG_MK) | lib-common
$(MFEM_CXX) $(MFEM_FLAGS) -c $(<)
$(MFEM_CXX) $(MFEM_LINK_FLAGS) -o $@ $@.o $(COMMON_LIB) $(MFEM_LIBS)
coef-fact: %: $(SRC)%.cpp $(MFEM_LIB_FILE) $(CONFIG_MK) | lib-common
$(MFEM_CXX) $(MFEM_FLAGS) -c $(<)
$(MFEM_CXX) $(MFEM_LINK_FLAGS) -o $@ $@.o $(COMMON_LIB) $(MFEM_LIBS)
# Rule for building lib-common
lib-common:
$(MAKE) -C $(MFEM_BUILD_DIR)/miniapps/common
@@ -75,8 +79,8 @@ RUN_MPI = $(MFEM_MPIEXEC) $(MFEM_MPIEXEC_NP) $(MFEM_MPI_NP)
@$(call mfem-test,$<,, Tools miniapp)
# Testing: Specific execution options
# Do not test: display-basis, load-dc, convert-dc, get-values, lor-transfer
NO_TEST_APPS = display-basis load-dc convert-dc get-values lor-transfer
# Do not test: display-basis, load-dc, coef-fact, convert-dc, get-values, lor-transfer
NO_TEST_APPS = display-basis load-dc coef-fact convert-dc get-values lor-transfer
$(foreach app,$(NO_TEST_APPS),$(app)-test-seq $(app)-test-par):
@true