RVector3 MeshEntity::grad(const RVector3 & xyz, const RVector & u) const { RVector3 rst(shape_->rst(xyz)); RMatrix MdNdL; MdNdL.push_back(dNdL(rst, 0)); MdNdL.push_back(dNdL(rst, 1)); MdNdL.push_back(dNdL(rst, 2)); RVector up(u(this->ids())); RVector3 gr; gr[0] = sum(up * MdNdL.transMult(shape_->invJacobian().col(0))); gr[1] = sum(up * MdNdL.transMult(shape_->invJacobian().col(1))); gr[2] = sum(up * MdNdL.transMult(shape_->invJacobian().col(2))); return gr; }
void interpolate(const Mesh & mesh, const std::string & dataName, Mesh & pos, bool verbose){ RMatrix vData; vData.push_back(mesh.exportData(dataName)); RMatrix viData; interpolate(mesh, vData, pos.positions(), viData, verbose); pos.addExportData(dataName, viData[0]); }
void interpolate(const Mesh & mesh, const RVector & data, const R3Vector & pos, RVector & iData, bool verbose){ RMatrix vData; vData.push_back(data); RMatrix viData; interpolate(mesh, vData, pos, viData, verbose); iData = viData[0]; }
void interpolate(const Mesh & mesh, Mesh & qmesh, bool verbose){ RMatrix cellData; RMatrix nodeData; std::vector< std::string > cellDataNames; std::vector< std::string > nodeDataNames; for (std::map< std::string, RVector >::const_iterator it = mesh.exportDataMap().begin(); it != mesh.exportDataMap().end(); it ++){ if (it->second.size() == mesh.nodeCount()){ if (verbose) std::cout << " interpolate node data: " << it->first << std::endl; nodeData.push_back(it->second); nodeDataNames.push_back(it->first); } else if (it->second.size() == mesh.cellCount()){ if (verbose) std::cout << " interpolate cell data: " << it->first << std::endl; cellData.push_back(it->second); cellDataNames.push_back(it->first); } else { if (verbose) std::cout << " omit unknown data: " << it->first << " " << it->second.size()<< std::endl; } } if (cellData.rows() > 0){ RMatrix qCellData; interpolate(mesh, cellData, qmesh.cellCenter(), qCellData, verbose) ; for (uint i= 0; i < cellData.rows(); i ++){ qmesh.addExportData(cellDataNames[i], qCellData[i]); } } if (nodeData.rows() > 0){ RMatrix qNodeData; interpolate(mesh, nodeData, qmesh.positions(), qNodeData, verbose) ; for (uint i= 0; i < nodeData.rows(); i ++){ qmesh.addExportData(nodeDataNames[i], qNodeData[i]); } } }
int main( int argc, char *argv [] ){ bool lambdaOpt = false, isRobust = false, isBlocky = false, doResolution = false; bool useAppPar = false, useTan = false, useWater = false, optimizeChi1 = false; double lambda = 1, lbound = 0, ubound = 0, errbabs = 20; int maxIter = 10, verboseCount = 0, ctype = 0; std::string matFile( "A.mat" ), bFile( "b.vec" ); OptionMap oMap; oMap.setDescription("Description. InvLinearMat - Linear Inversion with given matrix and vector\n"); oMap.addLastArg( bFile, "Data file" ); oMap.add( verboseCount, "v" , "verbose", "Verbose/debug/dosave mode (multiple use)." ); oMap.add( lambdaOpt, "O" , "OptimizeLambda", "Optimize model smoothness using L-curve." ); oMap.add( optimizeChi1, "C" , "OptimizeChi1", "Optimize lambda subject to chi^2=1." ); oMap.add( doResolution, "D" , "doResolution", "Do resolution analysis." ); oMap.add( isRobust, "R" , "RobustData", "Robust (L1) data weighting." ); oMap.add( isBlocky, "B" , "BlockyModel", "Blocky (L1) model constraints." ); oMap.add( useTan, "T" , "useTan", "Use (co-)Tan instead of Log for LU." ); oMap.add( useAppPar, "A" , "useAppPar", "Use apparent parameter transformation." ); oMap.add( useWater, "W" , "useWater", "Use water content transformation." ); oMap.add( matFile, "m:", "matFile", "Matrix file [A.mat]" ); oMap.add( lambda, "l:", "lambda", "Regularization strength lambda[100]." ); oMap.add( lbound, "b:", "lbound", "Lower parameter bound[0]" ); oMap.add( ubound, "u:", "ubound", "Upper parameter bound[0-inactive]" ); oMap.add( errbabs, "e:", "error", "Absolute error level" ); oMap.add( maxIter, "i:", "maxIter", "Maximum Iteration number" ); oMap.parse( argc, argv ); bool verbose = ( verboseCount > 0 ), debug = ( verboseCount > 1 ), dosave = ( verboseCount > 2 ); RMatrix A; if ( ! loadMatrixSingleBin( A, matFile ) ) { std::cerr << "Did not find A.mat!" << std::endl; return EXIT_OPEN_FILE; } RVector b; load( b, bFile ); size_t nModel( A.cols() ); dcout << "size(A) = " << A.rows() << "x" << nModel << "size(b) = " << b.size() << std::endl; RVector Asum( A * RVector( nModel, 1.0 ) ); RVector xapp( b / Asum ); DEBUG save( xapp, "xapp.vec" ); dcout << "apparent x: min/max = " << min( xapp ) << "/" << max( xapp ) << std::endl; Mesh mesh( createMesh1D( nModel ) ); DEBUG mesh.save( "mesh1d.bms" ); mesh.showInfos(); for ( size_t i = 0; i < mesh.cellCount(); i ++ ) mesh.cell( i ).setAttribute( 2.0 + i ); mesh.createNeighbourInfos(); LinearModelling f( mesh, A, verbose ); f.regionManager().region( 0 )->setConstraintType( ctype ); Trans < RVector > * transData; Trans < RVector > * transModel; if ( useAppPar ) { if ( useTan ) { if ( ubound <= lbound ) ubound = lbound + 1.0; transData = new TransNest< RVector >( *new TransCotLU< RVector >( lbound, ubound ), *new TransLinear< RVector >( RVector( xapp / b ) ) ); transModel = new TransCotLU< RVector >( lbound, ubound ); } else { transData = new TransNest< RVector >( *new TransLogLU< RVector >( lbound, ubound ), *new TransLinear< RVector >( RVector( xapp / b ) ) ); transModel = new TransLogLU< RVector >( lbound, ubound ); } } else { transData = new Trans< RVector >( ); transModel = new Trans< RVector >( ); } /*! set up inversion */ RInversion inv( b, f, *transData, *transModel, verbose, dosave ); inv.setRecalcJacobian( false ); //! no need since it is linear inv.setLambda( lambda ); inv.setOptimizeLambda( lambdaOpt ); inv.setRobustData( isRobust ); inv.setBlockyModel( isBlocky ); inv.setMaxIter( maxIter ); inv.setDeltaPhiAbortPercent( 1.0 ); RVector error( errbabs / b); vcout << "error: min/max = " << min( error ) << "/" << max( error ) << std::endl; inv.setError( error ); RVector x( nModel, mean( xapp ) ); inv.setModel( x ); inv.setReferenceModel( x ); if ( optimizeChi1 ) { x = inv.runChi1(); } else { x = inv.run(); } vcout << "x = " << x << std::endl; save( x, "x.vec" ); if ( doResolution ) { RVector resolution( nModel ); RVector resMDiag ( nModel ); RMatrix resM; for ( size_t iModel = 0; iModel < nModel; iModel++ ) { resolution = inv.modelCellResolution( iModel ); resM.push_back( resolution ); resMDiag[ iModel ] = resolution[ iModel ]; } save( resMDiag, "resMDiag.vec" ); save( resM, "resolution.matrix" ); } delete transData; delete transModel; return EXIT_SUCCESS; }
int main( int argc, char *argv [] ) { bool lambdaOpt = false, doResolution = false, useTan = false, optimizeChi1 = false; double lambda = 10.0, lambdaIP = 1.0, lbound = 0.0, ubound = 0.0, errPerc = 3.0; int maxIter = 10, nlay = 3, verboseCount = 0, linCount = 0; std::string modelFile( NOT_DEFINED ), dataFileName; OptionMap oMap; oMap.setDescription("Description. DC1dInv - 1D block inversion of dc resistivity data\n"); oMap.addLastArg( dataFileName, "Data file" ); oMap.add( verboseCount, "v" , "verbose", "Verbose/debug/dosave mode (multiple use)." ); oMap.add( lambdaOpt, "O" , "OptimizeLambda", "Optimize model smoothness using L-curve." ); oMap.add( doResolution, "D" , "doResolution", "Do resolution analysis." ); oMap.add( optimizeChi1, "C" , "OptimizeChi1", "Optimize lambda subject to chi^2=1." ); oMap.add( useTan, "T" , "useTan", "Use (co-)Tan instead of Log for LU." ); oMap.add( linCount, "L" , "dataLin", "Use linear trafo for data, 2x also for model." ); oMap.add( maxIter, "i:", "maxIter", "Maximum iteration number." ); oMap.add( lambda, "l:", "lambda", "Regularization strength lambda." ); oMap.add( lambdaIP, "r:", "lambdaIP", "Regularization strength lambda for IP." ); oMap.add( errPerc, "e:", "error", "Error percentage" ); oMap.add( nlay, "n:", "nlay", "Number of layers" ); oMap.add( lbound, "b:", "lbound", "Lower Resistivity bound" ); oMap.add( ubound, "u:", "ubound", "Upper Resistivity bound" ); oMap.add( modelFile, "m:", "modelFile", "Model file for pure modelling. file: thick_i rho_i\\n" ); oMap.parse( argc, argv ); bool verbose = ( verboseCount > 0 ), debug = ( verboseCount > 1 ), dosave = ( verboseCount > 2 ); bool dataLin = ( linCount > 0 ), modelLin = ( linCount > 1 ); /*! Data: read data file from column file */ RMatrix abmnr; loadMatrixCol( abmnr, dataFileName ); //! read data RVector ab2( abmnr[ 0 ] ); //! first column RVector mn2( abmnr[ 1 ] ); //! second column RVector rhoa( abmnr[ 2 ] ); //! third column /*! Define discretization according to AB/2 */ double maxDep = max( ab2 ) / 2; //! rule of thumb std::cout << "Maximum depth estimated to " << maxDep << std::endl; DC1dModelling f( nlay, ab2, mn2, debug ); /*! Error estimation */ double current = 0.1, errVolt = 0;//1e-4; RVector voltage( rhoa * f( RVector( 3, 1.0 ) ) * current ); RVector error = errVolt / voltage + errPerc / 100.0; vcout << "error min/max = " << min( error ) << "/" << max( error ) << std::endl; /*! Transformations: log for app. resisivity and thickness, logLU for resistivity */ // TransLog< RVector > transThk; // TransLogLU< RVector > transRho( lbound, ubound ); // TransLog< RVector > transRhoa; Trans< RVector > *transThk, *transRho, *transRhoa; if ( modelLin ) { transThk = new Trans< RVector >; transRho = new Trans< RVector >; } else { transThk = new TransLog< RVector >; if ( useTan ) { transRho = new TransCotLU< RVector >( lbound, ubound ); } else { transRho = new TransLogLU< RVector >( lbound, ubound ); } } if ( dataLin ) { transRhoa = new Trans< RVector >; } else { transRhoa = new TransLog< RVector >; } f.region( 0 )->setTransModel( *transThk ); f.region( 1 )->setTransModel( *transRho ); double paraDepth = max( ab2 ) / 3; vcout << "Paradepth = " << paraDepth << std::endl; f.region( 0 )->setStartValue( paraDepth / nlay / 2.0 ); f.region( 1 )->setStartValue( median( rhoa ) ); RVector model;//( f.createDefaultStartModel() ); model = f.createStartVector(); // model[ nlay ] *= 1.5; //! in order to make thicknesses sensitive DEBUG save( model, "start.vec" ); /*! Set up inversion with full matrix, data and forward operator */ RInversion inv( rhoa, f, verbose, dosave ); inv.setTransData( *transRhoa ); inv.setMarquardtScheme( 0.8 ); //! 0th order local decreasing regularization inv.setLambda( lambda ); inv.setOptimizeLambda( lambdaOpt ); inv.setMaxIter( maxIter ); inv.setRelativeError( error ); //! error model inv.setModel( model ); //! starting model inv.setDeltaPhiAbortPercent( 0.5 ); /*! actual computation: run the inversion */ if ( optimizeChi1 ) { model = inv.runChi1( 0.1 ); } else { model = inv.run(); } RVector thk( nlay - 1 ); RVector res( nlay ); for ( int i = 0 ; i < nlay - 1 ; i++ ) thk[ i ] = model[ i ]; for ( int i = 0 ; i < nlay ; i++ ) res[ i ] = model[ nlay - 1 + i ]; save( res, "resistivity.vec" ); save( thk, "thickness.vec" ); save( inv.response(), "response.vec" ); if ( verbose ) { RVector cumz( thk ); for ( size_t i = 1 ; i < thk.size() ; i++ ) cumz[i] = cumz[ i-1 ] + thk[i]; cumz.round(0.1); res.round(0.1); std::cout << "Res = " << res << std::endl; std::cout << " z = " << cumz << std::endl; } if ( abmnr.cols() > 3 ) { //** IP present // if ( verbose ) std::cout << "Found ip values, doing ip inversion" << std::endl; //! imaginary apparent resistivity RVector rhoai( rhoa * sin( abmnr[ 3 ] / 1000. ) ); //! modelling operator from fixed layer Mesh ipMesh( createMesh1D( nlay ) ); DC1dRhoModelling fIP( thk, ab2, mn2, verbose ); fIP.region( 0 )->setTransModel( *transRho ); //! IP (imaginary resistivity) inversion using fIP RInversion invIP( rhoai, fIP, verbose ); invIP.setAbsoluteError( rhoai / abmnr[ 3 ] * 1.0 ); //! take jacobian from real valued problems invIP.setModel( res ); invIP.checkJacobian(); //! force jacobian calculation invIP.setRecalcJacobian( false ); invIP.setLambda( lambdaIP ); invIP.setLocalRegularization( true ); //! Marquardt method invIP.setModel( model ); //! starting model invIP.stopAtChi1( false ); RVector ipModel( nlay, median( rhoai ) ); invIP.setModel( ipModel ); ipModel = invIP.run(); RVector phase = atan( ipModel / res ) * 1000.; save( phase, "phase.vec" ); RVector aphase = atan( invIP.response() / rhoa ) * 1000.; save( aphase, "aphase.vec" ); std::cout << " ip = " << phase << std::endl; } if ( doResolution ) { size_t nModel( 2 * nlay - 1 ); RVector resolution( nModel ); RVector resMDiag ( nModel ); RMatrix resM; for ( size_t iModel = 0; iModel < nModel; iModel++ ) { resolution = inv.modelCellResolution( iModel ); resM.push_back( resolution ); resMDiag[ iModel ] = resolution[ iModel ]; } save( resMDiag, "resMDiag.vec" ); save( resM, "resM" ); vcout << "diagRM = " << resMDiag << std::endl; } return EXIT_SUCCESS; }