Commit 1ecf410a authored by Jan Zapletal's avatar Jan Zapletal

ENH: added interface without bem4idata, created mex for matsol

parent 76f69d61
......@@ -6,6 +6,6 @@ rm -f heatdtn_mex.o
rm -f cpp_mexapi_version.o
rm -f heatdtn_mex.mexa64
g++ -c -DMATLAB_DEFAULT_RELEASE=R2018a -DUSE_MEX_CMD -D_GNU_SOURCE -DMATLAB_MEX_FILE -I${MATLAB_ROOT}/extern/include -I../../include -fexceptions -fPIC -fno-omit-frame-pointer -pthread -std=c++11 -O2 -fwrapv -DNDEBUG heatdtn_mex.cpp -o heatdtn_mex.o
g++ -c -DMATLAB_DEFAULT_RELEASE=R2018a -DUSE_MEX_CMD -D_GNU_SOURCE -DMATLAB_MEX_FILE -I${MATLAB_ROOT}/extern/include -I/opt/heatdtn/include -fexceptions -fPIC -fno-omit-frame-pointer -pthread -std=c++11 -O2 -fwrapv -DNDEBUG heatdtn_mex.cpp -o heatdtn_mex.o
g++ -c -DMX_COMPAT_64 -DMATLAB_MEXCMD_RELEASE=R2018a -DUSE_MEX_CMD -D_GNU_SOURCE -DMATLAB_MEX_FILE -I${MATLAB_ROOT}/extern/include -fexceptions -fPIC -fno-omit-frame-pointer -pthread -O2 -fwrapv -DNDEBUG "${MATLAB_ROOT}/extern/version/cpp_mexapi_version.cpp" -o cpp_mexapi_version.o
g++ -pthread -Wl,--no-undefined -Wl,-rpath-link,${MATLAB_ROOT}/bin/glnxa64 -shared -O -Wl,--version-script,${MATLAB_ROOT}/extern/lib/glnxa64/c_exportsmexfileversion.map heatdtn_mex.o cpp_mexapi_version.o -L"${MATLAB_ROOT}/bin/glnxa64" -L../../dist -Wl,-rpath,../../dist -lMatlabDataArray -lmx -lmex -lmat -lstdc++ -lheatdtn -o heatdtn_mex.mexa64
g++ -pthread -Wl,--no-undefined -Wl,-rpath-link,${MATLAB_ROOT}/bin/glnxa64 -shared -O -Wl,--version-script,${MATLAB_ROOT}/extern/lib/glnxa64/c_exportsmexfileversion.map heatdtn_mex.o cpp_mexapi_version.o -L"${MATLAB_ROOT}/bin/glnxa64" -L/opt/heatdtn/lib -Wl,-rpath,/opt/heatdtn/lib -lMatlabDataArray -lmx -lmex -lmat -lstdc++ -lheatdtn -o heatdtn_mex.mexa64
#!/bin/bash
MATLAB_ROOT=/opt/matlab
HEATDTN_ROOT=/home/zap150/repos/heatdtn
HEATDTN_LIB_DIR=dist
rm -f heatdtn_mex_c_api.o
rm -f c_mexapi_version.o
rm -f heatdtn_mex_c_api.mexa64
rm -f *.o
rm -f *.mexa64
g++ -c -DMATLAB_DEFAULT_RELEASE=R2018a -DUSE_MEX_CMD -D_GNU_SOURCE -DMATLAB_MEX_FILE -I${MATLAB_ROOT}/extern/include -I../../include -fexceptions -fPIC -fno-omit-frame-pointer -pthread -std=c++11 -O2 -fwrapv -DNDEBUG heatdtn_mex_c_api.cpp -o heatdtn_mex_c_api.o
g++ -c -DMATLAB_DEFAULT_RELEASE=R2018a -DUSE_MEX_CMD -D_GNU_SOURCE -DMATLAB_MEX_FILE -I${MATLAB_ROOT}/extern/include -I${HEATDTN_ROOT}/include -fexceptions -fPIC -fno-omit-frame-pointer -pthread -std=c++11 -O2 -fwrapv -DNDEBUG heatdtn_mex_c_api.cpp -o heatdtn_mex_c_api.o
g++ -c -DMATLAB_DEFAULT_RELEASE=R2018a -DUSE_MEX_CMD -D_GNU_SOURCE -DMATLAB_MEX_FILE -I${MATLAB_ROOT}/extern/include -I${HEATDTN_ROOT}/include -fexceptions -fPIC -fno-omit-frame-pointer -pthread -std=c++11 -O2 -fwrapv -DNDEBUG matsol_dtn_mex.cpp -o matsol_dtn_mex.o
g++ -c -DMATLAB_DEFAULT_RELEASE=R2018a -DUSE_MEX_CMD -D_GNU_SOURCE -DMATLAB_MEX_FILE -I${MATLAB_ROOT}/extern/include -I${HEATDTN_ROOT}/include -fexceptions -fPIC -fno-omit-frame-pointer -pthread -std=c++11 -O2 -fwrapv -DNDEBUG matsol_repr_mex.cpp -o matsol_repr_mex.o
g++ -c -DMX_COMPAT_64 -DMATLAB_MEXCMD_RELEASE=R2018a -DUSE_MEX_CMD -D_GNU_SOURCE -DMATLAB_MEX_FILE -I${MATLAB_ROOT}/extern/include -fexceptions -fPIC -fno-omit-frame-pointer -pthread -O2 -fwrapv -DNDEBUG "${MATLAB_ROOT}/extern/version/c_mexapi_version.c" -o c_mexapi_version.o
g++ -pthread -Wl,--no-undefined -Wl,-rpath-link,${MATLAB_ROOT}/bin/glnxa64 -shared -O -Wl,--version-script,${MATLAB_ROOT}/extern/lib/glnxa64/c_exportsmexfileversion.map heatdtn_mex_c_api.o c_mexapi_version.o -L"${MATLAB_ROOT}/bin/glnxa64" -L../../dist -Wl,-rpath,../../dist -lmx -lmex -lmat -lstdc++ -lheatdtn -o heatdtn_mex_c_api.mexa64
g++ -pthread -Wl,--no-undefined -Wl,-rpath-link,${MATLAB_ROOT}/bin/glnxa64 -shared -O -Wl,--version-script,${MATLAB_ROOT}/extern/lib/glnxa64/c_exportsmexfileversion.map heatdtn_mex_c_api.o c_mexapi_version.o -L"${MATLAB_ROOT}/bin/glnxa64" -L${HEATDTN_ROOT}/${HEATDTN_LIB_DIR} -Wl,-rpath,${HEATDTN_ROOT}/${HEATDTN_LIB_DIR} -lmx -lmex -lmat -lstdc++ -lheatdtn -o heatdtn_mex_c_api.mexa64
g++ -pthread -Wl,--no-undefined -Wl,-rpath-link,${MATLAB_ROOT}/bin/glnxa64 -shared -O -Wl,--version-script,${MATLAB_ROOT}/extern/lib/glnxa64/c_exportsmexfileversion.map matsol_dtn_mex.o c_mexapi_version.o -L"${MATLAB_ROOT}/bin/glnxa64" -L${HEATDTN_ROOT}/${HEATDTN_LIB_DIR} -Wl,-rpath,${HEATDTN_ROOT}/${HEATDTN_LIB_DIR} -lmx -lmex -lmat -lstdc++ -lheatdtn -o matsol_dtn_mex.mexa64
g++ -pthread -Wl,--no-undefined -Wl,-rpath-link,${MATLAB_ROOT}/bin/glnxa64 -shared -O -Wl,--version-script,${MATLAB_ROOT}/extern/lib/glnxa64/c_exportsmexfileversion.map matsol_repr_mex.o c_mexapi_version.o -L"${MATLAB_ROOT}/bin/glnxa64" -L${HEATDTN_ROOT}/${HEATDTN_LIB_DIR} -Wl,-rpath,${HEATDTN_ROOT}/${HEATDTN_LIB_DIR} -lmx -lmex -lmat -lstdc++ -lheatdtn -o matsol_repr_mex.mexa64
function [ S, VChol, KM, a, beta, values ] = matsol_dtn( )
nodes = [ 1 -1 -1 1 1 -1 -1 1 -1 -1 -1 -1 1 -1 1 1 1 1 -1 1 1 -1 -1 1 ]';
elems = int64( [ 0 1 5 0 5 4 1 2 6 1 6 5 2 7 6 2 3 7 3 0 4 3 4 7 0 3 1 2 1 3 4 5 6 4 6 7 ]' );
dirichlet = ones( size( nodes ) );
points = [ 0.0 0.0 0.0 0.5 0.5 0.5 -0.5 -0.5 -0.5 ]';
alpha = 1.0;
qType = int32( 1 );
orderNear = int32( 4 );
orderFar = int32( 4 );
nonsymmetric = false;
[ S, VChol, KM, a, beta ] = matsol_dtn_mex( nodes, elems, alpha, qType, orderNear, orderFar, nonsymmetric );
nNodes = length( nodes ) / 3;
S = reshape( S, nNodes, nNodes );
values = matsol_repr_mex( nodes, elems, points, dirichlet, VChol, KM, alpha, orderFar );
end
#include "mex.h"
#include "matrix.h"
#include "heatdtn.h"
/* Input Arguments */
#define nodes prhs[ 0 ]
#define elems prhs[ 1 ]
#define alpha prhs[ 2 ]
#define qType prhs[ 3 ]
#define orderNear prhs[ 4 ]
#define orderFar prhs[ 5 ]
#define nonsymmetric prhs[ 6 ]
/* Output Arguments */
#define S plhs[ 0 ]
#define VChol plhs[ 1 ]
#define KM plhs[ 2 ]
#define a plhs[ 3 ]
#define beta plhs[ 4 ]
void mexFunction(
int nlhs,
mxArray * plhs[ ],
int nrhs,
const mxArray * prhs[ ] ){
if( nrhs != 7 )
mexErrMsgIdAndTxt( "heatdtn:invalidNumInputs", "Seven input arguments required." );
if( !mxIsInt64( elems ) )
mexErrMsgIdAndTxt( "heatdtn:invalidInput", "elems must be defined as int64" );
if( !mxIsInt32( qType ) )
mexErrMsgIdAndTxt( "heatdtn:invalidInput", "qType must be defined as int32" );
if( !mxIsInt32( orderNear ) )
mexErrMsgIdAndTxt( "heatdtn:invalidInput", "orderNear must be defined as int32" );
if( !mxIsInt32( orderFar ) )
mexErrMsgIdAndTxt( "heatdtn:invalidInput", "orderFar must be defined as int32" );
if( !mxIsLogical( nonsymmetric ) )
mexErrMsgIdAndTxt( "heatdtn:invalidInput", "nonsymmetric must be defined as logical" );
if( nlhs > 5 )
mexErrMsgIdAndTxt( "heatdtn:invalidNumOutputs", "Too many output arguments." );
long nNodes = (long) mxGetNumberOfElements( nodes ) / 3;
long nElems = (long) mxGetNumberOfElements( elems ) / 3;
S = mxCreateDoubleMatrix( (mwSize) nNodes * (mwSize) nNodes, 1, mxREAL );
VChol = mxCreateDoubleMatrix( (mwSize) nElems * (mwSize) nElems, 1, mxREAL );
KM = mxCreateDoubleMatrix( (mwSize) nElems * (mwSize) nNodes, 1, mxREAL );
a = mxCreateDoubleMatrix( (mwSize) nNodes, (mwSize) 1, mxREAL );
beta = mxCreateDoubleScalar( 0.0 );
mxDouble * S_p = mxGetDoubles( S );
mxDouble * V_p = mxGetDoubles( VChol );
mxDouble * K_p = mxGetDoubles( KM );
mxDouble * a_p = mxGetDoubles( a );
mxDouble * beta_p = mxGetDoubles( beta );
mxDouble * nodes_p = mxGetDoubles( nodes );
mxInt64 * elems_p = mxGetInt64s( elems );
mxDouble * alpha_p = mxGetDoubles( alpha );
mxInt32 * qType_p = mxGetInt32s( qType );
mxInt32 * orderNear_p = mxGetInt32s( orderNear );
mxInt32 * orderFar_p = mxGetInt32s( orderFar );
mxLogical * nonsymmetric_p = mxGetLogicals( nonsymmetric );
bem4i::getLaplaceSteklovPoincare(
(double *) S_p,
(double *) V_p,
(double *) K_p,
(double *) a_p,
(double *) beta_p,
nNodes,
(double *) nodes_p,
nElems,
(long *) elems_p,
(double) *alpha_p,
(int) *qType_p,
(int) *orderNear_p,
(int) *orderFar_p,
(bool) *nonsymmetric_p,
false );
return;
}
#include "mex.h"
#include "matrix.h"
#include "heatdtn.h"
/* Input Arguments */
#define nodes prhs[ 0 ]
#define elems prhs[ 1 ]
#define points prhs[ 2 ]
#define dirichlet prhs[ 3 ]
#define VChol prhs[ 4 ]
#define KM prhs[ 5 ]
#define alpha prhs[ 6 ]
#define orderFar prhs[ 7 ]
/* Output Arguments */
#define values plhs[ 0 ]
void mexFunction(
int nlhs,
mxArray * plhs[ ],
int nrhs,
const mxArray * prhs[ ] ){
if( nrhs != 8 )
mexErrMsgIdAndTxt( "heatdtn:invalidNumInputs", "Seven input arguments required." );
if( !mxIsInt64( elems ) )
mexErrMsgIdAndTxt( "heatdtn:invalidInput", "elems must be defined as int64" );
if( !mxIsInt32( orderFar ) )
mexErrMsgIdAndTxt( "heatdtn:invalidInput", "orderFar must be defined as int32" );
if( nlhs > 1 )
mexErrMsgIdAndTxt( "heatdtn:invalidNumOutputs", "Too many output arguments." );
long nNodes = (long) mxGetNumberOfElements( nodes ) / 3;
long nElems = (long) mxGetNumberOfElements( elems ) / 3;
long nPoints = (long) mxGetNumberOfElements( points ) / 3;
values = mxCreateDoubleMatrix( (mwSize) nPoints, 1, mxREAL );
mxDouble * values_p = mxGetDoubles( values );
mxDouble * nodes_p = mxGetDoubles( nodes );
mxInt64 * elems_p = mxGetInt64s( elems );
mxDouble * points_p = mxGetDoubles( points );
mxDouble * alpha_p = mxGetDoubles( alpha );
mxDouble * dirichlet_p = mxGetDoubles( dirichlet );
mxInt32 * orderFar_p = mxGetInt32s( orderFar );
mxDouble * VChol_p = mxGetDoubles( VChol );
mxDouble * KM_p = mxGetDoubles( KM );
bem4i::evaluateLaplaceRepresentationFormula(
(double *) values_p,
nNodes,
(double *) nodes_p,
nElems,
(long *) elems_p,
nPoints,
(double *) points_p,
(double) *alpha_p,
(double *) dirichlet_p,
(int) *orderFar_p,
(double *) VChol_p,
(double *) KM_p,
false );
return;
}
......@@ -28,6 +28,25 @@ void getLaplaceSteklovPoincare(
bool verbose = false
);
template<class LO, class SC>
void getLaplaceSteklovPoincare(
SC * S,
SC * VChol,
SC * KM,
SC * a,
SC * beta,
LO nNodes,
const SC * nodes,
LO nElems,
const LO * elems,
SC alpha,
int qType, // 0 ... Steinbach, 1 ... Sauter-Schwab
int orderNear, // 5 for Steinbach, 3-4 for Sauter-Schwab
int orderFar, // 0 for none, else 3-4
bool nonsymmetric = false,
bool verbose = false
);
template<class LO, class SC>
void evaluateLaplaceRepresentationFormula(
SC * values,
......@@ -37,13 +56,30 @@ void evaluateLaplaceRepresentationFormula(
const LO * elems,
LO nPoints,
const SC * points,
SC alpha,
SC alpha,
SC * dirichlet,
int orderFar,
bem4idata< LO, SC > *& data,
bool verbose = false
);
template<class LO, class SC>
void evaluateLaplaceRepresentationFormula(
SC * values,
LO nNodes,
const SC * nodes,
LO nElems,
const LO * elems,
LO nPoints,
const SC * points,
SC alpha,
SC * dirichlet,
int orderFar,
SC * VChol,
SC * KM,
bool verbose = false
);
}
#endif
......@@ -198,6 +198,149 @@ void getLaplaceSteklovPoincare(
if ( quadFar ) delete [] quadFar;
}
template<class LO, class SC>
void getLaplaceSteklovPoincare(
SC * S,
SC * VChol,
SC * KM,
SC * a,
SC * beta,
LO nNodes,
const SC * nodes,
LO nElems,
const LO * elems,
SC alpha,
int qType,
int orderNear,
int orderFar,
bool nonsymmetric,
bool verbose
) {
typedef typename GetType<LO, SC>::SCVT SCVT;
if ( qType < 0 || qType > 1 ) qType = 1;
if ( qType == 1 && orderNear < 1 ) orderNear = 1;
if ( qType == 1 && orderNear > 7 ) orderNear = 7;
if ( qType == 0 && orderNear < 3 ) orderNear = 3;
if ( qType == 0 && orderNear > 10 ) orderNear = 10;
if ( orderFar < 0 ) orderFar = 0;
if ( orderFar > 7 ) orderFar = 7;
std::vector< SCVT > nodesv;
nodesv.assign( nodes, nodes + 3 * nNodes );
std::vector< LO > elemsv;
elemsv.assign( elems, elems + 3 * nElems );
SurfaceMesh3D< LO, SC > mesh( nodesv, elemsv );
if ( verbose ) mesh.printInfo( );
quadratureType quadType;
if ( qType == 0 ) {
quadType = Steinbach;
} else {
quadType = SauterSchwab;
}
int quadNear[ 4 ] = { orderNear, orderNear, orderNear, orderNear };
int * quadFar = nullptr;
if ( orderFar != 0 ) {
quadFar = new int [ 2 ];
quadFar[ 0 ] = quadFar[ 1 ] = orderFar;
}
if ( verbose ) {
if ( qType == 0 )
std::cout << "Steinbach ";
else
std::cout << "Sauter-Schwab ";
std::cout << "near-field order " << orderNear;
if ( quadFar )
std::cout << ", Gauss far-field order " << orderFar;
std::cout << "." << std::endl;
}
BESpace< LO, SC > bespace00( &mesh, p0, p0 );
BESpace< LO, SC > bespace10( &mesh, p1, p0 );
BESpace< LO, SC > bespace11( &mesh, p1, p1 );
FullMatrix< LO, SC > V( nElems, nElems, VChol );
BEBilinearFormLaplace1Layer< LO, SC > formV( &bespace00, quadNear,
quadType, quadFar );
if ( verbose ) ProgressMonitor::init( "V" );
formV.assemble( V );
if ( verbose ) ProgressMonitor::step( );
FullMatrix< LO, SC > K( nElems, nNodes, KM );
BEBilinearFormLaplace2Layer< LO, SC > formK( &bespace10, quadNear,
quadType, quadFar );
if ( verbose ) ProgressMonitor::init( "K" );
formK.assemble( K );
if ( verbose ) ProgressMonitor::step( );
IdentityOperator< LO, SC > id( &bespace10 );
SparseMatrix< LO, SC > M;
id.assemble( M );
if( a != nullptr ){
Vector< LO, SC > avect( nNodes, a, false );
avect.setAll( 0.0 );
Vector< LO, SC > onese( nElems );
onese.setAll( 1.0 );
M.apply( onese, avect, true, 1.0, 0.0 );
if( beta != nullptr ){
Vector< LO, SC > onesn( nNodes );
onesn.setAll( 1.0 );
*beta = avect.dot( onesn );
*beta = 0.25 / *beta;
}
}
Eigen::SparseMatrix<SC, Eigen::ColMajor, LO> * Me = M.getEigenSparseMatrix( );
// K <- 1/2M + K
for ( LO j = 0; j < Me->outerSize( ); ++j ) {
typename Eigen::SparseMatrix<SC, Eigen::ColMajor, LO>::InnerIterator
it( *Me, j );
for (; it; ++it ) {
K.add( it.row( ), it.col( ), 0.5 * it.value( ) );
}
}
FullMatrix< LO, SC > Smat( nNodes, nNodes, S );
BEBilinearFormLaplaceHypersingular< LO, SC > formD( &bespace11, quadNear,
quadType, quadFar );
if ( !nonsymmetric ) {
// S <- D
if ( verbose ) ProgressMonitor::init( "D" );
formD.assemble( Smat, V );
//formD.assemble( Smat );
if ( verbose ) ProgressMonitor::step( );
} else {
// S <- 0
Smat.setAll( 0.0 );
}
FullMatrix< LO, SC > * VinvK = new FullMatrix< LO, SC >( K );
if ( verbose ) ProgressMonitor::init( "Applying inverse of V" );
// VinvK <- V^-1 ( 1/2M + K )
V.CholeskiSolve( *VinvK ); // V is invalidated!
if ( verbose ) ProgressMonitor::step( );
if ( !nonsymmetric ) {
// S <- D + (1/2M + K)' * V^-1 * (1/2M + K)
Smat.multiply( K, *VinvK, true, false, 1.0, 1.0 );
} else {
// S <- M' * V^-1 * (1/2M + K)
Smat.multiply( M, *VinvK, true, false, 1.0, 0.0 );
}
Smat.scale(alpha);
if ( quadFar ) delete [] quadFar;
}
template<class LO, class SC>
void evaluateLaplaceRepresentationFormula(
SC * values,
......@@ -256,6 +399,65 @@ void evaluateLaplaceRepresentationFormula(
if ( verbose ) ProgressMonitor::step( );
}
template<class LO, class SC>
void evaluateLaplaceRepresentationFormula(
SC * values,
LO nNodes,
const SC * nodes,
LO nElems,
const LO * elems,
LO nPoints,
const SC * points,
SC alpha,
SC * dirichlet,
int orderFar,
SC * VChol,
SC * KM,
bool verbose
) {
typedef typename GetType<LO, SC>::SCVT SCVT;
if ( VChol == nullptr || KM == nullptr ) {
for ( LO i = 0; i < nPoints; ++i ) {
values[ i ] = 0.0;
}
return;
}
FullMatrix< LO, SC > V( nElems, nElems, VChol );
FullMatrix< LO, SC > K( nElems, nNodes, KM );
std::vector< SCVT > nodesv;
nodesv.assign( nodes, nodes + 3 * nNodes );
std::vector< LO > elemsv;
elemsv.assign( elems, elems + 3 * nElems );
SurfaceMesh3D< LO, SC > mesh( nodesv, elemsv );
BESpace< LO, SC > bespace10( &mesh, p1, p0 );
// solve local Dirichlet problem
Vector< LO, SC > neu( nElems );
Vector< LO, SC > dir( nNodes, dirichlet, false );
// rhs = (1/2 I + K)*dir
K.apply( dir, neu, false, 1.0, 0.0 );
// local solve (V decomposed in assembly)
if ( verbose ) ProgressMonitor::init( "Applying inverse of V" );
V.CholeskiDecomposedSolve( neu );
if ( verbose ) ProgressMonitor::step( );
RepresentationFormulaLaplace<LO, SC> formula( &bespace10, &dir, &neu,
orderFar );
Vector< LO, SC > val( nPoints, values, false );
if ( verbose ) ProgressMonitor::init( "Representation formula" );
formula.evaluate( points, nPoints, true, val );
if ( verbose ) ProgressMonitor::step( );
}
}
#ifdef BLAS_INT
......@@ -281,6 +483,24 @@ template void bem4i::getLaplaceSteklovPoincare< int, double >(
bool verbose
);
template void bem4i::getLaplaceSteklovPoincare< int, double >(
double * S,
double * Vchol,
double * KM,
double * a,
double * beta,
int nNodes,
const double * nodes,
int nElems,
const int * elems,
double alpha,
int qType,
int orderNear,
int orderFar,
bool nonsymmetric,
bool verbose
);
template void bem4i::evaluateLaplaceRepresentationFormula< int, double >(
double * values,
int nNodes,
......@@ -296,6 +516,22 @@ template void bem4i::evaluateLaplaceRepresentationFormula< int, double >(
bool verbose
);
template void bem4i::evaluateLaplaceRepresentationFormula< int, double >(
double * values,
int nNodes,
const double * nodes,
int nElems,
const int * elems,
int nPoints,
const double * points,
double alpha,
double * dirichlet,
int orderFar,
double * VChol,
double * KM,
bool verbose
);
#endif
#ifdef BLAS_LONG
......@@ -321,6 +557,24 @@ template void bem4i::getLaplaceSteklovPoincare< long, double >(
bool verbose
);
template void bem4i::getLaplaceSteklovPoincare< long, double >(
double * S,
double * VChol,
double * KM,
double * a,
double * beta,
long nNodes,
const double * nodes,
long nElems,
const long * elems,
double alpha,
int qType,
int orderNear,
int orderFar,
bool nonsymmetric,
bool verbose
);
template void bem4i::evaluateLaplaceRepresentationFormula< long, double >(
double * values,
long nNodes,
......@@ -336,4 +590,20 @@ template void bem4i::evaluateLaplaceRepresentationFormula< long, double >(
bool verbose
);
template void bem4i::evaluateLaplaceRepresentationFormula< long, double >(
double * values,
long nNodes,
const double * nodes,
long nElems,
const long * elems,
long nPoints,
const double * points,
double alpha,
double * dirichlet,
int orderFar,
double * VChol,
double * KM,
bool verbose
);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment