Skip to content
Snippets Groups Projects
Commit 8669671c authored by Boris Martin's avatar Boris Martin
Browse files

first draft of flexibleAcquisition

parent c26a1a37
No related branches found
No related tags found
1 merge request!6Draft: "Flexible acquisition", a configuration with arbitrary sources and receivers read from a YAML file.
//Standard Library
#include <numeric>
#include <array>
//GmshFEM Library
#include "GmshFem.h"
#include "Exception.h"
#include "Message.h"
#include "Domain.h"
#include "Function.h"
#include "CSVio.h"
//Gmsh Library
#include "gmsh.h"
//GmshFWI Library
#include "../../common/model/macro.h"
#include "../../common/data/element.h"
#include "../wave/correlation.h"
#include "flexible_acquisition.h"
namespace gmodel = gmsh::model;
namespace factory = gmsh::model::geo;
using namespace gmshfem;
using namespace gmshfem::common;
using namespace gmshfem::domain;
using namespace gmshfem::function;
static const std::complex< double > im = std::complex< double >(0., 1.);
namespace flexible_acquisition
{
/*
* class Configuration
*/
Configuration::Configuration(std::string name, const ParametrizationInterface* const parametrization, const GmshFem& gmshFem) : ConfigurationInterface(name, parametrization, gmshFem)
{
msg::print << "Initialize flexible configuration" << msg::endl;
/*
* MESH
*/
if(
!(
gmshFem.userDefinedParameter(_H, "H") &&
gmshFem.userDefinedParameter(_L, "L") &&
gmshFem.userDefinedParameter(_Hsub, "Hsub") &&
gmshFem.userDefinedParameter(_h, "h")
)
)
{
throw common::Exception("A geometric parameter could not be found.");
}
// Setup E/R
_er_positions.emplace_back(0.4, -0.5);
_er_positions.emplace_back(0.5, -0.5);
_er_positions.emplace_back(0.6, -0.5);
mesh();
/*
* DOMAIN
*/
// TODO: actual data mesh!
_data_omega = Domain("supersurface") | Domain("subsurface");
std::string unknownRegion = "subsurface";
gmshFem.userDefinedParameter(unknownRegion, "unknown");
if (unknownRegion == "subsurface")
{
_model_known[Support::BLK] = Domain("supersurface");
_model_known[Support::BND] = Domain("supersurface_bnd");
_model_unknown[Support::BLK] = Domain("subsurface");
_model_unknown[Support::BND] = Domain("subsurface_bnd");
}
else if (unknownRegion == "none")
{
_model_known[Support::BLK] = Domain("supersurface") | Domain("subsurface");
_model_known[Support::BND] = Domain("supersurface_bnd") | Domain("subsurface_bnd");
}
else {
throw Exception("Invalid unknown region type: " + unknownRegion);
}
_wave_omega[Support::BLK] = _model_known[Support::BLK] | _model_unknown[Support::BLK];
_wave_omega[Support::BND] = _model_known[Support::BND] | _model_unknown[Support::BND];
// Once Dirichlet BCs are added
//_named_domains() ...
/*
* Reference model function
*/
/*
_m_super.resize(model_size());
_m_sub.resize(model_size());
for (unsigned int c = 0; c < model_size(); c++)
{
ScalarPiecewiseFunction<std::complex<double>> m0;
std::string suffix = "c" + std::to_string(c);
double Rem_super, Imm_super, Rem_sub, Imm_sub;
if (!(
gmshFem.userDefinedParameter(Rem_super, "Re(m_super" + suffix + ")") && gmshFem.userDefinedParameter(Imm_super, "Im(m_super" + suffix + ")") &&
gmshFem.userDefinedParameter(Rem_sub, "Re(m_sub" + suffix + ")") && gmshFem.userDefinedParameter(Imm_sub, "Im(m_sub" + suffix + ")")))
{
throw common::Exception("A model component " + suffix + " could not be found.");
}
_m_super[c] = Rem_super + im * Imm_super;
_m_sub[c] = Rem_sub + im * Imm_sub;
_mc[c] = _m_sub[c];
m0.addFunction(_m_super[c], _supersurface[Support::BLK] | _supersurface[Support::BND] | _points);
std::string m0_type;
if (!gmshFem.userDefinedParameter(m0_type, "m0_type" + suffix))
{
throw Exception("Reference model type could not be found.");
}
if (m0_type == "file")
{
std::string path = "";
if (!gmshFem.userDefinedParameter(path, "m0_path" + suffix))
{
throw common::Exception("Path to subsurface data could not be found.");
}
m0.addFunction(bilinearInterpolation(path), _subsurface[Support::BLK] | _subsurface[Support::BND]);
}
else if (m0_type == "file.pos")
{
std::string path = "";
if (!gmshFem.userDefinedParameter(path, "m0_path" + suffix))
{
throw common::Exception("Path to subsurface data could not be found.");
}
gmsh::merge(path + suffix + ".pos");
ScalarFunction<std::complex<double>> mpos = probeScalarView<std::complex<double>>(c);
m0.addFunction(mpos, _subsurface[Support::BLK] | _subsurface[Support::BND]);
}
else if (m0_type == "inverse_linear_squared")
{
double Rea_0, Ima_0;
if (!(
gmshFem.userDefinedParameter(Rea_0, "Re(a0" + suffix + ")") && gmshFem.userDefinedParameter(Ima_0, "Im(a0" + suffix + ")")))
{
throw common::Exception("Initial model parameter (a0) could not be found.");
}
double Rea_H, Ima_H;
if (!(
gmshFem.userDefinedParameter(Rea_H, "Re(aH" + suffix + ")") && gmshFem.userDefinedParameter(Ima_H, "Im(aH" + suffix + ")")))
{
throw common::Exception("Initial model parameter (aH) could not be found.");
}
ScalarFunction<std::complex<double>> num = (Rea_0 + im * Ima_0) - ((Rea_H + im * Ima_H) - (Rea_0 + im * Ima_0)) / H() * y<std::complex<double>>();
m0.addFunction(1. / pow(num, 2), _subsurface[Support::BLK] | _subsurface[Support::BND]);
}
else if (m0_type == "linear")
{
double Rea_0, Ima_0;
if (!(
gmshFem.userDefinedParameter(Rea_0, "Re(a0" + suffix + ")") && gmshFem.userDefinedParameter(Ima_0, "Im(a0" + suffix + ")")))
{
throw common::Exception("Initial model parameter (a0) could not be found.");
}
double Rea_H, Ima_H;
if (!(
gmshFem.userDefinedParameter(Rea_H, "Re(aH" + suffix + ")") && gmshFem.userDefinedParameter(Ima_H, "Im(aH" + suffix + ")")))
{
throw common::Exception("Initial model parameter (aH) could not be found.");
}
ScalarFunction<std::complex<double>> lin = (Rea_0 + im * Ima_0) - ((Rea_H + im * Ima_H) - (Rea_0 + im * Ima_0)) / H() * (y<std::complex<double>>() + _ymin);
m0.addFunction(lin, _subsurface[Support::BLK] | _subsurface[Support::BND]);
}
else if (m0_type == "constant")
{
m0.addFunction(_m_sub[c], _subsurface[Support::BLK] | _subsurface[Support::BND]);
}
else
{
throw common::Exception("Initial model type (" + suffix + ") " + m0_type + " is unknown.");
}
_m0.push_back(m0);
}
*/
// MODEL ON SUBSURFACE, SURFACE
/*
_mb.resize(model_size());
_mi.resize(model_size());
for (unsigned int c = 0; c < model_size(); c++)
{
std::string suffix = "c"+std::to_string(c);
double Remb, Immb;
if
(!
(
gmshFem.userDefinedParameter(Remb, "Re(mb"+suffix+")") &&
gmshFem.userDefinedParameter(Immb, "Im(mb"+suffix+")")
)
)
{
throw common::Exception("Background (reference) model parameter (component "+suffix+" ) could not be found.");
}
else
{
_mb[c] = Remb + im * Immb;
_mc[c] = _mb[c];
}
ScalarPiecewiseFunction< std::complex< double > > m0;
std::string m0_type = "constant";
if(!gmshFem.userDefinedParameter(m0_type, "m0_type"+suffix))
{
msg::warning << "Reference model type could not be found. Constant background is used (default)." << msg::endl;
}
if(m0_type=="file")
{
std::string path = "";
if(!gmshFem.userDefinedParameter(path, "m0_path"+suffix))
{
throw common::Exception("Path to circular data could not be found.");
}
m0.addFunction(bilinearInterpolation(path),_background[Support::BLK] | _background[Support::BND] );
}
else if(m0_type=="file.pos")
{
std::string path = "";
if(!gmshFem.userDefinedParameter(path, "m0_path"+suffix))
{
throw common::Exception("Path to model file could not be found.");
}
gmsh::merge(path+suffix+".pos");
ScalarFunction<std::complex<double>> mpos = probeScalarView<std::complex<double>>(c);
m0.addFunction(mpos,_background[Support::BLK] | _background[Support::BND]);
}
else if(m0_type=="constant")
{
m0.addFunction(_mb[c],_background[Support::BLK] | _background[Support::BND]);
}
else
{
throw common::Exception("Initial model type ("+ suffix + ") " + m0_type +" is unknown.");
}
_mi[c].resize(_ni);
for (unsigned int i = 0; i < _ni; i++)
{
double Remi=0., Immi=0.;
if
(
!(gmshFem.userDefinedParameter(Remi, "Re(mi"+std::to_string(i)+suffix+")") &&
gmshFem.userDefinedParameter(Immi, "Im(mi"+std::to_string(i)+suffix+")"))
)
{
throw Exception("Inclusion model parameter could not be found.");
}
_mi[c][i] = Remi + im * Immi;
m0.addFunction(_mi[c][i],_inclusion[i][Support::BLK] | _inclusion[i][Support::BND]);
}
_m0.push_back(m0);
}*/
}
void Configuration::wave_mesh() const
{
int p0 = factory::addPoint(0., -_H, 0., _h);
int p1 = factory::addPoint(_L, -_H, 0., _h);
int p2 = factory::addPoint(_L, -_Hsub, 0., _h);
int p3 = factory::addPoint(0., -_Hsub, 0., _h);
int p4 = factory::addPoint(_L, 0., 0., _h);
int p5 = factory::addPoint(0., 0., 0., _h);
// All horizontal lines defined left to right, vertical bottom to top
int lineBottom = factory::addLine(p0, p1);
int lineSub = factory::addLine(p3, p2);
int lineTop = factory::addLine(p5, p4);
int lineLeftSub = factory::addLine(p0, p3);
int lineLeftSuper = factory::addLine(p3, p5);
int lineRightSub = factory::addLine(p1, p2);
int lineRightSuper = factory::addLine(p2, p4);
int clSub = factory::addCurveLoop({lineBottom, lineRightSub, -lineSub, -lineLeftSub});
int clSuper = factory::addCurveLoop({lineSub, lineRightSuper, -lineTop, -lineLeftSuper});
int sSub = factory::addPlaneSurface({clSub});
int sSuper = factory::addPlaneSurface({clSuper});
std::vector<int> p_er;
// Emitters and receivers
for (auto pos: _er_positions) {
p_er.push_back(factory::addPoint(pos.first, pos.second, 0.0, _h));
}
factory::synchronize();
// Embed the e/r. Check if they're in the subsurface or supersurface
for (unsigned i = 0; i < p_er.size(); ++i) {
bool isSub = _er_positions[i].second < (-_Hsub);
gmodel::mesh::embed(0, {p_er[i]}, 2, isSub ? sSub : sSuper);
}
//gmodel::addPhysicalGroup(2, {}, 1000+p);
//gmodel::setPhysicalName(0, 1000+p, "emitter_receiver_"+std::to_string(p));
gmodel::addPhysicalGroup(2, {sSub}, 21);
gmodel::setPhysicalName(2, 21, "subsurface");
gmodel::addPhysicalGroup(2, {sSuper}, 22);
gmodel::setPhysicalName(2, 22, "supersurface");
gmodel::addPhysicalGroup(1, {lineLeftSub, lineBottom, lineRightSub}, 11);
gmodel::setPhysicalName(1, 11, "subsurface_bnd");
gmodel::addPhysicalGroup(1, {lineLeftSuper, lineTop, lineRightSuper}, 12);
gmodel::setPhysicalName(1, 12, "supersurface_bnd");
for (unsigned p = 0; p < p_er.size(); ++p) {
gmodel::addPhysicalGroup(0, {p_er[p]}, 1000+p);
gmodel::setPhysicalName(0, 1000+p, "emitter_receiver_"+std::to_string(p));
}
/*
//Vertical emitters
std::vector<int> pnt(_np);
double DAngle = 2. * M_PI /((double) _np);
for (unsigned int p = 0; p < _np; p++)
{
double angle = ((double)p) * DAngle;
pnt[p] = factory::addPoint(_rer*std::cos(angle), _rer*std::sin(angle), 0., _h);
}
int sb;
std::vector<int> si;
std::vector<std::vector<int>> li(_ni);
std::vector<int> li_tot;
if(_ni!=0)
{
std::vector<int> cli(_ni,0);
if(_areFilled){si.resize(_ni);}
for (unsigned int i = 0; i < _ni; i++)
{
li[i] = _inclusion_geo[i]->addInclusion();
li_tot.insert(li_tot.end(), li[i].begin(), li[i].end());
cli[i] = factory::addCurveLoop(li[i]);
if(_areFilled)
{
si[i] = factory::addPlaneSurface({cli[i]});
}
}
std::vector<int> clbcli = cli;
clbcli.insert(clbcli.begin(), clb);
sb = factory::addPlaneSurface(clbcli);
}
else
{
sb = factory::addPlaneSurface({clb});
}
factory::synchronize();
gmodel::mesh::embed(0, pnt, 2, sb);
for (unsigned int p = 0; p <_np; p++)
{
gmodel::addPhysicalGroup(0, {pnt[p]}, 1000+p);
gmodel::setPhysicalName(0, 1000+p, "emitter_receiver_"+std::to_string(p));
}
gmodel::addPhysicalGroup(1, {lb1,lb2,lb3,lb4}, 12);
gmodel::setPhysicalName(1, 12, "background_bnd");
gmodel::addPhysicalGroup(2, {sb}, 21);
gmodel::setPhysicalName(2, 21, "background_vol");
for (unsigned int i = 0; i < _ni; i++)
{
if(_areFilled)
{
gmodel::addPhysicalGroup(2, {si[i]}, 1000+i);
gmodel::setPhysicalName(2, 1000+i, "inclusion_vol"+std::to_string(i));
}
else
{
gmodel::addPhysicalGroup(1, li[i], 2000+i);
gmodel::setPhysicalName(1, 2000+i, "inclusion_bnd"+std::to_string(i));
}
}*/
}
void Configuration::data_mesh() const
{
// TODO
/*
double DAngle = 2. * M_PI /((double) _np);
double Ds_e = DAngle * _emitter_skip * _rer;
double Ds_r = DAngle * _receiver_skip * _rer;
double Le0 = DAngle * _emitter_offset * _rer;
double Lr0 = DAngle * _receiver_offset * _rer;
double Le = (_ne-1) * Ds_e;
double Lr = (_nr-1) * Ds_r;
int p0 = factory::addPoint(Le0, Lr0, 1.);
int p1 = factory::addPoint(Le0+Le, Lr0, 1.);
int p2 = factory::addPoint(Le0+Le, Lr0+Lr, 1.);
int p3 = factory::addPoint(Le0, Lr0+Lr, 1.);
int l0 = factory::addLine(p0, p1);
int l1 = factory::addLine(p1, p2);
int l2 = factory::addLine(p2, p3);
int l3 = factory::addLine(p3, p0);
int cl = factory::addCurveLoop({l0,l1,l2,l3});
int s1 = factory::addPlaneSurface({cl});
factory::mesh::setTransfiniteCurve(l0,_ne);
factory::mesh::setTransfiniteCurve(l1,_nr);
factory::mesh::setTransfiniteCurve(l2,_ne);
factory::mesh::setTransfiniteCurve(l3,_nr);
factory::mesh::setTransfiniteSurface(s1,"Left",{p0,p1,p2,p3});
factory::mesh::setRecombine(2,s1);
gmodel::addPhysicalGroup(2, {s1}, 1);
gmodel::setPhysicalName(2, 1, "data_omega");
*/
}
std::array<unsigned int,2> Configuration::data_coordinate_to_index(double xs, double xr) const
{
throw Exception("Unimplemented Configuration::data_coordinate_to_index");
/*
if( (!_receiver_on_emitter) )
{
throw Exception("Data space when an emitter is not also a receiver is not implemented yet");
}
std::array<unsigned int,2> index;
double DAngle = 2. * M_PI /((double) _np);
double Ds_e = DAngle * _emitter_skip * _rer;
double Ds_r = DAngle * _receiver_skip * _rer;
double Le0 = DAngle * _emitter_offset * _rer;
double Lr0 = DAngle * _receiver_offset * _rer;
index[0] = std::round( (xs-Le0) / Ds_e );
index[1] = std::round( (xr-Lr0) / Ds_r );
return index;
*/
}
std::array<double,2> Configuration::index_to_data_coordinate(unsigned int s, unsigned int r) const
{
throw Exception("Unimplemented Configuration::index_to_data_coordinate");
/*
if( (!_receiver_on_emitter) )
{
throw Exception("Data space when an emitter is not also a receiver is not implemented yet");
}
std::array<double,2> index;
double DAngle = 2. * M_PI /((double) _np);
double Ds_e = DAngle * _emitter_skip * _rer;
double Ds_r = DAngle * _receiver_skip * _rer;
double Le0 = DAngle * _emitter_offset * _rer;
double Lr0 = DAngle * _receiver_offset * _rer;
index[0] = Le0 + ((double)s) * Ds_e;
index[1] = Lr0 + ((double)r) * Ds_r;
return index;*/
}
double Configuration::data_area() const
{
throw Exception("Unimplemented Configuration::data_area");
/*
double DAngle = 2. * M_PI /((double) _np);
double Ds_e = DAngle * _emitter_skip * _rer;
double Ds_r = DAngle * _receiver_skip * _rer;
double Le = (_ne-1) * Ds_e;
double Lr = (_nr-1) * Ds_r;
return Le * Lr;
*/
};
double Configuration::datapoint_area() const
{
throw Exception("Unimplemented Configuration::datapoint_area");
/*
double DAngle = 2. * M_PI /((double) _np);
double Ds_e = DAngle * _emitter_skip * _rer;
double Ds_r = DAngle * _receiver_skip * _rer;
return Ds_e * Ds_r;*/
};
bool Configuration::data_coordinate_isValid(double xs,double xr) const
{
throw Exception("Unimplemented Configuration::data_coordinate_isValid");
/*
double DAngle = 2. * M_PI /((double) _np);
double Ds_e = DAngle * _emitter_skip * _rer;
double Ds_r = DAngle * _receiver_skip * _rer;
double Le0 = DAngle * _emitter_offset * _rer;
double Lr0 = DAngle * _receiver_offset * _rer;
double Le = (_ne-1) * Ds_e;
double Lr = (_nr-1) * Ds_r;
double eps = 1e-8;
gmsh::option::getNumber("Geometry.MatchMeshTolerance",eps);
if( (Le0-eps <= xs) && (xs <= Le0+Le+eps) && (Lr0-eps <= xr) && (xr <= Lr0+Lr+eps) )
{
return true;
}
else
{
return false;
}
*/
}
template<Physic T_Physic>
ModelMonoFunction green0_preconditioner(const Data<T_Physic>& dd, const WaveMultiField<T_Physic>& g, const Configuration* const config)
{
return autocorrelate<T_Physic>(g,config->emitter_idx())*autocorrelate<T_Physic>(g,config->receiver_idx());
}
template ModelMonoFunction green0_preconditioner<Physic::acoustic>(const Data<Physic::acoustic>&, const WaveMultiField<Physic::acoustic>&, const Configuration* const);
template ModelMonoFunction green0_preconditioner<Physic::electromagnetic>(const Data<Physic::electromagnetic>&, const WaveMultiField<Physic::electromagnetic>&, const Configuration* const);
template ModelMonoFunction green0_preconditioner<Physic::elastodynamic>(const Data<Physic::elastodynamic>&, const WaveMultiField<Physic::elastodynamic>&, const Configuration* const);
} // namespace circular_acquisition
#ifndef H_CONFIGURATION_FLEXIBLE_ACQUISITION
#define H_CONFIGURATION_FLEXIBLE_ACQUISITION
//GmshFEM Library
#include "GmshFem.h"
//#include "Function.h"
//GmshFWI Library
#include "../../common/configuration.h"
#include "../../common/wave/element.h"
#include "inclusion/inclusion.h"
//Forward declaration
template<Physic T_Physic>
class Data;
namespace flexible_acquisition
{
class Configuration final : public ConfigurationInterface
{
private:
/**
* Emetters and receivers are stored together, and for each shot, one point is set as emitter,
* and some others (potentially including the emitter) are enabled as receivers
*/
std::vector<std::pair<double, double>> _er_positions;
struct ShotConfig {
unsigned int emetterIdx;
std::vector<unsigned int> enabledReceivers;
};
std::vector<ShotConfig> _shotsConfigs;
/* Domain is a rectangle. "x" goes from 0 to L and "y" from -H to 0. Known part is y between 0 and -Hsub*/
double _H;
double _L;
double _Hsub;
// Mesh resolution
double _h;
// TODO
std::vector<unsigned int> _emitter_idx;
std::vector<unsigned int> _receiver_idx;
bool _areFilled;
// Subdomains: all in the parent class
/*
double _rer;
double _rext;
unsigned int _ne;
unsigned int _nr;
unsigned int _emitter_offset;
unsigned int _receiver_offset;
unsigned int _emitter_skip;
unsigned int _receiver_skip;
bool _receiver_on_emitter;
unsigned int _ni;
std::vector<const InclusionInterface*> _inclusion_geo;
UnknownRegion _unknown_region;
std::array<gmshfem::domain::Domain,2> _background;
std::array<gmshfem::domain::Domain,2> _inclusions;
std::vector<std::array<gmshfem::domain::Domain,2>> _inclusion;
std::vector<std::complex<double>> _mb;
std::vector<std::vector<std::complex<double>>> _mi;
*/
virtual void wave_mesh() const;
virtual void data_mesh() const;
public:
Configuration(std::string name, const ParametrizationInterface* const parametrization, const gmshfem::common::GmshFem& gmshFem);
const std::vector<unsigned int>& emitter_idx() const {return _emitter_idx;};
const std::vector<unsigned int>& receiver_idx() const {return _receiver_idx;};
bool areFilled() const {return _areFilled;};
unsigned int ner() const {return _np;};
// virtual void mesh() const;
virtual std::array<unsigned int,2> data_coordinate_to_index(double xs, double xr) const;
virtual std::array<double,2> index_to_data_coordinate(unsigned int s, unsigned int r) const;
virtual bool data_coordinate_isValid(double xs,double xr) const;
virtual double area() const {return _H * _L;};
virtual double data_area() const override;
virtual double datapoint_area() const;
virtual double array() const {return 2. * (_L + _H);};
virtual double depth() const {return _H;};
virtual std::string wave_gmodel() const {return _name;};
virtual std::string model_gmodel() const {return _name;};
virtual std::string data_gmodel() const {return _name;};
};
template<Physic T_Physic>
ModelMonoFunction green0_preconditioner(const Data<T_Physic>& dd, const WaveMultiField<T_Physic>& g, const Configuration* const config);
} // namespace soil
#endif // H_CONFIGURATION_FLEXIBLE_ACQUISITION
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "circular_acquisition.h" #include "circular_acquisition.h"
#include "line_acquisition.h" #include "line_acquisition.h"
#include "rectangular_acquisition.h" #include "rectangular_acquisition.h"
#include "flexible_acquisition.h"
ConfigurationInterface* newConfiguration(std::string name, const ParametrizationInterface* const parametrization, const gmshfem::common::GmshFem& gmshFem) ConfigurationInterface* newConfiguration(std::string name, const ParametrizationInterface* const parametrization, const gmshfem::common::GmshFem& gmshFem)
{ {
...@@ -29,6 +30,7 @@ ConfigurationInterface* newConfiguration(std::string name, const Parametrization ...@@ -29,6 +30,7 @@ ConfigurationInterface* newConfiguration(std::string name, const Parametrization
else if(configuration=="circular_acquisition"){return new circular_acquisition::Configuration(name, parametrization, gmshFem);} else if(configuration=="circular_acquisition"){return new circular_acquisition::Configuration(name, parametrization, gmshFem);}
else if(configuration=="line_acquisition"){return new line_acquisition::Configuration(name, parametrization, gmshFem);} else if(configuration=="line_acquisition"){return new line_acquisition::Configuration(name, parametrization, gmshFem);}
else if(configuration=="rectangular_acquisition"){return new rectangular_acquisition::Configuration(name, parametrization, gmshFem);} else if(configuration=="rectangular_acquisition"){return new rectangular_acquisition::Configuration(name, parametrization, gmshFem);}
else if(configuration=="flexible_acquisition"){return new flexible_acquisition::Configuration(name, parametrization, gmshFem);}
else else
{ {
throw gmshfem::common::Exception("Configuration" + configuration + " is not valid."); throw gmshfem::common::Exception("Configuration" + configuration + " is not valid.");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment