mirror of
https://github.com/NGSolve/netgen.git
synced 2025-05-12 05:30:49 +05:00

Current initialization of the global geometryregister suffers from a classic 'initialization order fiasco'. Depending on the order the compilation units are loaded/linked, the initialization of the global geometryregisterarray is not guaranteed to happen (and indeed often does not happen) before it is used. This leads to entries being appended before it's initialized (usually 'suceeding, but potentially causing memory corruption if the segment at that point isn't zeroed), initialization then happening halfway through (wiping the initial entries) and then the last entries being the only ones that show up. The net effect is either a crash at startup, or several geometry types seeming to be missing. Eg, step files will oad, but STL files are just ignored. The bug is actively observed on, eg, Linux. This patch implements a simple 'initialize at first access' convention for the array, eliminating the ordering problem. I've not reviewed the rest of the source for other potential examples of the fiasco pattern; this fixes only the geometryregister, since that was actively biting.
1112 lines
25 KiB
C++
1112 lines
25 KiB
C++
/*
|
|
|
|
2d Spline curve for Mesh generator
|
|
|
|
*/
|
|
|
|
#include <meshing.hpp>
|
|
#include <geometry2d.hpp>
|
|
#include <core/register_archive.hpp>
|
|
|
|
namespace netgen
|
|
{
|
|
|
|
|
|
|
|
SplineGeometry2d :: ~SplineGeometry2d()
|
|
{
|
|
for ( int i = 0; i < bcnames.Size(); i++ )
|
|
delete bcnames[i];
|
|
for (int i=0; i<materials.Size(); i++)
|
|
delete [] materials[i];
|
|
}
|
|
|
|
void SplineGeometry2d :: PointBetweenEdge(const Point<3> & p1, const Point<3> & p2, double secpoint,
|
|
int surfi1, int surfi2,
|
|
const EdgePointGeomInfo & ap1,
|
|
const EdgePointGeomInfo & ap2,
|
|
Point<3> & newp, EdgePointGeomInfo & newgi) const
|
|
{
|
|
Point<2> p2d;
|
|
double newdist;
|
|
auto spline = GetSplines().Get(ap1.edgenr);
|
|
if( (ap1.dist == 0.0) && (ap2.dist == 0.0) )
|
|
{
|
|
// used for manually generated meshes
|
|
const SplineSeg3<2> * ss3;
|
|
const LineSeg<2> * ls;
|
|
auto ext = dynamic_cast<const SplineSegExt *>(spline);
|
|
if(ext)
|
|
{
|
|
ss3 = dynamic_cast<const SplineSeg3<2> *>(ext->seg);
|
|
ls = dynamic_cast<const LineSeg<2> *>(ext->seg);
|
|
}
|
|
else
|
|
{
|
|
ss3 = dynamic_cast<const SplineSeg3<2> *>(spline);
|
|
ls = dynamic_cast<const LineSeg<2> *>(spline);
|
|
}
|
|
Point<2> p12d(p1(0),p1(1)), p22d(p2(0),p2(1));
|
|
Point<2> p1_proj(0.0,0.0), p2_proj(0.0,0.0);
|
|
double t1_proj = 0.0;
|
|
double t2_proj = 0.0;
|
|
if(ss3)
|
|
{
|
|
ss3->Project(p12d,p1_proj,t1_proj);
|
|
ss3->Project(p22d,p2_proj,t2_proj);
|
|
}
|
|
else if(ls)
|
|
{
|
|
ls->Project(p12d,p1_proj,t1_proj);
|
|
ls->Project(p22d,p2_proj,t2_proj);
|
|
}
|
|
p2d = spline->GetPoint (((1-secpoint)*t1_proj+secpoint*t2_proj));
|
|
newdist = (1-secpoint)*t1_proj+secpoint*t2_proj;
|
|
}
|
|
else
|
|
{
|
|
p2d = spline->GetPoint (((1-secpoint)*ap1.dist+secpoint*ap2.dist));
|
|
newdist = (1-secpoint)*ap1.dist+secpoint*ap2.dist;
|
|
}
|
|
|
|
// (*testout) << "refine 2d line, ap1.dist, ap2.dist = " << ap1.dist << ", " << ap2.dist << endl;
|
|
// (*testout) << "p1, p2 = " << p1 << p2 << ", newp = " << p2d << endl;
|
|
|
|
newp = Point3d (p2d(0), p2d(1), 0);
|
|
newgi.edgenr = ap1.edgenr;
|
|
newgi.dist = newdist;
|
|
};
|
|
|
|
|
|
|
|
Vec<3> SplineGeometry2d :: GetTangent(const Point<3> & p, int surfi1, int surfi2,
|
|
const EdgePointGeomInfo & ap1) const
|
|
{
|
|
Vec<2> t2d = GetSplines().Get(ap1.edgenr) -> GetTangent(ap1.dist);
|
|
return Vec<3> (t2d(0), t2d(1), 0);
|
|
}
|
|
|
|
Vec<3> SplineGeometry2d :: GetNormal(int surfi1, const Point<3> & p,
|
|
const PointGeomInfo* gi) const
|
|
{
|
|
return Vec<3> (0,0,1);
|
|
}
|
|
|
|
void SplineGeometry2d :: Load (const filesystem::path & filename)
|
|
{
|
|
|
|
ifstream infile;
|
|
Point<2> x;
|
|
char buf[50];
|
|
|
|
|
|
infile.open (filename);
|
|
|
|
if ( ! infile.good() )
|
|
throw NgException(string ("Input file '") +
|
|
filename.string() +
|
|
string ("' not available!"));
|
|
|
|
TestComment ( infile );
|
|
|
|
infile >> buf; // file recognition
|
|
|
|
tensormeshing.SetSize(0);
|
|
quadmeshing.SetSize(0);
|
|
|
|
TestComment ( infile );
|
|
if ( strcmp (buf, "splinecurves2dnew") == 0 )
|
|
{
|
|
LoadDataNew ( infile );
|
|
}
|
|
else if ( strcmp (buf, "splinecurves2dv2") == 0 )
|
|
{
|
|
LoadDataV2 ( infile );
|
|
}
|
|
else
|
|
{
|
|
LoadData(infile );
|
|
}
|
|
infile.close();
|
|
}
|
|
|
|
|
|
|
|
// herbert: fixed TestComment
|
|
void SplineGeometry2d :: TestComment ( ifstream & infile )
|
|
{
|
|
bool comment = true;
|
|
char ch;
|
|
while ( comment == true && !infile.eof() ) {
|
|
infile.get(ch);
|
|
if ( ch == '#' ) { // skip comments
|
|
while ( ch != '\n' && !infile.eof() ) {
|
|
infile.get(ch);
|
|
}
|
|
}
|
|
else if ( ch == '\n' ) { // skip empty lines
|
|
;
|
|
}
|
|
else if ( isspace(ch) ) { // skip whitespaces
|
|
;
|
|
}
|
|
else { // end of comment
|
|
infile.putback(ch);
|
|
comment = false;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
void SplineGeometry2d :: LoadData ( ifstream & infile )
|
|
{
|
|
enum { D = 2 };
|
|
|
|
int nump, numseg, leftdom, rightdom;
|
|
Point<D> x;
|
|
int hi1, hi2, hi3;
|
|
double hd;
|
|
char buf[50], ch;
|
|
|
|
materials.SetSize(0);
|
|
maxh.SetSize(0);
|
|
infile >> elto0;
|
|
|
|
TestComment ( infile );
|
|
|
|
infile >> nump;
|
|
for (int i = 0; i < nump; i++)
|
|
{
|
|
TestComment ( infile );
|
|
for(int j=0; j<D; j++)
|
|
infile >> x(j);
|
|
infile >> hd;
|
|
|
|
Flags flags;
|
|
|
|
ch = 'a';
|
|
// infile >> ch;
|
|
do {
|
|
infile.get (ch);
|
|
} while (isspace(ch) && ch != '\n');
|
|
while (ch == '-')
|
|
{
|
|
char flag[100];
|
|
flag[0]='-';
|
|
infile >> (flag+1);
|
|
flags.SetCommandLineFlag (flag);
|
|
ch = 'a';
|
|
do {
|
|
infile.get (ch);
|
|
} while (isspace(ch) && ch != '\n');
|
|
}
|
|
|
|
if (infile.good())
|
|
infile.putback (ch);
|
|
|
|
geompoints.Append (GeomPoint<D>(x, hd));
|
|
geompoints.Last().hpref = flags.GetDefineFlag ("hpref");
|
|
geompoints.Last().hmax = flags.GetNumFlag("hmax", 1e99);
|
|
}
|
|
|
|
PrintMessage (3, nump, " points loaded");
|
|
TestComment ( infile );
|
|
|
|
infile >> numseg;
|
|
bcnames.SetSize(numseg);
|
|
for ( int i = 0; i < numseg; i++ )
|
|
bcnames[i] = 0; // "default";
|
|
|
|
SplineSeg<D> * spline = 0;
|
|
|
|
PrintMessage (3, numseg, " segments loaded");
|
|
for (int i = 0; i < numseg; i++)
|
|
{
|
|
TestComment ( infile );
|
|
|
|
infile >> leftdom >> rightdom;
|
|
|
|
// cout << "add spline " << i << ", left = " << leftdom << ", right = " << rightdom << endl;
|
|
|
|
infile >> buf;
|
|
// type of spline segment
|
|
if (strcmp (buf, "2") == 0)
|
|
{ // a line
|
|
infile >> hi1 >> hi2;
|
|
spline = new LineSeg<D>(geompoints[hi1-1],
|
|
geompoints[hi2-1]);
|
|
}
|
|
else if (strcmp (buf, "3") == 0)
|
|
{ // a rational spline
|
|
infile >> hi1 >> hi2 >> hi3;
|
|
spline = new SplineSeg3<D> (geompoints[hi1-1],
|
|
geompoints[hi2-1],
|
|
geompoints[hi3-1]);
|
|
}
|
|
else if (strcmp (buf, "4") == 0)
|
|
{ // an arc
|
|
infile >> hi1 >> hi2 >> hi3;
|
|
spline = new CircleSeg<D> (geompoints[hi1-1],
|
|
geompoints[hi2-1],
|
|
geompoints[hi3-1]);
|
|
// break;
|
|
}
|
|
else if (strcmp (buf, "discretepoints") == 0)
|
|
{
|
|
int npts;
|
|
infile >> npts;
|
|
NgArray< Point<D> > pts(npts);
|
|
for (int j = 0; j < npts; j++)
|
|
for(int k=0; k<D; k++)
|
|
infile >> pts[j](k);
|
|
|
|
spline = new DiscretePointsSeg<D> (pts);
|
|
}
|
|
|
|
|
|
SplineSegExt * spex = new SplineSegExt (*spline);
|
|
|
|
infile >> spex->reffak;
|
|
spex -> leftdom = leftdom;
|
|
spex -> rightdom = rightdom;
|
|
splines.Append (spex);
|
|
|
|
|
|
Flags flags;
|
|
ch = 'a';
|
|
infile >> ch;
|
|
while (ch == '-')
|
|
{
|
|
char flag[100];
|
|
flag[0]='-';
|
|
infile >> (flag+1);
|
|
flags.SetCommandLineFlag (flag);
|
|
ch = 'a';
|
|
infile >> ch;
|
|
}
|
|
|
|
if (infile.good())
|
|
infile.putback (ch);
|
|
|
|
spex->bc = int (flags.GetNumFlag ("bc", i+1));
|
|
spex->hpref_left = int (flags.GetDefineFlag ("hpref")) ||
|
|
int (flags.GetDefineFlag ("hprefleft"));
|
|
spex->hpref_right = int (flags.GetDefineFlag ("hpref")) ||
|
|
int (flags.GetDefineFlag ("hprefright"));
|
|
spex->copyfrom = int (flags.GetNumFlag ("copy", -1));
|
|
if ( flags.StringFlagDefined("bcname") )
|
|
{
|
|
int mybc = spex->bc-1;
|
|
delete bcnames[mybc];
|
|
bcnames[mybc] = new string (flags.GetStringFlag("bcname","") );
|
|
}
|
|
spex -> hmax = flags.GetNumFlag("hmax", 1e99);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void SplineGeometry2d :: LoadDataNew ( ifstream & infile )
|
|
{
|
|
enum { D = 2 };
|
|
int nump, numseg, leftdom, rightdom;
|
|
Point<D> x;
|
|
int hi1, hi2, hi3;
|
|
double hd;
|
|
char buf[50], ch;
|
|
int pointnr;
|
|
|
|
|
|
TestComment ( infile );
|
|
infile >> elto0;
|
|
TestComment ( infile );
|
|
|
|
infile >> nump;
|
|
geompoints.SetSize(nump);
|
|
|
|
for (int i = 0; i < nump; i++)
|
|
{
|
|
TestComment ( infile );
|
|
infile >> pointnr;
|
|
if ( pointnr > nump )
|
|
{
|
|
throw NgException(string ("Point number greater than total number of points") );
|
|
}
|
|
for(int j=0; j<D; j++)
|
|
infile >> x(j);
|
|
|
|
|
|
// hd is now optional, default 1
|
|
// infile >> hd;
|
|
hd = 1;
|
|
|
|
Flags flags;
|
|
|
|
|
|
// get flags,
|
|
ch = 'a';
|
|
// infile >> ch;
|
|
do
|
|
{
|
|
|
|
infile.get (ch);
|
|
// if another int-value, set refinement flag to this value
|
|
// (corresponding to old files)
|
|
if ( int (ch) >= 48 && int(ch) <= 57 )
|
|
{
|
|
infile.putback(ch);
|
|
infile >> hd;
|
|
infile.get(ch);
|
|
}
|
|
}
|
|
while (isspace(ch) && ch != '\n');
|
|
while (ch == '-')
|
|
{
|
|
char flag[100];
|
|
flag[0]='-';
|
|
infile >> (flag+1);
|
|
flags.SetCommandLineFlag (flag);
|
|
ch = 'a';
|
|
do {
|
|
infile.get (ch);
|
|
} while (isspace(ch) && ch != '\n');
|
|
}
|
|
|
|
if (infile.good())
|
|
infile.putback (ch);
|
|
|
|
if ( hd == 1 )
|
|
hd = flags.GetNumFlag ( "ref", 1.0);
|
|
// geompoints.Append (GeomPoint<D>(x, hd));
|
|
geompoints[pointnr-1] = GeomPoint<D>(x, hd);
|
|
geompoints[pointnr-1].hpref = flags.GetDefineFlag ("hpref");
|
|
}
|
|
|
|
TestComment ( infile );
|
|
|
|
infile >> numseg;
|
|
bcnames.SetSize(numseg);
|
|
for ( int i = 0; i < numseg; i++ )
|
|
bcnames[i] = 0;//new"default";
|
|
|
|
SplineSeg<D> * spline = 0;
|
|
for (int i = 0; i < numseg; i++)
|
|
{
|
|
TestComment ( infile );
|
|
|
|
infile >> leftdom >> rightdom;
|
|
|
|
// cout << "add spline " << i << ", left = " << leftdom << endl;
|
|
|
|
infile >> buf;
|
|
// type of spline segment
|
|
if (strcmp (buf, "2") == 0)
|
|
{ // a line
|
|
infile >> hi1 >> hi2;
|
|
spline = new LineSeg<D> (geompoints[hi1-1],
|
|
geompoints[hi2-1]);
|
|
}
|
|
else if (strcmp (buf, "3") == 0)
|
|
{ // a rational spline
|
|
infile >> hi1 >> hi2 >> hi3;
|
|
spline = new SplineSeg3<D> (geompoints[hi1-1],
|
|
geompoints[hi2-1],
|
|
geompoints[hi3-1]);
|
|
}
|
|
else if (strcmp (buf, "4") == 0)
|
|
{ // an arc
|
|
infile >> hi1 >> hi2 >> hi3;
|
|
spline = new CircleSeg<D> (geompoints[hi1-1],
|
|
geompoints[hi2-1],
|
|
geompoints[hi3-1]);
|
|
// break;
|
|
}
|
|
else if (strcmp (buf, "discretepoints") == 0)
|
|
{
|
|
int npts;
|
|
infile >> npts;
|
|
NgArray< Point<D> > pts(npts);
|
|
for (int j = 0; j < npts; j++)
|
|
for(int k=0; k<D; k++)
|
|
infile >> pts[j](k);
|
|
|
|
spline = new DiscretePointsSeg<D> (pts);
|
|
}
|
|
|
|
// infile >> spline->reffak;
|
|
|
|
SplineSegExt * spex = new SplineSegExt (*spline);
|
|
|
|
spex -> leftdom = leftdom;
|
|
spex -> rightdom = rightdom;
|
|
splines.Append (spex);
|
|
|
|
// hd is now optional, default 1
|
|
// infile >> hd;
|
|
hd = 1;
|
|
infile >> ch;
|
|
|
|
// get refinement parameter, if it is there
|
|
// infile.get (ch);
|
|
// if another int-value, set refinement flag to this value
|
|
// (corresponding to old files)
|
|
if ( int (ch) >= 48 && int(ch) <= 57 )
|
|
{
|
|
infile.putback(ch);
|
|
infile >> hd;
|
|
infile >> ch ;
|
|
}
|
|
|
|
Flags flags;
|
|
while (ch == '-')
|
|
{
|
|
char flag[100];
|
|
flag[0]='-';
|
|
infile >> (flag+1);
|
|
flags.SetCommandLineFlag (flag);
|
|
ch = 'a';
|
|
infile >> ch;
|
|
}
|
|
|
|
if (infile.good())
|
|
infile.putback (ch);
|
|
|
|
spex->bc = int (flags.GetNumFlag ("bc", i+1));
|
|
spex->hpref_left = int (flags.GetDefineFlag ("hpref")) ||
|
|
int (flags.GetDefineFlag ("hprefleft"));
|
|
spex->hpref_right = int (flags.GetDefineFlag ("hpref")) ||
|
|
int (flags.GetDefineFlag ("hprefright"));
|
|
spex->copyfrom = int (flags.GetNumFlag ("copy", -1));
|
|
spex->reffak = flags.GetNumFlag ("ref", 1 );
|
|
spex->hmax = flags.GetNumFlag ("maxh", 1e99 );
|
|
|
|
if ( flags.StringFlagDefined("bcname") )
|
|
{
|
|
int mybc = spex->bc-1;
|
|
if ( bcnames[mybc] ) delete bcnames[mybc];
|
|
bcnames[mybc] = new string (flags.GetStringFlag("bcname","") );
|
|
}
|
|
|
|
if ( hd != 1 )
|
|
spex->reffak = hd;
|
|
}
|
|
if ( !infile.good() )
|
|
return;
|
|
TestComment ( infile );
|
|
int numdomains;
|
|
int domainnr;
|
|
char material[100];
|
|
|
|
if ( !infile.good() )
|
|
return;
|
|
|
|
infile >> numdomains;
|
|
materials.SetSize(numdomains) ;
|
|
maxh.SetSize ( numdomains ) ;
|
|
maxh = 1e99;
|
|
|
|
TestComment ( infile );
|
|
|
|
for ( int i=0; i<numdomains; i++)
|
|
materials [ i ] = new char (100);
|
|
|
|
for ( int i=0; i<numdomains && infile.good(); i++)
|
|
{
|
|
TestComment ( infile );
|
|
infile >> domainnr;
|
|
infile >> material;
|
|
strcpy(materials[domainnr-1], material);
|
|
|
|
Flags flags;
|
|
ch = 'a';
|
|
infile >> ch;
|
|
while (ch == '-')
|
|
{
|
|
char flag[100];
|
|
flag[0]='-';
|
|
infile >> (flag+1);
|
|
flags.SetCommandLineFlag (flag);
|
|
ch = 'a';
|
|
infile >> ch;
|
|
}
|
|
|
|
if (infile.good())
|
|
infile.putback (ch);
|
|
|
|
maxh[domainnr-1] = flags.GetNumFlag ( "maxh", 1e99);
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
void SplineGeometry2d :: LoadDataV2 ( ifstream & infile )
|
|
{
|
|
enum { D = 2 };
|
|
// new parser by Astrid Sinwel
|
|
|
|
PrintMessage (1, "Load 2D Geometry V2");
|
|
int nump, leftdom, rightdom;
|
|
Point<D> x;
|
|
int hi1, hi2, hi3;
|
|
double hd;
|
|
char buf[50], ch;
|
|
int pointnr;
|
|
|
|
string keyword;
|
|
|
|
NgArray < GeomPoint<D> > infilepoints (0);
|
|
NgArray <int> pointnrs (0);
|
|
nump = 0;
|
|
int numdomains = 0;
|
|
|
|
|
|
TestComment ( infile );
|
|
// refinement factor
|
|
infile >> elto0;
|
|
TestComment ( infile );
|
|
|
|
|
|
// test if next ch is a letter, i.e. new keyword starts
|
|
bool ischar = false;
|
|
|
|
while ( infile.good() )
|
|
{
|
|
infile >> keyword;
|
|
|
|
ischar = false;
|
|
|
|
if ( keyword == "points" )
|
|
{
|
|
PrintMessage (3, "load points");
|
|
infile.get(ch);
|
|
infile.putback(ch);
|
|
|
|
// test if ch is a letter
|
|
if ( int(ch) >= 65 && int(ch) <=90 )
|
|
ischar = true;
|
|
if ( int(ch) >= 97 && int(ch) <= 122 )
|
|
ischar = true;
|
|
|
|
while ( ! ischar )
|
|
{
|
|
TestComment ( infile );
|
|
infile >> pointnr;
|
|
// pointnrs 1-based
|
|
if ( pointnr > nump ) nump = pointnr;
|
|
pointnrs.Append(pointnr);
|
|
|
|
for(int j=0; j<D; j++)
|
|
infile >> x(j);
|
|
// hd is now optional, default 1
|
|
// infile >> hd;
|
|
hd = 1;
|
|
|
|
Flags flags;
|
|
|
|
|
|
// get flags,
|
|
ch = 'a';
|
|
// infile >> ch;
|
|
do
|
|
{
|
|
infile.get (ch);
|
|
// if another int-value, set refinement flag to this value
|
|
// (corresponding to old files)
|
|
if ( int (ch) >= 48 && int(ch) <= 57 )
|
|
{
|
|
infile.putback(ch);
|
|
infile >> hd;
|
|
infile.get(ch);
|
|
}
|
|
}
|
|
while (isspace(ch) && ch != '\n');
|
|
while (ch == '-')
|
|
{
|
|
char flag[100];
|
|
flag[0]='-';
|
|
infile >> (flag+1);
|
|
flags.SetCommandLineFlag (flag);
|
|
ch = 'a';
|
|
do {
|
|
infile.get (ch);
|
|
} while (isspace(ch) && ch != '\n');
|
|
}
|
|
if (infile.good())
|
|
infile.putback (ch);
|
|
|
|
if ( hd == 1 )
|
|
hd = flags.GetNumFlag ( "ref", 1.0);
|
|
// geompoints.Append (GeomPoint<D>(x, hd));
|
|
|
|
infilepoints.Append ( GeomPoint<D>(x, hd) );
|
|
infilepoints.Last().hpref = flags.GetDefineFlag ("hpref");
|
|
infilepoints.Last().hmax = flags.GetNumFlag ("maxh", 1e99);
|
|
|
|
TestComment(infile);
|
|
infile.get(ch);
|
|
infile.putback(ch);
|
|
|
|
// test if letter
|
|
if ( int(ch) >= 65 && int(ch) <=90 )
|
|
ischar = true;
|
|
if ( int(ch) >= 97 && int(ch) <= 122 )
|
|
ischar = true;
|
|
}
|
|
|
|
// infile.putback (ch);
|
|
|
|
geompoints.SetSize(nump);
|
|
for ( int i = 0; i < nump; i++ )
|
|
{
|
|
geompoints[pointnrs[i] - 1] = infilepoints[i];
|
|
geompoints[pointnrs[i] - 1].hpref = infilepoints[i].hpref;
|
|
}
|
|
TestComment(infile);
|
|
}
|
|
|
|
else if ( keyword == "segments" )
|
|
{
|
|
PrintMessage (3, "load segments");
|
|
|
|
bcnames.SetSize(0);
|
|
infile.get(ch);
|
|
infile.putback(ch);
|
|
int i = 0;
|
|
|
|
// test if ch is a letter
|
|
if ( int(ch) >= 65 && int(ch) <=90 )
|
|
ischar = true;
|
|
if ( int(ch) >= 97 && int(ch) <= 122 )
|
|
ischar = true;
|
|
|
|
while ( !ischar ) //ch != 'p' && ch != 'm' )
|
|
{
|
|
i++;
|
|
TestComment ( infile );
|
|
|
|
SplineSeg<D> * spline = 0;
|
|
TestComment ( infile );
|
|
|
|
infile >> leftdom >> rightdom;
|
|
|
|
if ( leftdom > numdomains ) numdomains = leftdom;
|
|
if ( rightdom > numdomains ) numdomains = rightdom;
|
|
|
|
|
|
infile >> buf;
|
|
// type of spline segment
|
|
if (strcmp (buf, "2") == 0)
|
|
{ // a line
|
|
infile >> hi1 >> hi2;
|
|
spline = new LineSeg<D>(geompoints[hi1-1],
|
|
geompoints[hi2-1]);
|
|
}
|
|
else if (strcmp (buf, "3") == 0)
|
|
{ // a rational spline
|
|
infile >> hi1 >> hi2 >> hi3;
|
|
spline = new SplineSeg3<D> (geompoints[hi1-1],
|
|
geompoints[hi2-1],
|
|
geompoints[hi3-1]);
|
|
}
|
|
else if (strcmp (buf, "4") == 0)
|
|
{ // an arc
|
|
infile >> hi1 >> hi2 >> hi3;
|
|
spline = new CircleSeg<D> (geompoints[hi1-1],
|
|
geompoints[hi2-1],
|
|
geompoints[hi3-1]);
|
|
}
|
|
else if (strcmp (buf, "discretepoints") == 0)
|
|
{
|
|
int npts;
|
|
infile >> npts;
|
|
NgArray< Point<D> > pts(npts);
|
|
for (int j = 0; j < npts; j++)
|
|
for(int k=0; k<D; k++)
|
|
infile >> pts[j](k);
|
|
|
|
spline = new DiscretePointsSeg<D> (pts);
|
|
}
|
|
else if (strcmp (buf, "bsplinepoints") == 0)
|
|
{
|
|
int npts,order;
|
|
infile >> npts;
|
|
infile >> order;
|
|
NgArray< Point<D> > pts(npts);
|
|
for (int j = 0; j < npts; j++)
|
|
for(int k=0; k<D; k++)
|
|
infile >> pts[j](k);
|
|
if(order<2)
|
|
cerr<<"Minimum order of 2 is required!!"<<endl;
|
|
else if(order==2)
|
|
spline = new BSplineSeg<D,2> (pts);
|
|
else if(order==3)
|
|
spline = new BSplineSeg<D,3> (pts);
|
|
else if(order==4)
|
|
spline = new BSplineSeg<D,4> (pts);
|
|
else if(order>4)
|
|
cerr<<"Maximum allowed order is 4!!"<<endl;
|
|
}
|
|
|
|
// infile >> spline->reffak;
|
|
SplineSegExt * spex = new SplineSegExt (*spline);
|
|
|
|
spex -> leftdom = leftdom;
|
|
spex -> rightdom = rightdom;
|
|
splines.Append (spex);
|
|
|
|
|
|
// hd is now optional, default 1
|
|
// infile >> hd;
|
|
hd = 1;
|
|
|
|
infile >> ch;
|
|
|
|
// get refinement parameter, if it is there
|
|
//infile.get (ch);
|
|
// if another int-value, set refinement flag to this value
|
|
// (corresponding to old files)
|
|
/*
|
|
if ( int (ch) >= 48 && int(ch) <= 57 )
|
|
{
|
|
infile.putback(ch);
|
|
infile >> hd;
|
|
infile >> ch ;
|
|
}
|
|
*/
|
|
// get flags,
|
|
Flags flags;
|
|
while (ch == '-')
|
|
{
|
|
char flag[100];
|
|
flag[0]='-';
|
|
infile >> (flag+1);
|
|
flags.SetCommandLineFlag (flag);
|
|
ch = 'a';
|
|
infile >> ch;
|
|
}
|
|
|
|
if (infile.good())
|
|
infile.putback (ch);
|
|
|
|
spex->bc = int (flags.GetNumFlag ("bc", i+1));
|
|
spex->hpref_left = int (flags.GetDefineFlag ("hpref")) ||
|
|
int (flags.GetDefineFlag ("hprefleft"));
|
|
spex->hpref_right = int (flags.GetDefineFlag ("hpref")) ||
|
|
int (flags.GetDefineFlag ("hprefright"));
|
|
spex->copyfrom = int (flags.GetNumFlag ("copy", -1));
|
|
spex->reffak = flags.GetNumFlag ("ref", 1 );
|
|
spex->hmax = flags.GetNumFlag ("maxh", 1e99 );
|
|
if ( hd != 1 ) spex->reffak = hd;
|
|
|
|
if ( flags.StringFlagDefined("bcname") )
|
|
{
|
|
int mybc = spex->bc-1;
|
|
for ( int ii = bcnames.Size(); ii <= mybc; ii++ )
|
|
bcnames.Append ( new string ("default"));
|
|
if ( bcnames[mybc] ) delete bcnames[mybc];
|
|
bcnames[mybc] = new string (flags.GetStringFlag("bcname","") );
|
|
}
|
|
|
|
TestComment(infile);
|
|
infile.get(ch);
|
|
infile.putback(ch);
|
|
|
|
// test if ch is a letter
|
|
if ( int(ch) >= 65 && int(ch) <=90 )
|
|
ischar = true;
|
|
if ( int(ch) >= 97 && int(ch) <= 122 )
|
|
ischar = true;
|
|
|
|
}
|
|
|
|
infile.get(ch);
|
|
infile.putback(ch);
|
|
|
|
|
|
}
|
|
else if ( keyword == "materials" )
|
|
{
|
|
TestComment ( infile );
|
|
int domainnr;
|
|
char material[100];
|
|
|
|
if ( !infile.good() )
|
|
return;
|
|
|
|
materials.SetSize(numdomains) ;
|
|
maxh.SetSize ( numdomains ) ;
|
|
for ( int i = 0; i < numdomains; i++)
|
|
maxh[i] = 1000;
|
|
quadmeshing.SetSize ( numdomains );
|
|
quadmeshing = false;
|
|
tensormeshing.SetSize ( numdomains );
|
|
tensormeshing = false;
|
|
layer.SetSize ( numdomains );
|
|
layer = 1;
|
|
|
|
|
|
TestComment ( infile );
|
|
|
|
for ( int i=0; i<numdomains; i++)
|
|
materials [ i ] = new char[100];
|
|
|
|
for ( int i=0; i<numdomains && infile.good(); i++)
|
|
{
|
|
TestComment ( infile );
|
|
infile >> domainnr;
|
|
infile >> material;
|
|
|
|
strcpy (materials[domainnr-1], material);
|
|
|
|
Flags flags;
|
|
ch = 'a';
|
|
infile >> ch;
|
|
while (ch == '-')
|
|
{
|
|
char flag[100];
|
|
flag[0]='-';
|
|
infile >> (flag+1);
|
|
flags.SetCommandLineFlag (flag);
|
|
ch = 'a';
|
|
infile >> ch;
|
|
}
|
|
|
|
if (infile.good())
|
|
infile.putback (ch);
|
|
|
|
maxh[domainnr-1] = flags.GetNumFlag ( "maxh", 1000);
|
|
if (flags.GetDefineFlag("quad")) quadmeshing[domainnr-1] = true;
|
|
if (flags.GetDefineFlag("tensor")) tensormeshing[domainnr-1] = true;
|
|
layer[domainnr-1] = int(flags.GetNumFlag ("layer", 1));
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
void CalcPartition (const SplineSegExt & spline,
|
|
double l, double h, double h1, double h2,
|
|
double hcurve, double elto0, NgArray<double> & points)
|
|
{
|
|
double fperel, oldf, f;
|
|
|
|
int n = 1000;
|
|
|
|
points.SetSize (0);
|
|
|
|
double dt = l / n;
|
|
|
|
double sum = 0;
|
|
for (int i = 1; i <= n; i++)
|
|
{
|
|
double t = (i-0.5)*dt;
|
|
double fun = min3 (hcurve, t/elto0 + h1, (l-t)/elto0 + h2);
|
|
double curv = spline.CalcCurvature (t/l);
|
|
cout << "curv = " << curv << endl;
|
|
if (curv < 1e-10) curv = 1e-10;
|
|
fun = min2 (fun, 0.1/curv);
|
|
sum += dt / fun;
|
|
}
|
|
|
|
int nel = int (sum+1);
|
|
fperel = sum / nel;
|
|
|
|
points.Append (0);
|
|
|
|
int i = 1;
|
|
oldf = 0;
|
|
// t = 0.5 * dt;
|
|
for (int j = 1; j <= n && i < nel; j++)
|
|
{
|
|
double t = (j-0.5)*dt;
|
|
double fun = min3 (hcurve, t/elto0 + h1, (l-t)/elto0 + h2);
|
|
double curv = spline.CalcCurvature (t/l);
|
|
if (curv < 1e-10) curv = 1e-10;
|
|
fun = min2 (fun, 0.1/curv);
|
|
|
|
f = oldf + dt / fun;
|
|
|
|
while (i * fperel < f && i < nel)
|
|
{
|
|
points.Append ( dt * (j-1) + (i * fperel - oldf) * fun);
|
|
i++;
|
|
}
|
|
oldf = f;
|
|
t += dt;
|
|
}
|
|
points.Append (l);
|
|
}
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void SplineGeometry2d :: SetBCName (int bcnr, string name)
|
|
{
|
|
if (bcnr < 1)
|
|
throw NgException ("Illegal nr in SetBCName");
|
|
int new_to_add = bcnr - bcnames.Size();
|
|
for (int i = 0; i < new_to_add; i++)
|
|
bcnames.Append (new string("default"));
|
|
delete bcnames[bcnr-1];
|
|
bcnames[bcnr-1] = new string(name);
|
|
}
|
|
|
|
string SplineGeometry2d :: GetBCName( int bcnr ) const
|
|
{
|
|
if (bcnames.Size() >= bcnr)
|
|
if (bcnames[bcnr-1] )
|
|
return *bcnames[bcnr-1];
|
|
return "default";
|
|
}
|
|
|
|
string * SplineGeometry2d :: BCNamePtr( int bcnr )
|
|
{
|
|
if ( bcnr > bcnames.Size() )
|
|
return nullptr;
|
|
else
|
|
return bcnames[bcnr-1];
|
|
}
|
|
|
|
|
|
int SplineGeometry2d :: GetBCNumber (string name) const
|
|
{
|
|
for (int i = 0; i < bcnames.Size(); i++)
|
|
if (*bcnames[i] == name)
|
|
return i+1;
|
|
return 0;
|
|
}
|
|
|
|
int SplineGeometry2d :: AddBCName (string name)
|
|
{
|
|
bcnames.Append (new string(name));
|
|
return bcnames.Size();
|
|
}
|
|
|
|
|
|
|
|
void SplineGeometry2d :: GetMaterial (int domnr, char* & material )
|
|
{
|
|
if ( materials.Size() >= domnr)
|
|
material = materials[domnr-1];
|
|
else
|
|
material = 0;
|
|
}
|
|
|
|
void SplineGeometry2d :: SetMaterial (int domnr, const string & material)
|
|
{
|
|
int oldsize = materials.Size();
|
|
if (domnr > materials.Size()) materials.SetSize (domnr);
|
|
for (int i = oldsize; i < domnr; i++)
|
|
materials[i] = nullptr;
|
|
|
|
if (domnr >= 1) // && domnr <= materials.Size())
|
|
{
|
|
delete materials[domnr-1];
|
|
materials[domnr-1] = new char[material.size()+1];
|
|
strcpy(materials[domnr-1], material.c_str());
|
|
}
|
|
else
|
|
throw NgException ("material index out of range");
|
|
}
|
|
|
|
|
|
|
|
double SplineGeometry2d :: GetDomainMaxh (const int domnr )
|
|
{
|
|
if ( maxh.Size() >= domnr && domnr > 0)
|
|
return maxh[domnr-1];
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
void SplineGeometry2d :: SetDomainMaxh (int domnr, double h)
|
|
{
|
|
int oldsize = maxh.Size();
|
|
if (domnr > maxh.Size()) maxh.SetSize (domnr);
|
|
for (int i = oldsize; i < domnr; i++)
|
|
maxh[i] = 1e99;
|
|
|
|
if (domnr >= 1)
|
|
maxh[domnr-1] = h;
|
|
else
|
|
throw NgException ("material index out of range");
|
|
}
|
|
|
|
|
|
|
|
extern void MeshFromSpline2D (SplineGeometry2d & geometry,
|
|
shared_ptr<Mesh> & mesh,
|
|
MeshingParameters & mp);
|
|
|
|
|
|
int SplineGeometry2d :: GenerateMesh (shared_ptr<Mesh> & mesh, MeshingParameters & mparam)
|
|
{
|
|
if(restricted_h.Size())
|
|
{
|
|
// copy so that we don't change mparam outside
|
|
MeshingParameters mp = mparam;
|
|
for(const auto& [pnt, maxh] : restricted_h)
|
|
mp.meshsize_points.Append({pnt, maxh});
|
|
MeshFromSpline2D (*this, mesh, mp);
|
|
}
|
|
else
|
|
MeshFromSpline2D (*this, mesh, mparam);
|
|
return 0;
|
|
}
|
|
|
|
class SplineGeometryRegister : public GeometryRegister
|
|
{
|
|
public:
|
|
virtual NetgenGeometry * Load (const filesystem::path & filename) const;
|
|
};
|
|
|
|
NetgenGeometry * SplineGeometryRegister :: Load (const filesystem::path & filename) const
|
|
{
|
|
string ext = ToLower(filename.extension());
|
|
if (ext == ".in2d")
|
|
{
|
|
PrintMessage (1, "Load 2D-Spline geometry file ", filename);
|
|
|
|
ifstream infile(filename);
|
|
|
|
SplineGeometry2d * hgeom = new SplineGeometry2d();
|
|
hgeom -> Load (filename);
|
|
return hgeom;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
class SplineGeoInit
|
|
{
|
|
public:
|
|
SplineGeoInit()
|
|
{
|
|
GeometryRegisterArray& gra = FetchGeometryRegisterArray();
|
|
gra.Append (new SplineGeometryRegister);
|
|
}
|
|
};
|
|
|
|
SplineGeoInit sginit;
|
|
static RegisterClassForArchive<SplineGeometry2d, SplineGeometry<2>, NetgenGeometry> regspg2;
|
|
static RegisterClassForArchive<SplineSegExt, SplineSeg<2>> regssext;
|
|
}
|