Beispiel #1
0
 Objective_PDEOPT_ElasticitySIMP(const Teuchos::RCP<ElasticitySIMPOperators<Real> > &data,
                                 const Teuchos::RCP<DensityFilter<Real> > &filter,
                                 const Teuchos::RCP<Teuchos::ParameterList> &parlist)
   : data_(data), filter_(filter) {
   // Compute compliance scaling
   Teuchos::Array<Real> dotF(1, 0);
   (data_->getVecF())->dot(*(data_->getVecF()),dotF);
   Real minDensity = parlist->sublist("ElasticitySIMP").get<Real>("Minimum Density");
   scale_ = minDensity/dotF[0];
   useFU_ = parlist->sublist("ElasticitySIMP").get("Use Force Dot Displacement Objective",true);
   print_ = parlist->sublist("ElasticitySIMP").get("Print Density",false);
 }
Beispiel #2
0
int main(int argc, char *argv[]) {
//  feenableexcept(FE_ALL_EXCEPT & ~FE_INEXACT);

    // This little trick lets us print to std::cout only if a (dummy) command-line argument is provided.
    int iprint = argc - 1;
    Teuchos::RCP<std::ostream> outStream;
    Teuchos::oblackholestream bhs; // outputs nothing

    /*** Initialize communicator. ***/
    Teuchos::GlobalMPISession mpiSession (&argc, &argv, &bhs);
    Teuchos::RCP<const Teuchos::Comm<int> > comm = Tpetra::DefaultPlatform::getDefaultPlatform().getComm();
    const int myRank = comm->getRank();
    if ((iprint > 0) && (myRank == 0)) {
        outStream = Teuchos::rcp(&std::cout, false);
    }
    else {
        outStream = Teuchos::rcp(&bhs, false);
    }

    int errorFlag  = 0;

    // *** Example body.
    try {

        /*** Read in XML input ***/
        std::string filename = "input.xml";
        Teuchos::RCP<Teuchos::ParameterList> parlist = Teuchos::rcp( new Teuchos::ParameterList() );
        Teuchos::updateParametersFromXmlFile( filename, parlist.ptr() );
        std::string stoch_filename = "stochastic.xml";
        Teuchos::RCP<Teuchos::ParameterList> stoch_parlist = Teuchos::rcp( new Teuchos::ParameterList() );
        Teuchos::updateParametersFromXmlFile( stoch_filename, stoch_parlist.ptr() );

        /*** Initialize main data structure. ***/
        Teuchos::RCP<const Teuchos::Comm<int> > serial_comm = Teuchos::rcp(new Teuchos::SerialComm<int>());
        Teuchos::RCP<ElasticitySIMPOperators<RealT> > data
            = Teuchos::rcp(new ElasticitySIMPOperators<RealT>(serial_comm, parlist, outStream));
        /*** Initialize density filter. ***/
        Teuchos::RCP<DensityFilter<RealT> > filter
            = Teuchos::rcp(new DensityFilter<RealT>(serial_comm, parlist, outStream));
        /*** Build vectors and dress them up as ROL vectors. ***/
        Teuchos::RCP<const Tpetra::Map<> > vecmap_u = data->getDomainMapA();
        Teuchos::RCP<const Tpetra::Map<> > vecmap_z = data->getCellMap();
        Teuchos::RCP<Tpetra::MultiVector<> > u_rcp      = createTpetraVector(vecmap_u);
        Teuchos::RCP<Tpetra::MultiVector<> > z_rcp      = createTpetraVector(vecmap_z);
        Teuchos::RCP<Tpetra::MultiVector<> > du_rcp     = createTpetraVector(vecmap_u);
        Teuchos::RCP<Tpetra::MultiVector<> > dw_rcp     = createTpetraVector(vecmap_u);
        Teuchos::RCP<Tpetra::MultiVector<> > dz_rcp     = createTpetraVector(vecmap_z);
        Teuchos::RCP<Tpetra::MultiVector<> > dz2_rcp    = createTpetraVector(vecmap_z);
        Teuchos::RCP<std::vector<RealT> >    vc_rcp     = Teuchos::rcp(new std::vector<RealT>(1, 0));
        Teuchos::RCP<std::vector<RealT> >    vc_lam_rcp = Teuchos::rcp(new std::vector<RealT>(1, 0));
        Teuchos::RCP<std::vector<RealT> >    vscale_rcp = Teuchos::rcp(new std::vector<RealT>(1, 0));
        // Set all values to 1 in u, z.
        RealT one(1), two(2);
        u_rcp->putScalar(one);
        // Set z to gray solution.
        RealT volFrac = parlist->sublist("ElasticityTopoOpt").get<RealT>("Volume Fraction");
        z_rcp->putScalar(volFrac);
        // Set scaling vector for constraint
        RealT W = parlist->sublist("Geometry").get<RealT>("Width");
        RealT H = parlist->sublist("Geometry").get<RealT>("Height");
        (*vscale_rcp)[0] = one/std::pow(W*H*(one-volFrac),two);
        // Set Scaling vector for density
        bool  useZscale = parlist->sublist("Problem").get<bool>("Use Scaled Density Vectors");
        RealT densityScaling = parlist->sublist("Problem").get<RealT>("Density Scaling");
        Teuchos::RCP<Tpetra::MultiVector<> > scaleVec = createTpetraVector(vecmap_z);
        scaleVec->putScalar(densityScaling);
        if ( !useZscale ) {
            scaleVec->putScalar(one);
        }
        Teuchos::RCP<const Tpetra::Vector<> > zscale_rcp = scaleVec->getVector(0);

        // Randomize d vectors.
        du_rcp->randomize(); //du_rcp->scale(0);
        dw_rcp->randomize();
        dz_rcp->randomize(); //dz_rcp->scale(0);
        dz2_rcp->randomize();
        // Create ROL::TpetraMultiVectors.
        Teuchos::RCP<ROL::Vector<RealT> > up
            = Teuchos::rcp(new ROL::TpetraMultiVector<RealT>(u_rcp));
        Teuchos::RCP<ROL::Vector<RealT> > dup
            = Teuchos::rcp(new ROL::TpetraMultiVector<RealT>(du_rcp));
        Teuchos::RCP<ROL::Vector<RealT> > dwp
            = Teuchos::rcp(new ROL::TpetraMultiVector<RealT>(dw_rcp));
        Teuchos::RCP<ROL::Vector<RealT> > zp
            = Teuchos::rcp(new ROL::PrimalScaledTpetraMultiVector<RealT>(z_rcp,zscale_rcp));
        Teuchos::RCP<ROL::Vector<RealT> > dzp
            = Teuchos::rcp(new ROL::PrimalScaledTpetraMultiVector<RealT>(dz_rcp,zscale_rcp));
        Teuchos::RCP<ROL::Vector<RealT> > dz2p
            = Teuchos::rcp(new ROL::PrimalScaledTpetraMultiVector<RealT>(dz2_rcp,zscale_rcp));
        Teuchos::RCP<ROL::Vector<RealT> > vcp
            = Teuchos::rcp(new ROL::PrimalScaledStdVector<RealT>(vc_rcp,vscale_rcp));
        Teuchos::RCP<ROL::Vector<RealT> > vc_lamp
            = Teuchos::rcp(new ROL::DualScaledStdVector<RealT>(vc_lam_rcp,vscale_rcp));
        // Create ROL SimOpt vectors.
        ROL::Vector_SimOpt<RealT> x(up,zp);
        ROL::Vector_SimOpt<RealT> d(dup,dzp);
        ROL::Vector_SimOpt<RealT> d2(dwp,dz2p);

        /*** Build sampler. ***/
        BuildSampler<RealT> buildSampler(comm,*stoch_parlist,*parlist);
        buildSampler.print("samples");

        /*** Compute compliance objective function scaling. ***/
        RealT min(ROL::ROL_INF<RealT>()), gmin(0), max(0), gmax(0), sum(0), gsum(0), tmp(0);
        Teuchos::Array<RealT> dotF(1, 0);
        RealT minDensity = parlist->sublist("ElasticitySIMP").get<RealT>("Minimum Density");
        for (int i = 0; i < buildSampler.get()->numMySamples(); ++i) {
            data->updateF(buildSampler.get()->getMyPoint(i));
            (data->getVecF())->dot(*(data->getVecF()),dotF.view(0,1));
            tmp = minDensity/dotF[0];
            min = ((min < tmp) ? min : tmp);
            max = ((max > tmp) ? max : tmp);
            sum += buildSampler.get()->getMyWeight(i) * tmp;
        }
        ROL::Elementwise::ReductionMin<RealT> ROLmin;
        buildSampler.getBatchManager()->reduceAll(&min,&gmin,ROLmin);
        ROL::Elementwise::ReductionMax<RealT> ROLmax;
        buildSampler.getBatchManager()->reduceAll(&max,&gmax,ROLmax);
        buildSampler.getBatchManager()->sumAll(&sum,&gsum,1);
        bool useExpValScale = stoch_parlist->sublist("Problem").get("Use Expected Value Scaling",false);
        RealT scale = (useExpValScale ? gsum : gmin);

        /*** Build objective function, constraint and reduced objective function. ***/
        Teuchos::RCP<ROL::Objective_SimOpt<RealT> > obj
            = Teuchos::rcp(new ParametrizedObjective_PDEOPT_ElasticitySIMP<RealT>(data, filter, parlist,scale));
        Teuchos::RCP<ROL::EqualityConstraint_SimOpt<RealT> > con
            = Teuchos::rcp(new ParametrizedEqualityConstraint_PDEOPT_ElasticitySIMP<RealT>(data, filter, parlist));
        Teuchos::RCP<ROL::Reduced_Objective_SimOpt<RealT> > objReduced
            = Teuchos::rcp(new ROL::Reduced_Objective_SimOpt<RealT>(obj, con, up, zp, dwp));
        Teuchos::RCP<ROL::EqualityConstraint<RealT> > volcon
            = Teuchos::rcp(new EqualityConstraint_PDEOPT_ElasticitySIMP_Volume<RealT>(data, parlist));

        /*** Build bound constraint ***/
        Teuchos::RCP<Tpetra::MultiVector<> > lo_rcp = Teuchos::rcp(new Tpetra::MultiVector<>(vecmap_z, 1, true));
        Teuchos::RCP<Tpetra::MultiVector<> > hi_rcp = Teuchos::rcp(new Tpetra::MultiVector<>(vecmap_z, 1, true));
        lo_rcp->putScalar(0.0);
        hi_rcp->putScalar(1.0);
        Teuchos::RCP<ROL::Vector<RealT> > lop
            = Teuchos::rcp(new ROL::PrimalScaledTpetraMultiVector<RealT>(lo_rcp, zscale_rcp));
        Teuchos::RCP<ROL::Vector<RealT> > hip
            = Teuchos::rcp(new ROL::PrimalScaledTpetraMultiVector<RealT>(hi_rcp, zscale_rcp));
        Teuchos::RCP<ROL::BoundConstraint<RealT> > bnd = Teuchos::rcp(new ROL::BoundConstraint<RealT>(lop,hip));

        /*** Build Stochastic Functionality. ***/
        ROL::StochasticProblem<RealT> opt(*stoch_parlist,objReduced,buildSampler.get(),zp,bnd);

        /*** Check functional interface. ***/
        bool checkDeriv = parlist->sublist("Problem").get("Derivative Check",false);
        if ( checkDeriv ) {
//      *outStream << "Checking Objective:" << "\n";
//      obj->checkGradient(x,d,true,*outStream);
//      obj->checkHessVec(x,d,true,*outStream);
//      obj->checkHessSym(x,d,d2,true,*outStream);
//      *outStream << "Checking Constraint:" << "\n";
//      con->checkAdjointConsistencyJacobian(*dup,d,x,true,*outStream);
//      con->checkAdjointConsistencyJacobian_1(*dwp, *dup, *up, *zp, true, *outStream);
//      con->checkAdjointConsistencyJacobian_2(*dwp, *dzp, *up, *zp, true, *outStream);
//      con->checkInverseJacobian_1(*up,*up,*up,*zp,true,*outStream);
//      con->checkInverseAdjointJacobian_1(*up,*up,*up,*zp,true,*outStream);
//      con->checkApplyJacobian(x,d,*up,true,*outStream);
//      con->checkApplyAdjointHessian(x,*dup,d,x,true,*outStream);
            *outStream << "Checking Reduced Objective:" << "\n";
            opt.checkObjectiveGradient(*dzp,true,*outStream);
            opt.checkObjectiveHessVec(*dzp,true,*outStream);
            *outStream << "Checking Volume Constraint:" << "\n";
            volcon->checkAdjointConsistencyJacobian(*vcp,*dzp,*zp,true,*outStream);
            volcon->checkApplyJacobian(*zp,*dzp,*vcp,true,*outStream);
            volcon->checkApplyAdjointHessian(*zp,*vcp,*dzp,*zp,true,*outStream);
        }

        /*** Run optimization ***/
        ROL::AugmentedLagrangian<RealT> augLag(opt.getObjective(),volcon,*vc_lamp,1.0,
                                               *opt.getSolutionVector(),*vcp,*parlist);
        ROL::Algorithm<RealT> algo("Augmented Lagrangian",*parlist,false);
        std::clock_t timer = std::clock();
        algo.run(*opt.getSolutionVector(),*vc_lamp,augLag,*volcon,*opt.getBoundConstraint(),true,*outStream);
        *outStream << "Optimization time: "
                   << static_cast<RealT>(std::clock()-timer)/static_cast<RealT>(CLOCKS_PER_SEC)
                   << " seconds." << std::endl;

        data->outputTpetraVector(z_rcp, "density.txt");
        data->outputTpetraVector(u_rcp, "state.txt");
        data->outputTpetraVector(zscale_rcp, "weights.txt");

        // Build objective function distribution
        RealT val(0);
        int nSamp = stoch_parlist->sublist("Problem").get("Number of Output Samples",10);
        stoch_parlist->sublist("Problem").set("Number of Samples",nSamp);
        BuildSampler<RealT> buildSampler_dist(comm,*stoch_parlist,*parlist);
        std::stringstream name;
        name << "samples_" << buildSampler_dist.getBatchManager()->batchID() << ".txt";
        std::ofstream file;
        file.open(name.str());
        std::vector<RealT> sample;
        RealT tol = 1.e-8;
        std::clock_t timer_print = std::clock();
        for (int i = 0; i < buildSampler_dist.get()->numMySamples(); ++i) {
            sample = buildSampler_dist.get()->getMyPoint(i);
            objReduced->setParameter(sample);
            val = objReduced->value(*zp,tol);
            for (int j = 0; j < static_cast<int>(sample.size()); ++j) {
                file << sample[j] << "  ";
            }
            file << val << "\n";
        }
        file.close();
        *outStream << "Output time: "
                   << static_cast<RealT>(std::clock()-timer_print)/static_cast<RealT>(CLOCKS_PER_SEC)
                   << " seconds." << std::endl;
    }
    catch (std::logic_error err) {
        *outStream << err.what() << "\n";
        errorFlag = -1000;
    }; // end try

    if (errorFlag != 0)
        std::cout << "End Result: TEST FAILED\n";
    else
        std::cout << "End Result: TEST PASSED\n";

    return 0;
}