int usermult(Mat A, Vec x, Vec y) { // Wrap PETSc Vec as dolfin::PETScVector boost::shared_ptr<Vec> _x(&x, NoDeleter()); boost::shared_ptr<Vec> _y(&y, NoDeleter()); PETScVector __x(_x); PETScVector __y(_y); // Extract pointer to PETScLinearOperator void* ctx = 0; MatShellGetContext(A, &ctx); PETScLinearOperator* _A = ((PETScLinearOperator*) ctx); // Call user-defined mult function through wrapper dolfin_assert(_A); GenericLinearOperator* wrapper = _A->wrapper(); dolfin_assert(wrapper); wrapper->mult(__x, __y); return 0; }
bool readFreeFemFile( RegionMesh<LinearTriangle, MC> & mesh, const std::string & fileName, markerID_Type regionFlag, bool /*useless*/ = false) { MeshElementBareHandler<BareEdge> _be; std::pair<BareEdge, bool> _edge; typedef LinearTriangle GeoShape; typename RegionMesh<GeoShape, MC>::point_Type * pp = 0; typename RegionMesh<GeoShape, MC>::edge_Type * pe = 0; typename RegionMesh<GeoShape, MC>::face_Type * pf = 0; std::ifstream __is ( fileName.c_str() ); if( __is.fail() ) { std::cerr << " Error in readFreeFemFile: File " << fileName << " not found or locked" << std::endl; abort(); } // first row: how many vertices, triangles, edges UInt __nv, __nt, __ne, i1, i2, i3; __is >> __nv >> __nt >> __ne; #ifdef DEBUG debugStream ( 8000 ) << "number of vertices: "<< __nv << "\n"; debugStream ( 8000 ) << "number of triangles: "<< __nt << "\n"; debugStream ( 8000 ) << "number of edges: "<< __ne << "\n"; #endif // first section: read the list of vertices // on each row find the two coordinates and the label for each node std::vector<Real> __x(2*__nv); std::vector<bool> __isonboundary(__nv); std::vector<UInt> __whichboundary(__nv); #ifdef DEBUG debugStream ( 8000 ) << "reading "<< __nv << " nodes\n"; #endif // count the number of nodes on the boundary UInt __nbv( 0 ); // reading vertices for ( UInt __i = 0; __i < __nv; ++ __i ) { __is >> __x[ 2 * __i ] >> __x[ 2 * __i + 1 ] >> __whichboundary[ __i ]; __isonboundary[ __i ] = __whichboundary[ __i ]; __nbv += __isonboundary[ __i ]; } // second section: read the list of triangles // on each row find the three nodes and the label for each triangle std::vector<int> __triangle_nodes( 3 * __nt ); std::vector<int> __triangle_label( __nt ); #ifdef DEBUG debugStream ( 8000 ) << "reading "<< __nt << " triangles\n"; #endif std::map<UInt,UInt> edge_to_firstAdjacentElementIdentity, edge_to_firstAdjacentElementPosition; // reading vertices for ( UInt __i = 0; __i < __nt; ++__i ) { __is >> __triangle_nodes[ 3 * __i ] >> __triangle_nodes[ 3 * __i + 1 ] >> __triangle_nodes[ 3 * __i + 2 ] >> __triangle_label[ __i ]; //from 1-based numbering to 0-based numbering __triangle_nodes[3 * __i]--; __triangle_nodes[3 * __i+1]--; __triangle_nodes[3 * __i+2]--; // dump first the existing edges, to maintain the correct numbering // if everything is correct the numbering in the bareedge // structure will reflect the actual edge numbering std::pair<UInt, bool> _check; i1 = __triangle_nodes[ 3 * __i ]; i2 = __triangle_nodes[ 3 * __i + 1 ]; i3 = __triangle_nodes[ 3 * __i + 2 ]; _edge = makeBareEdge( i1, i2 ); _check = _be.addIfNotThere( _edge.first ); edge_to_firstAdjacentElementIdentity[ _check.first ] = __i; edge_to_firstAdjacentElementPosition[ _check.first ] = 0; _edge = makeBareEdge( i2, i3 ); _check = _be.addIfNotThere( _edge.first ); edge_to_firstAdjacentElementIdentity[ _check.first ] = __i; edge_to_firstAdjacentElementPosition[ _check.first ] = 1; _edge = makeBareEdge( i3, i1 ); _check = _be.addIfNotThere( _edge.first ); edge_to_firstAdjacentElementIdentity[ _check.first ] = __i; edge_to_firstAdjacentElementPosition[ _check.first ] = 2; } // ( __triangle[ 3 * i + 2] > __triangle[ 3 * i + 1 ] ) // third section: read the list of edges // NOTE: only boundary edges are stored // on each row find the two nodes and the label for each edge std::vector<int> __edge_nodes( 2 * __ne ); std::vector<int> __edge_label( __ne ); // reading edges for ( UInt __i = 0; __i < __ne; ++__i ) { __is >> __edge_nodes[ 2 * __i ] >> __edge_nodes[ 2 * __i + 1 ] >> __edge_label[ __i ]; } //from 1-based numbering to 0-based numbering for(UInt i(0); i<__edge_nodes.size(); i++) __edge_nodes[i]--; // Set mesh properties // Add Marker to list of Markers mesh.setMarkerID( regionFlag ); // Till now I only have information about boundary edges - I don't know the MAX num of edges // Euler formula: ne = nv + nt - 1 mesh.setMaxNumEdges ( _be.size() ); mesh.setMaxNumGlobalEdges( _be.size() ); // Here the REAL number of edges (all of them) mesh.setNumEdges ( _be.size() ); mesh.setNumBEdges ( __ne ); mesh.setMaxNumFaces ( __nt ); mesh.setMaxNumGlobalFaces( __nt ); // Here the REAL number of edges (all of them) mesh.setNumFaces ( __nt); mesh.setMaxNumPoints ( __nv, true ); mesh.setMaxNumGlobalPoints( __nv ); mesh.setNumVertices ( __nv ); mesh.setNumGlobalVertices ( __nv ); mesh.numBVertices() = __nbv; mesh.setNumBPoints( mesh.numBVertices() ); #ifdef DEBUG debugStream ( 8000 ) << "number of points : " << mesh.numPoints() << "\n"; debugStream ( 8000 ) << "number of boundary points : " << mesh.numBPoints() << "\n"; debugStream ( 8000 ) << "number of vertices : " << mesh.numVertices() << "\n"; debugStream ( 8000 ) << "number of boundary vertices : " << mesh.numBVertices() << "\n"; #endif for ( UInt __i = 0; __i < __nv; ++__i ) { pp = &mesh.addPoint( __isonboundary[ __i ], true ); pp->setMarkerID( __whichboundary[ __i ] ); pp->x() = __x[ 2 * __i ]; pp->y() = __x[ 2 * __i + 1 ]; pp->z() = 0; pp->setId( __i ); } // add the edges to the mesh for ( UInt __i = 0; __i < __ne; ++__i ) { pe = &( mesh.addEdge( true ) ); pe->setMarkerID( markerID_Type( __edge_label[ __i ] ) ); pe->setPoint( 0, mesh.point( __edge_nodes[ 2 * __i ] ) ); pe->setPoint( 1, mesh.point( __edge_nodes[ 2 * __i + 1 ] ) ); pe->setId( __i ); _edge = makeBareEdge( __edge_nodes[ 2 * __i ], __edge_nodes[ 2 * __i + 1 ] ); UInt map_it( _be.id( _edge.first ) ); pe->firstAdjacentElementIdentity() = edge_to_firstAdjacentElementIdentity[ map_it ]; pe->firstAdjacentElementPosition() = edge_to_firstAdjacentElementPosition[ map_it ]; } // add the triangles to the mesh for ( UInt __i = 0; __i < __nt; ++__i ) { pf = &( mesh.addFace(true) ); pf->setId( __i ); pf->setMarkerID( markerID_Type( __triangle_label[ __i ] ) ); pf->setPoint( 0, mesh.point( __triangle_nodes[ 3 * __i ] ) ); pf->setPoint( 1, mesh.point( __triangle_nodes[ 3 * __i + 1 ] ) ); pf->setPoint( 2, mesh.point( __triangle_nodes[ 3 * __i + 2 ] ) ); } return true; } // Function readFreeFemFile