Esempio n. 1
0
    void assemble_HM(const Geometry& geo, SymMatrix& mat, const unsigned gauss_order) 
    {
        mat = SymMatrix((geo.size()-geo.outermost_interface().nb_triangles()));
        mat.set(0.0);
        double K = 1.0 / (4.0 * M_PI);

        // We iterate over the meshes (or pair of domains) to fill the lower half of the HeadMat (since its symmetry)
        for ( Geometry::const_iterator mit1 = geo.begin(); mit1 != geo.end(); ++mit1) {

            for ( Geometry::const_iterator mit2 = geo.begin(); (mit2 != (mit1+1)); ++mit2) {

                // if mit1 and mit2 communicate, i.e they are used for the definition of a common domain
                const int orientation = geo.oriented(*mit1, *mit2); // equals  0, if they don't have any domains in common
                                                                       // equals  1, if they are both oriented toward the same domain
                                                                       // equals -1, if they are not

                if ( orientation != 0 ) {

                    double Scoeff =   orientation * geo.sigma_inv(*mit1, *mit2) * K;
                    double Dcoeff = - orientation * geo.indicator(*mit1, *mit2) * K;
                    double Ncoeff;

                    if ( !(mit1->outermost() || mit2->outermost()) ) {
                        // Computing S block first because it's needed for the corresponding N block
                        operatorS(*mit1, *mit2, mat, Scoeff, gauss_order);
                        Ncoeff = geo.sigma(*mit1, *mit2)/geo.sigma_inv(*mit1, *mit2);
                    } else {
                        Ncoeff = orientation * geo.sigma(*mit1, *mit2) * K;
                    }

                    if ( !mit1->outermost() ) {
                        // Computing D block
                        operatorD(*mit1, *mit2, mat, Dcoeff, gauss_order);
                    }
                    if ( ( *mit1 != *mit2 ) && ( !mit2->outermost() ) ) {
                        // Computing D* block
                        operatorD(*mit1, *mit2, mat, Dcoeff, gauss_order, true);
                    }

                    // Computing N block
                    operatorN(*mit1, *mit2, mat, Ncoeff, gauss_order);
                }
            }
        }

        // Deflate the diagonal block (N33) of 'mat' : (in order to have a zero-mean potential for the outermost interface)
        const Interface i = geo.outermost_interface();
        unsigned i_first = (*i.begin()->mesh().vertex_begin())->index();
        deflat(mat, i, mat(i_first, i_first) / (geo.outermost_interface().nb_vertices()));
    }
Esempio n. 2
0
    void deflat(T& M, const Geometry& geo)
    {
        //deflat all current barriers as one
        unsigned nb_vertices=0,i_first=0;
        double coef=0.0;
        for(std::vector<std::vector<std::string> >::const_iterator git=geo.geo_group().begin();git!=geo.geo_group().end();++git){
            nb_vertices=0;
            i_first=0;
            for(std::vector<std::string>::const_iterator mit=git->begin();mit!=git->end();++mit){
                const Mesh msh=geo.mesh(*mit);
                if(msh.outermost()){
                    nb_vertices+=msh.nb_vertices();
                    if(i_first==0)
                        i_first=(*msh.vertex_begin())->index();
                }
            }
            coef=M(i_first,i_first)/nb_vertices;
            for(std::vector<std::string>::const_iterator mit=git->begin();mit!=git->end();++mit){
                Mesh msh=geo.mesh(*mit);
                if(msh.outermost())
                    for(Mesh::const_vertex_iterator vit1=msh.vertex_begin();vit1!=msh.vertex_end();++vit1){
                        #pragma omp parallel for
                        #ifndef OPENMP_3_0
                        for (int i2=vit1-msh.vertex_begin();i2<msh.vertex_size();++i2) {
                            const Mesh::const_vertex_iterator vit2 = msh.vertex_begin()+i2;
                        #else
                        for (Mesh::const_vertex_iterator vit2=vit1;vit2<msh.vertex_end();++vit2) {
                        #endif
                            M((*vit1)->index(),(*vit2)->index()) += coef;
                        }
                    }
            }
        }
    }

    void assemble_HM(const Geometry& geo, SymMatrix& mat, const unsigned gauss_order) 
    {
        mat = SymMatrix((geo.size()-geo.nb_current_barrier_triangles()));
        mat.set(0.0);
        double K = 1.0 / (4.0 * M_PI);

        // We iterate over the meshes (or pair of domains) to fill the lower half of the HeadMat (since its symmetry)
        for(Geometry::const_iterator mit1 = geo.begin(); mit1 != geo.end(); ++mit1) {
            if(!mit1->isolated()){
                for(Geometry::const_iterator mit2 = geo.begin(); (mit2 != (mit1+1)); ++mit2) {
                    if((!mit2->isolated()) && (geo.sigma(*mit1,*mit2)!=0.0)){
                        // if mit1 and mit2 communicate, i.e they are used for the definition of a common domain
                        const int orientation = geo.oriented(*mit1, *mit2); // equals  0, if they don't have any domains in common
                                                                            // equals  1, if they are both oriented toward the same domain
                                                                            // equals -1, if they are not
                        if(orientation!=0){
                            double Scoeff =   orientation * geo.sigma_inv(*mit1, *mit2) * K;
                            double Dcoeff = - orientation * geo.indicator(*mit1, *mit2) * K;
                            double Ncoeff;

                            if( (!mit1->current_barrier()) && (!mit2->current_barrier()) ) {
                                // Computing S block first because it's needed for the corresponding N block
                                operatorS(*mit1, *mit2, mat, Scoeff, gauss_order);
                                Ncoeff = geo.sigma(*mit1, *mit2)/geo.sigma_inv(*mit1, *mit2);
                            }else{
                                Ncoeff = orientation * geo.sigma(*mit1, *mit2) * K;
                            }

                            if(!mit1->current_barrier()){
                                // Computing D block
                                operatorD(*mit1, *mit2, mat, Dcoeff, gauss_order,false);
                            }
                            if((*mit1!=*mit2) && (!mit2->current_barrier())){
                                // Computing D* block
                                operatorD(*mit1, *mit2, mat, Dcoeff, gauss_order, true);
                            }
                            // Computing N block
                            operatorN(*mit1, *mit2, mat, Ncoeff, gauss_order);
                        }
                    }
                }
            }
        }
        // Deflate all current barriers as one
        deflat(mat,geo);
    }