コード例 #1
0
ファイル: subspaceit.C プロジェクト: aishugang/oofem
NM_Status
SubspaceIteration :: solve(SparseMtrx &a, SparseMtrx &b, FloatArray &_eigv, FloatMatrix &_r, double rtol, int nroot)
//
// this function solve the generalized eigenproblem using the Generalized
// jacobi iteration
//
{
    if ( a.giveNumberOfColumns() != b.giveNumberOfColumns() ) {
        OOFEM_ERROR("matrices size mismatch");
    }

    FloatArray temp, w, d, tt, f, rtolv, eigv;
    FloatMatrix r;
    int nn, nc1, ij = 0, is;
    double rt, art, brt, eigvt;
    FloatMatrix ar, br, vec;
    std :: unique_ptr< SparseLinearSystemNM > solver( GiveClassFactory().createSparseLinSolver(ST_Direct, domain, engngModel) );

    GJacobi mtd(domain, engngModel);
    int nc = min(2 * nroot, nroot + 8);
    nn = a.giveNumberOfColumns();
    if ( nc > nn ) {
        nc = nn;
    }

    ar.resize(nc, nc);
    ar.zero();
    br.resize(nc, nc);
    br.zero();

    //
    // creation of initial iteration vectors
    //
    nc1 = nc - 1;

    w.resize(nn);
    w.zero();
    d.resize(nc);
    d.zero();
    tt.resize(nn);
    tt.zero();
    rtolv.resize(nc);
    rtolv.zero();
    vec.resize(nc, nc);
    vec.zero();                   // eigen vectors of reduced problem

    //
    // create work arrays
    //
    r.resize(nn, nc);
    r.zero();
    eigv.resize(nc);
    eigv.zero();

    FloatArray h(nn);
    for ( int i = 1; i <= nn; i++ ) {
        h.at(i) = 1.0;
        w.at(i) = b.at(i, i) / a.at(i, i);
    }

    b.times(h, tt);
    r.setColumn(tt, 1);

    for ( int j = 2; j <= nc; j++ ) {
        rt = 0.0;
        for ( int i = 1; i <= nn; i++ ) {
            if ( fabs( w.at(i) ) >= rt ) {
                rt = fabs( w.at(i) );
                ij = i;
            }
        }

        tt.at(j) = ij;
        w.at(ij) = 0.;
        for ( int i = 1; i <= nn; i++ ) {
            if ( i == ij ) {
                h.at(i) = 1.0;
            } else {
                h.at(i) = 0.0;
            }
        }

        b.times(h, tt);
        r.setColumn(tt, j);
    } // (r = z)

# ifdef DETAILED_REPORT
    OOFEM_LOG_INFO("SubspaceIteration :: solveYourselfAt: Degrees of freedom invoked by initial vectors :\n");
    tt.printYourself();
    OOFEM_LOG_INFO("SubspaceIteration :: solveYourselfAt: initial vectors for iteration:\n");
    r.printYourself();
# endif

    //ish = 0;
    a.factorized();
    //
    // start of iteration loop
    //
    for ( int nite = 0; ; ++nite ) {               // label 100
# ifdef DETAILED_REPORT
        printf("SubspaceIteration :: solveYourselfAt: Iteration loop no. %d\n", nite);
# endif
        //
        // compute projection ar and br of matrices a , b
        //
        for ( int j = 1; j <= nc; j++ ) {
            f.beColumnOf(r, j);

            solver->solve(a, f, tt);

            for ( int i = j; i <= nc; i++ ) {
                art = 0.;
                for ( int k = 1; k <= nn; k++ ) {
                    art += r.at(k, i) * tt.at(k);
                }

                ar.at(j, i) = art;
            }

            r.setColumn(tt, j);            // (r = xbar)
        }

        ar.symmetrized();        // label 110
#ifdef DETAILED_REPORT
        OOFEM_LOG_INFO("SubspaceIteration :: solveYourselfAt: Printing projection matrix ar\n");
        ar.printYourself();
#endif
        //
        for ( int j = 1; j <= nc; j++ ) {
            tt.beColumnOf(r, j);

            b.times(tt, temp);
            for ( int i = j; i <= nc; i++ ) {
                brt = 0.;
                for ( int k = 1; k <= nn; k++ ) {
                    brt += r.at(k, i) * temp.at(k);
                }

                br.at(j, i) = brt;
            }                   // label 180

            r.setColumn(temp, j);        // (r=zbar)
        }                       // label 160

        br.symmetrized();
#ifdef DETAILED_REPORT
        OOFEM_LOG_INFO("SubspaceIteration :: solveYourselfAt: Printing projection matrix br\n");
        br.printYourself();
#endif

        //
        // solution of reduced eigenvalue problem
        //
        mtd.solve(ar, br, eigv, vec);

        // START EXPERIMENTAL
#if 0
        // solve the reduced problem by Inverse iteration
        {
            FloatMatrix x(nc,nc), z(nc,nc), zz(nc,nc), arinv;
            FloatArray  w(nc), ww(nc), tt(nc), t(nc);
            double c;

            //  initial setting
            for ( int i = 1;i <= nc; i++ ) {
                ww.at(i)=1.0;
            }
            
            
            for ( int i = 1;i <= nc; i++ )
                for ( int j = 1; j <= nc;j++ )
                    z.at(i,j)=1.0;
            
            arinv.beInverseOf (ar);
            
            for ( int i = 0;i < nitem; i++ ) {
                //  copy zz=z
                zz = z;
                
                // solve matrix equation K.X = M.X
                x.beProductOf(arinv, z);
                //  evaluation of Rayleigh quotients
                for ( int j = 1;j <= nc; j++ ) {
                    w.at(j) = 0.0;
                    for (k = 1; k<= nc; k++) w.at(j) += zz.at(k,j) * x.at(k,j);
                }

                z.beProductOf (br, x);

                for ( int j = 1;j <= nc; j++ ) {
                    c = 0;
                    for ( int k = 1; k<= nc; k++ ) c += z.at(k,j) * x.at(k,j);
                    w.at(j) /= c;
                }

                //  check convergence
                int ac = 0;
                for ( int j = 1;j <= nc; j++ ) {
                    if (fabs((ww.at(j)-w.at(j))/w.at(j))< rtol)  ac++;
                    ww.at(j) = w.at(j);
                }

                //printf ("\n iterace cislo  %d   %d",i,ac);
                //w.printYourself();

                //  Gramm-Schmidt ortogonalization
                for ( int j = 1;j <= nc;j++ ) {
                    for ( int k = 1; k<= nc; k++ ) tt.at(k) = x.at(k,j);
                    t.beProductOf(br,tt) ;
                    for ( int ii = 1;ii < j; ii++ ) {
                        c = 0.0;
                        for ( int k = 1; k<= nc; k++ ) c += x.at(k,ii) * t.at(k);
                        for ( int k = 1; k<= nc; k++ ) x.at(k,j) -= x.at(k,ii) * c;
                    }
                    for ( int k = 1; k<= nc; k++) tt.at(k) = x.at(k,j);
                    t.beProductOf(br, tt);
                    c = 0.0;
                    for ( int k = 1; k<= nc; k++) c += x.at(k,j)*t.at(k);
                    for ( int k = 1; k<= nc; k++) x.at(k,j) /= sqrt(c);
                }

                if ( ac > nroot ) {
                    break;
                }

                //  compute new approximation of Z
                z.beProductOf(br,x);
            }
            
            eigv = w;
            vec = x;
        }
#endif


        //
        // sorting eigenvalues according to their values
        //
        do {
            is = 0; // label 350
            for ( int i = 1; i <= nc1; i++ ) {
                if ( fabs( eigv.at(i + 1) ) < fabs( eigv.at(i) ) ) {
                    is++;
                    eigvt = eigv.at(i + 1);
                    eigv.at(i + 1) = eigv.at(i);
                    eigv.at(i)   = eigvt;
                    for ( int k = 1; k <= nc; k++ ) {
                        rt = vec.at(k, i + 1);
                        vec.at(k, i + 1) = vec.at(k, i);
                        vec.at(k, i)   = rt;
                    }
                }
            }                   // label 360
        } while ( is != 0 );

# ifdef DETAILED_REPORT
        OOFEM_LOG_INFO("SubspaceIteration :: solveYourselfAt: current eigen values of reduced problem \n");
        eigv.printYourself();
        OOFEM_LOG_INFO("SubspaceIteration :: solveYourselfAt: current eigen vectors of reduced problem \n");
        vec.printYourself();
# endif
        //
        // compute eigenvectors
        //
        for ( int i = 1; i <= nn; i++ ) { // label 375
            for ( int j = 1; j <= nc; j++ ) {
                tt.at(j) = r.at(i, j);
            }

            for ( int k = 1; k <= nc; k++ ) {
                rt = 0.;
                for ( int j = 1; j <= nc; j++ ) {
                    rt += tt.at(j) * vec.at(j, k);
                }

                r.at(i, k) = rt;
            }
        }                       // label 420   (r = z)

        //
        // convergency check
        //
        for ( int i = 1; i <= nc; i++ ) {
            double dif = ( eigv.at(i) - d.at(i) );
            rtolv.at(i) = fabs( dif / eigv.at(i) );
        }

# ifdef DETAILED_REPORT
        OOFEM_LOG_INFO("SubspaceIteration :: solveYourselfAt: Reached precision of eigenvalues:\n");
        rtolv.printYourself();
# endif
        for ( int i = 1; i <= nroot; i++ ) {
            if ( rtolv.at(i) > rtol ) {
                goto label400;
            }
        }

        OOFEM_LOG_INFO("SubspaceIteration :: solveYourselfAt: Convergence reached for RTOL=%20.15f\n", rtol);
        break;
label400:
        if ( nite >= nitem ) {
            OOFEM_WARNING("SubspaceIteration :: solveYourselfAt: Convergence not reached in %d iteration - using current values", nitem);
            break;
        }

        d = eigv;                     // label 410 and 440

        continue;
    }


    // compute eigenvectors
    for ( int j = 1; j <= nc; j++ ) {
        tt.beColumnOf(r, j);

        a.backSubstitutionWith(tt);
        r.setColumn(tt, j);                          // r = xbar
    }

    // one cad add a normalization of eigen-vectors here

    // initialize original index locations
    _r.resize(nn, nroot);
    _eigv.resize(nroot);
    for ( int i = 1; i <= nroot; i++ ) {
        _eigv.at(i) = eigv.at(i);
        for ( int j = 1; j <= nn; j++ ) {
            _r.at(j, i) = r.at(j, i);
        }
    }

    return NM_Success;
}
コード例 #2
0
ファイル: classfactory.C プロジェクト: xyuan/oofem
namespace oofem {
ClassFactory &GiveClassFactory()
{
    static ClassFactory ans;
    return ans;
}

ClassFactory &classFactory = GiveClassFactory();

std :: string conv2lower(const char *input)
{
    std :: string line(input);
    for ( std :: size_t i = 0; i < line.size(); i++ ) {
        line [ i ] = std :: tolower(line [ i ]);
    }
    return line;
}

ClassFactory :: ClassFactory()
{
    // Fixed list for DOF types. No new components can register for these since these are part of the internal structure in OOFEM.
    dofList [ DT_master ] = dofCreator< MasterDof >;
    dofList [ DT_simpleSlave ] = dofCreator< SimpleSlaveDof >;
    dofList [ DT_slave ] = dofCreator< SlaveDof >;
    dofList [ DT_active ] = dofCreator< ActiveDof >;

#ifdef __PARALLEL_MODE
    loadBalancerList [ "parmetis" ] = loadBalancerCreator< ParmetisLoadBalancer >;
    loadMonitorList [ "wallclock" ] = loadMonitorCreator< WallClockLoadBalancerMonitor >;
#endif
}

SparseMtrx *ClassFactory :: createSparseMtrx(SparseMtrxType name)
{
    return ( sparseMtrxList.count(name) == 1 ) ? sparseMtrxList [ name ]() : NULL;
}

bool ClassFactory :: registerSparseMtrx( SparseMtrxType name, SparseMtrx * ( *creator )( ) )
{
    sparseMtrxList [ name ] = creator;
    return true;
}

Dof *ClassFactory :: createDof(dofType name, int num, DofManager *dman)
{
    return ( dofList.count(name) == 1 ) ? dofList [ name ](num, dman) : NULL;
}

SparseLinearSystemNM *ClassFactory :: createSparseLinSolver(LinSystSolverType name, Domain *d, EngngModel *m)
{
    return ( sparseLinSolList.count(name) == 1 ) ? sparseLinSolList [ name ](d, m) : NULL;
}

bool ClassFactory :: registerSparseLinSolver( LinSystSolverType name, SparseLinearSystemNM * ( *creator )( Domain *, EngngModel * ) )
{
    sparseLinSolList [ name ] = creator;
    return true;
}

ErrorEstimator *ClassFactory :: createErrorEstimator(ErrorEstimatorType name, int num, Domain *d)
{
    return ( errEstList.count(name) == 1 ) ? errEstList [ name ](num, d) : NULL;
}

bool ClassFactory :: registerErrorEstimator( ErrorEstimatorType name, ErrorEstimator * ( *creator )( int, Domain * ) )
{
    errEstList [ name ] = creator;
    return true;
}

InitialCondition *ClassFactory :: createInitialCondition(const char *name, int num, Domain *d)
{
    if ( conv2lower(name).compare("initialcondition") == 0 ) {
        return new InitialCondition(num, d);
    }
    return NULL;
}

NodalRecoveryModel *ClassFactory :: createNodalRecoveryModel(NodalRecoveryModel :: NodalRecoveryModelType type, Domain *d)
{
    if ( type == NodalRecoveryModel :: NRM_NodalAveraging ) {
        return new NodalAveragingRecoveryModel(d);
    } else if ( type == NodalRecoveryModel :: NRM_ZienkiewiczZhu ) {
        return new ZZNodalRecoveryModel(d);
    } else if ( type == NodalRecoveryModel :: NRM_SPR ) {
        return new SPRNodalRecoveryModel(d);
    }
    return NULL;
}


Element *ClassFactory :: createElement(const char *name, int number, Domain *domain)
{
    return ( elemList.count(name) == 1 ) ? elemList [ conv2lower(name) ](number, domain) : NULL;
}

bool ClassFactory :: registerElement( const char *name, Element * ( *creator )( int, Domain * ) )
{
    elemList [ conv2lower(name) ] = creator;
    return true;
}

DofManager *ClassFactory :: createDofManager(const char *name, int number, Domain *domain)
{
    return ( dofmanList.count(name) == 1 ) ? dofmanList [ conv2lower(name) ](number, domain) : NULL;
}

bool ClassFactory :: registerDofManager( const char *name, DofManager * ( *creator )( int, Domain * ) )
{
    dofmanList [ conv2lower(name) ] = creator;
    return true;
}

GeneralBoundaryCondition *ClassFactory :: createBoundaryCondition(const char *name, int number, Domain *domain)
{
    return ( bcList.count(name) == 1 ) ? bcList [ conv2lower(name) ](number, domain) : NULL;
}

bool ClassFactory :: registerBoundaryCondition( const char *name, GeneralBoundaryCondition * ( *creator )( int, Domain * ) )
{
    bcList [ conv2lower(name) ] = creator;
    return true;
}

CrossSection *ClassFactory :: createCrossSection(const char *name, int number, Domain *domain)
{
    return ( csList.count(name) == 1 ) ? csList [ conv2lower(name) ](number, domain) : NULL;
}

bool ClassFactory :: registerCrossSection( const char *name, CrossSection * ( *creator )( int, Domain * ) )
{
    csList [ conv2lower(name) ] = creator;
    return true;
}

Material *ClassFactory :: createMaterial(const char *name, int number, Domain *domain)
{
    return ( matList.count(conv2lower(name).c_str()) == 1 ) ? matList [ conv2lower(name) ](number, domain) : NULL;
}

bool ClassFactory :: registerMaterial( const char *name, Material * ( *creator )( int, Domain * ) )
{
    matList [ conv2lower(name) ] = creator;
    return true;
}

EngngModel *ClassFactory :: createEngngModel(const char *name, int number, EngngModel *master)
{
    return ( engngList.count(name) == 1 ) ? engngList [ conv2lower(name) ](number, master) : NULL;
}

bool ClassFactory :: registerEngngModel( const char *name, EngngModel * ( *creator )( int, EngngModel * ) )
{
    engngList [ conv2lower(name) ] = creator;
    return true;
}

Function *ClassFactory :: createFunction(const char *name, int number, Domain *domain)
{
    return ( funcList.count(name) == 1 ) ? funcList [ conv2lower(name) ](number, domain) : NULL;
}

bool ClassFactory :: registerFunction( const char *name, Function * ( *creator )( int, Domain * ) )
{
    funcList [ conv2lower(name) ] = creator;
    return true;
}

NonlocalBarrier *ClassFactory :: createNonlocalBarrier(const char *name, int number, Domain *domain)
{
    return ( nlbList.count(name) == 1 ) ? nlbList [ conv2lower(name) ](number, domain) : NULL;
}

bool ClassFactory :: registerNonlocalBarrier( const char *name, NonlocalBarrier * ( *creator )( int, Domain * ) )
{
    nlbList [ conv2lower(name) ] = creator;
    return true;
}

RandomFieldGenerator *ClassFactory :: createRandomFieldGenerator(const char *name, int number, Domain *domain)
{
    return ( rfgList.count(name) == 1 ) ? rfgList [ conv2lower(name) ](number, domain) : NULL;
}

bool ClassFactory :: registerRandomFieldGenerator( const char *name, RandomFieldGenerator * ( *creator )( int, Domain * ) )
{
    rfgList [ conv2lower(name) ] = creator;
    return true;
}

ExportModule *ClassFactory :: createExportModule(const char *name, int number, EngngModel *emodel)
{
    return ( exportList.count(name) == 1 ) ? exportList [ conv2lower(name) ](number, emodel) : NULL;
}

bool ClassFactory :: registerExportModule( const char *name, ExportModule * ( *creator )( int, EngngModel * ) )
{
    exportList [ conv2lower(name) ] = creator;
    return true;
}

SparseNonLinearSystemNM *ClassFactory :: createNonLinearSolver(const char *name, Domain *d, EngngModel *emodel)
{
    return ( nonlinList.count(name) == 1 ) ? nonlinList [ conv2lower(name) ](d, emodel) : NULL;
}

bool ClassFactory :: registerSparseNonLinearSystemNM( const char *name, SparseNonLinearSystemNM * ( *creator )( Domain *, EngngModel * ) )
{
    nonlinList [ conv2lower(name) ] = creator;
    return true;
}

InitModule *ClassFactory :: createInitModule(const char *name, int number, EngngModel *emodel)
{
    return ( initList.count(name) == 1 ) ? initList [ conv2lower(name) ](number, emodel) : NULL;
}

bool ClassFactory :: registerInitModule( const char *name, InitModule * ( *creator )( int, EngngModel * ) )
{
    initList [ conv2lower(name) ] = creator;
    return true;
}

TopologyDescription *ClassFactory :: createTopology(const char *name, Domain *domain)
{
    return ( topologyList.count(name) == 1 ) ? topologyList [ conv2lower(name) ](domain) : NULL;
}

bool ClassFactory :: registerTopologyDescription( const char *name, TopologyDescription * ( *creator )( Domain * ) )
{
    topologyList [ conv2lower(name) ] = creator;
    return true;
}


// XFEM:
EnrichmentItem *ClassFactory :: createEnrichmentItem(const char *name, int number, XfemManager *xm, Domain *domain)
{
    return ( enrichItemList.count(name) == 1 ) ? enrichItemList [ conv2lower(name) ](number, xm, domain) : NULL;
}

bool ClassFactory :: registerEnrichmentItem( const char *name, EnrichmentItem * ( *creator )( int, XfemManager *, Domain * ) )
{
    enrichItemList [ conv2lower(name) ] = creator;
    return true;
}

EnrichmentFunction *ClassFactory :: createEnrichmentFunction(const char *name, int number, Domain *domain)
{
    return ( enrichFuncList.count(name) == 1 ) ? enrichFuncList [ conv2lower(name) ](number, domain) : NULL;
}

bool ClassFactory :: registerEnrichmentFunction( const char *name, EnrichmentFunction * ( *creator )( int, Domain * ) )
{
    enrichFuncList [ conv2lower(name) ] = creator;
    return true;
}

EnrichmentDomain *ClassFactory :: createEnrichmentDomain(const char *name)
{
    return ( enrichmentDomainList.count(name) == 1 ) ? enrichmentDomainList [ conv2lower(name) ]() : NULL;
}

bool ClassFactory :: registerEnrichmentDomain( const char *name, EnrichmentDomain * ( *creator )( ) )
{
    enrichmentDomainList [ conv2lower(name) ] = creator;
    return true;
}

EnrichmentFront *ClassFactory :: createEnrichmentFront(const char *name)
{
    return ( enrichmentFrontList.count(name) == 1 ) ? enrichmentFrontList [ conv2lower(name) ]() : NULL;
}

bool ClassFactory :: registerEnrichmentFront( const char *name, EnrichmentFront * ( *creator )( ) )
{
    enrichmentFrontList [ conv2lower(name) ] = creator;
    return true;
}

PropagationLaw *ClassFactory :: createPropagationLaw(const char *name)
{
    return ( propagationLawList.count(name) == 1 ) ? propagationLawList [ conv2lower(name) ]() : NULL;
}

bool ClassFactory :: registerPropagationLaw( const char *name, PropagationLaw * ( *creator )( ) )
{
    propagationLawList [ conv2lower(name) ] = creator;
    return true;
}

BasicGeometry *ClassFactory :: createGeometry(const char *name)
{
    return ( geometryList.count(name) == 1 ) ? geometryList [ conv2lower(name) ]() : NULL;
}

bool ClassFactory :: registerGeometry( const char *name, BasicGeometry * ( *creator )( ) )
{
    geometryList [ conv2lower(name) ] = creator;
    return true;
}

XfemManager *ClassFactory :: createXfemManager(const char *name, Domain *domain)
{
    return ( xManList.count(name) == 1 ) ? xManList [ conv2lower(name) ](domain) : NULL;
}
bool ClassFactory :: registerXfemManager( const char *name, XfemManager * ( *creator )( Domain * ) )
{
    xManList [ conv2lower(name) ] = creator;
    return true;
}


// Failure module:

FailureCriteria *ClassFactory :: createFailureCriteria(const char *name, int number, FractureManager *fracManager)
{
    return ( failureCriteriaList.count(name) == 1 ) ? failureCriteriaList [ conv2lower(name) ](number, fracManager) : NULL;
}

bool ClassFactory :: registerFailureCriteria( const char *name, FailureCriteria * ( *creator )( int, FractureManager * ) )
{
    failureCriteriaList [ conv2lower(name) ] = creator;
    return true;
}

FailureCriteriaStatus *ClassFactory :: createFailureCriteriaStatus(const char *name, int number, FailureCriteria *fc)
{
    return ( failureCriteriaList.count(name) == 1 ) ? failureCriteriaStatusList [ conv2lower(name) ](number, fc) : NULL;
}

bool ClassFactory :: registerFailureCriteriaStatus( const char *name, FailureCriteriaStatus * ( *creator )( int, FailureCriteria * ) )
{
    failureCriteriaStatusList [ conv2lower(name) ] = creator;
    return true;
}




SparseGeneralEigenValueSystemNM *ClassFactory :: createGeneralizedEigenValueSolver(GenEigvalSolverType st, Domain *d, EngngModel *m)
{
    if ( st == GES_SubspaceIt ) {
        return new SubspaceIteration(d, m);
    } else if ( st == GES_InverseIt ) {
        return new InverseIteration(d, m);
    }
#ifdef __SLEPC_MODULE
    else if ( st == GES_SLEPc ) {
        return new SLEPcSolver(d, m);
    }
#endif
    return NULL;
}

IntegrationRule *ClassFactory :: createIRule(IntegrationRuleType type, int number, Element *e)
{
    if ( type == IRT_Gauss ) {
        return new GaussIntegrationRule(number, e);
    } else if ( type == IRT_Lobatto ) {
        return new LobattoIntegrationRule(number, e);
    }
    return NULL;
}

MaterialMappingAlgorithm *ClassFactory :: createMaterialMappingAlgorithm(MaterialMappingAlgorithmType type)
{
    if ( type == MMA_ClosestPoint ) {
        return new MMAClosestIPTransfer();
    } else if ( type == MMA_LeastSquareProjection ) {
        return new MMALeastSquareProjection();
    } else if ( type == MMA_ShapeFunctionProjection ) {
        return new MMAShapeFunctProjection();
    }
    return NULL;
}

MesherInterface *ClassFactory :: createMesherInterface(MeshPackageType type, Domain *d)
{
    if ( type == MPT_T3D ) {
        return new T3DInterface(d);
    } else if ( type == MPT_TARGE2 ) {
        return new Targe2Interface(d);
    } else if ( type == MPT_FREEM ) {
        return new FreemInterface(d);
    } else if ( type == MPT_SUBDIVISION ) {
        return new Subdivision(d);
    }
    return NULL;
}


#ifdef __PARALLEL_MODE
LoadBalancerMonitor *ClassFactory :: createLoadBalancerMonitor(const char *name, EngngModel *e)
{
    return ( loadMonitorList.count(name) == 1 ) ? loadMonitorList [ conv2lower(name) ](e) : NULL;
}

LoadBalancer *ClassFactory :: createLoadBalancer(const char *name, Domain *d)
{
    return ( loadBalancerList.count(name) == 1 ) ? loadBalancerList [ conv2lower(name) ](d) : NULL;
}
#endif
} // End namespace oofem
コード例 #3
0
ファイル: inverseit.C プロジェクト: johnnyontheweb/oofem
NM_Status
InverseIteration :: solve(SparseMtrx &a, SparseMtrx &b, FloatArray &_eigv, FloatMatrix &_r, double rtol, int nroot)
{
	FILE *outStream;
    if ( a.giveNumberOfColumns() != b.giveNumberOfColumns() ) {
        OOFEM_ERROR("matrices size mismatch");
    }

    SparseLinearSystemNM *solver = GiveClassFactory().createSparseLinSolver(ST_Direct, domain, engngModel);
   
    int nn = a.giveNumberOfColumns();
    int nc = min(2 * nroot, nroot + 8);
    nc = min(nc, nn);

	//// control of diagonal zeroes in mass matrix, to be avoided
	//int i;
	//for (i = 1; i <= nn; i++) {
	//	if (b.at(i, i) == 0) {
	//		b.at(i, i) = 1.0e-12;
	//	}
	//}

    FloatArray w(nc), ww(nc), t;
    std :: vector< FloatArray > z(nc, nn), zz(nc, nn), x(nc, nn);
	outStream = domain->giveEngngModel()->giveOutputStream();

    /*  initial setting  */
#if 0
    ww.add(1.0);
    for ( int j = 0; j < nc; j++ ) {
        z[j].add(1.0);
    }
#else
	{
		FloatArray ad(nn), bd(nn);
		for (int i = 1; i <= nn; i++) {
			ad.at(i) = fabs(a.at(i, i));
			bd.at(i) = fabs(b.at(i, i));
			}
		IntArray order;
		order.enumerate(nn);
		std::sort(order.begin(), order.end(), [&ad, &bd](int a, int b) { return bd.at(a) * ad.at(b) > bd.at(b) * ad.at(a); });
		for (int i = 0; i < nc; i++) {
			x[i].at(order[i]) = 1.0;
			b.times(x[i], z[i]);
			ww.at(i + 1) = z[i].dotProduct(x[i]);
		}
	}
#endif

    int it;
    for ( it = 0; it < nitem; it++ ) {
        /*  copy zz=z  */
        for ( int j = 0; j < nc; j++ ) {
            zz[j] = z[j];
        }

        /*  solve matrix equation K.X = M.X  */
        for ( int j = 0; j < nc; j++ ) {
            solver->solve(a, z[j], x[j]);
        }

        /*  evaluation of Rayleigh quotients  */
        for ( int j = 0; j < nc; j++ ) {
            w.at(j + 1) = zz[j].dotProduct(x[j]);
        }

        for ( int j = 0; j < nc; j++ ) {
            b.times(x[j], z[j]);
        }

        for ( int j = 0; j < nc; j++ ) {
            w.at(j + 1) /= z[j].dotProduct(x[j]);
        }

        /*  check convergence  */
        int ac = 0;
        for ( int j = 1; j <= nc; j++ ) {
            if ( fabs( ww.at(j) - w.at(j) ) <= fabs( w.at(j) * rtol ) ) {
                ac++;
            }

            ww.at(j) = w.at(j);
        }

        //printf ("\n iteration  %d   %d",it,ac);
        //w.printYourself();

        /*  Gramm-Schmidt ortogonalization   */
        for ( int j = 0; j < nc; j++ ) {
            if ( j != 0 ) {
                b.times(x[j], t);
            }

            for ( int ii = 0; ii < j; ii++ ) {
                x[j].add( -x[ii].dotProduct(t), x[ii] );
            }

            b.times(x[j], t);
            x[j].times( 1.0 / sqrt( x[j].dotProduct(t) ) );
        }

        if ( ac > nroot ) {
            break;
        }

        /*  compute new approximation of Z  */
        for ( int j = 0; j < nc; j++ ) {
            b.times(x[j], z[j]);
        }
    }

    // copy results
    IntArray order;
    order.enumerate(w.giveSize());
    std :: sort(order.begin(), order.end(), [&w](int a, int b) { return w.at(a) < w.at(b); });

    _eigv.resize(nroot);
    _r.resize(nn, nroot);
    for ( int i = 1; i <= nroot; i++ ) {
        _eigv.at(i) = w.at(order.at(i));
        _r.setColumn(x[order.at(i) - 1], i);
    }

    if ( it < nitem ) {
		fprintf(outStream, "InverseIteration :: convergence reached in %d iterations\n", it);
    } else {
		fprintf(outStream, "InverseIteration :: convergence not reached after %d iterations\n", it);
    }

    return NM_Success;
}
コード例 #4
0
ファイル: classfactory.C プロジェクト: framby/OOFEM_Johannes
    auto creator = list.find(conv2lower(name));\
    return creator != list.end() ? creator->second(__VA_ARGS__) : nullptr;

// Helper macro for storing objects
#define CF_STORE(list) \
    list[ conv2lower(name) ] = creator;\
    return true;

namespace oofem {
ClassFactory &GiveClassFactory()
{
    static ClassFactory ans;
    return ans;
}

ClassFactory &classFactory = GiveClassFactory();

std :: string conv2lower(std :: string input)
{
    for ( std :: size_t i = 0; i < input.size(); i++ ) {
        input [ i ] = (char)std :: tolower(input [ i ]);
    }
    return input;
}

ClassFactory :: ClassFactory()
{
    // Fixed list for DOF types. No new components can register for these since these are part of the internal structure in OOFEM.
    dofList [ DT_master ] = dofCreator< MasterDof >;
    dofList [ DT_simpleSlave ] = dofCreator< SimpleSlaveDof >;
    dofList [ DT_slave ] = dofCreator< SlaveDof >;