Пример #1
0
int LSmear::var_to_bisect(IntervalMatrix& J, const IntervalVector& box) const {
  int lvar = -1; 
 
	//Linearization
	LPSolver::Status_Sol stat = LPSolver::UNKNOWN;

	Vector dual_solution(1);

	if (lsmode==LSMEAR_MG) { //compute the Jacobian in the midpoint
		IntervalMatrix J2(sys.f_ctrs.image_dim(), sys.nb_var);
		IntervalVector box2(IntervalVector(box.mid()).inflate(1e-8));
		//		IntervalVector box2(IntervalVector(box.random()));
		box2 &= box;

		sys.f_ctrs.jacobian(box2,J2);
		stat = getdual(J2, box, dual_solution);

	} else if (lsmode==LSMEAR) {
		stat = getdual(J, box, dual_solution);
	}


	if (stat == LPSolver::OPTIMAL) {
		double max_Lmagn = 0.0;
		int k=0;

		for (int j=0; j<nbvars; j++) {
			Interval lsmear=Interval(0.0);
			if ((!too_small(box,j)) && (box[j].mag() <1 ||  box[j].diam()/ box[j].mag() >= prec(j))){
				lsmear=dual_solution[j];

				for (int i=0; i<sys.f_ctrs.image_dim(); i++){
					lsmear += dual_solution[sys.nb_var+i] * J[i][j];
				}
			}

			lsmear*=(box[j].diam());

			if (lsmear.mag() > 1e-10  && (j!=goal_var() || mylinearsolver->get_obj_value().mid() > box[goal_var()].lb() )) {
				k++;
				if (lsmear.mag() > max_Lmagn) {
					max_Lmagn = lsmear.mag();
					lvar = j;
				}
			}
		}

		if (k==1 && lvar==goal_var()) { lvar=-1; }
	}
	if (lvar==-1) {
	  //	  std::cout << "ssr " << std::endl;
	  lvar=SmearSumRelative::var_to_bisect(J, box);
	}
	//	std::cout << "lsmear " << lvar << std::endl;
	return lvar;
}
Пример #2
0
// The main program
int main(int argc, char** argv)
{
    // Initialize libMesh
    LibMeshInit init(argc, argv);

    // Parameters
    GetPot infile("fem_system_params.in");
    const Real global_tolerance          = infile("global_tolerance", 0.);
    const unsigned int nelem_target      = infile("n_elements", 400);
    const bool transient                 = infile("transient", true);
    const Real deltat                    = infile("deltat", 0.005);
    unsigned int n_timesteps             = infile("n_timesteps", 1);
    //const unsigned int coarsegridsize    = infile("coarsegridsize", 1);
    const unsigned int coarserefinements = infile("coarserefinements", 0);
    const unsigned int max_adaptivesteps = infile("max_adaptivesteps", 10);
    //const unsigned int dim               = 2;

#ifdef LIBMESH_HAVE_EXODUS_API
    const unsigned int write_interval    = infile("write_interval", 5);
#endif

    // Create a mesh, with dimension to be overridden later, distributed
    // across the default MPI communicator.
    Mesh mesh(init.comm());
    GetPot infileForMesh("convdiff_mprime.in");
    std::string find_mesh_here = infileForMesh("mesh","psiLF_mesh.xda");
    mesh.read(find_mesh_here);

    std::cout << "Read in mesh from: " << find_mesh_here << "\n\n";

    // And an object to refine it
    MeshRefinement mesh_refinement(mesh);
    mesh_refinement.coarsen_by_parents() = true;
    mesh_refinement.absolute_global_tolerance() = global_tolerance;
    mesh_refinement.nelem_target() = nelem_target;
    mesh_refinement.refine_fraction() = 0.3;
    mesh_refinement.coarsen_fraction() = 0.3;
    mesh_refinement.coarsen_threshold() = 0.1;

    //mesh_refinement.uniformly_refine(coarserefinements);

    // Print information about the mesh to the screen.
    mesh.print_info();

    // Create an equation systems object.
    EquationSystems equation_systems (mesh);

    // Name system
    ConvDiff_MprimeSys & system =
        equation_systems.add_system<ConvDiff_MprimeSys>("Diff_ConvDiff_MprimeSys");

    // Steady-state problem
    system.time_solver =
        AutoPtr<TimeSolver>(new SteadySolver(system));

    // Sanity check that we are indeed solving a steady problem
    libmesh_assert_equal_to (n_timesteps, 1);

    // Read in all the equation systems data from the LF solve (system, solutions, rhs, etc)
    std::string find_psiLF_here = infileForMesh("psiLF_file","psiLF.xda");
    std::cout << "Looking for psiLF at: " << find_psiLF_here << "\n\n";

    equation_systems.read(find_psiLF_here, READ,
                          EquationSystems::READ_HEADER |
                          EquationSystems::READ_DATA |
                          EquationSystems::READ_ADDITIONAL_DATA);

    // Check that the norm of the solution read in is what we expect it to be
    Real readin_L2 = system.calculate_norm(*system.solution, 0, L2);
    std::cout << "Read in solution norm: "<< readin_L2 << std::endl << std::endl;

    //DEBUG
    //equation_systems.write("right_back_out.xda", WRITE, EquationSystems::WRITE_DATA |
    //		 EquationSystems::WRITE_ADDITIONAL_DATA);
#ifdef LIBMESH_HAVE_GMV
    //GMVIO(equation_systems.get_mesh()).write_equation_systems(std::string("right_back_out.gmv"), equation_systems);
#endif

    // Initialize the system
    //equation_systems.init ();  //already initialized by read-in

    // And the nonlinear solver options
    NewtonSolver *solver = new NewtonSolver(system);
    system.time_solver->diff_solver() = AutoPtr<DiffSolver>(solver);
    solver->quiet = infile("solver_quiet", true);
    solver->verbose = !solver->quiet;
    solver->max_nonlinear_iterations =
        infile("max_nonlinear_iterations", 15);
    solver->relative_step_tolerance =
        infile("relative_step_tolerance", 1.e-3);
    solver->relative_residual_tolerance =
        infile("relative_residual_tolerance", 0.0);
    solver->absolute_residual_tolerance =
        infile("absolute_residual_tolerance", 0.0);

    // And the linear solver options
    solver->max_linear_iterations =
        infile("max_linear_iterations", 50000);
    solver->initial_linear_tolerance =
        infile("initial_linear_tolerance", 1.e-3);

    // Print information about the system to the screen.
    equation_systems.print_info();

    // Now we begin the timestep loop to compute the time-accurate
    // solution of the equations...not that this is transient, but eh, why not...
    for (unsigned int t_step=0; t_step != n_timesteps; ++t_step)
    {
        // A pretty update message
        std::cout << "\n\nSolving time step " << t_step << ", time = "
                  << system.time << std::endl;

        // Adaptively solve the timestep
        unsigned int a_step = 0;
        for (; a_step != max_adaptivesteps; ++a_step)
        {   // VESTIGIAL for now ('vestigial' eh ? ;) )

            std::cout << "\n\n I should be skipped what are you doing here lalalalalalala *!**!*!*!*!*!* \n\n";

            system.solve();
            system.postprocess();
            ErrorVector error;
            AutoPtr<ErrorEstimator> error_estimator;

            // To solve to a tolerance in this problem we
            // need a better estimator than Kelly
            if (global_tolerance != 0.)
            {
                // We can't adapt to both a tolerance and a mesh
                // size at once
                libmesh_assert_equal_to (nelem_target, 0);

                UniformRefinementEstimator *u =
                    new UniformRefinementEstimator;

                // The lid-driven cavity problem isn't in H1, so
                // lets estimate L2 error
                u->error_norm = L2;

                error_estimator.reset(u);
            }
            else
            {
                // If we aren't adapting to a tolerance we need a
                // target mesh size
                libmesh_assert_greater (nelem_target, 0);

                // Kelly is a lousy estimator to use for a problem
                // not in H1 - if we were doing more than a few
                // timesteps we'd need to turn off or limit the
                // maximum level of our adaptivity eventually
                error_estimator.reset(new KellyErrorEstimator);
            }

            // Calculate error
            std::vector<Real> weights(9,1.0);  // based on u, v, p, c, their adjoints, and source parameter

            // Keep the same default norm type.
            std::vector<FEMNormType>
            norms(1, error_estimator->error_norm.type(0));
            error_estimator->error_norm = SystemNorm(norms, weights);

            error_estimator->estimate_error(system, error);

            // Print out status at each adaptive step.
            Real global_error = error.l2_norm();
            std::cout << "Adaptive step " << a_step << ": " << std::endl;
            if (global_tolerance != 0.)
                std::cout << "Global_error = " << global_error
                          << std::endl;
            if (global_tolerance != 0.)
                std::cout << "Worst element error = " << error.maximum()
                          << ", mean = " << error.mean() << std::endl;

            if (global_tolerance != 0.)
            {
                // If we've reached our desired tolerance, we
                // don't need any more adaptive steps
                if (global_error < global_tolerance)
                    break;
                mesh_refinement.flag_elements_by_error_tolerance(error);
            }
            else
            {
                // If flag_elements_by_nelem_target returns true, this
                // should be our last adaptive step.
                if (mesh_refinement.flag_elements_by_nelem_target(error))
                {
                    mesh_refinement.refine_and_coarsen_elements();
                    equation_systems.reinit();
                    a_step = max_adaptivesteps;
                    break;
                }
            }

            // Carry out the adaptive mesh refinement/coarsening
            mesh_refinement.refine_and_coarsen_elements();
            equation_systems.reinit();

            std::cout << "Refined mesh to "
                      << mesh.n_active_elem()
                      << " active elements and "
                      << equation_systems.n_active_dofs()
                      << " active dofs." << std::endl;
        } // End loop over adaptive steps

        // Do one last solve if necessary
        if (a_step == max_adaptivesteps)
        {
            QoISet qois;
            std::vector<unsigned int> qoi_indices;

            qoi_indices.push_back(0);
            qois.add_indices(qoi_indices);

            qois.set_weight(0, 1.0);

            system.assemble_qoi_sides = true; //QoI doesn't involve sides

            std::cout << "\n~*~*~*~*~*~*~*~*~ adjoint solve start ~*~*~*~*~*~*~*~*~\n" << std::endl;
            std::pair<unsigned int, Real> adjsolve = system.adjoint_solve();
            std::cout << "number of iterations to solve adjoint: " << adjsolve.first << std::endl;
            std::cout << "final residual of adjoint solve: " << adjsolve.second << std::endl;
            std::cout << "\n~*~*~*~*~*~*~*~*~ adjoint solve end ~*~*~*~*~*~*~*~*~" << std::endl;

            NumericVector<Number> &dual_solution = system.get_adjoint_solution(0);
            NumericVector<Number> &primal_solution = *system.solution;

            primal_solution.swap(dual_solution);
            ExodusII_IO(mesh).write_timestep("super_adjoint.exo",
                                             equation_systems,
                                             1, /* This number indicates how many time steps
	                                       are being written to the file */
                                             system.time);
            primal_solution.swap(dual_solution);

            system.assemble(); //overwrite residual read in from psiLF solve

            // The total error estimate
            system.postprocess(); //to compute M_HF(psiLF) and M_LF(psiLF) terms
            Real QoI_error_estimate = (-0.5*(system.rhs)->dot(dual_solution)) + system.get_MHF_psiLF() - system.get_MLF_psiLF();
            std::cout << "\n\n 0.5*M'_HF(psiLF)(superadj): " << std::setprecision(17) << 0.5*(system.rhs)->dot(dual_solution) << "\n";
            std::cout << " M_HF(psiLF): " << std::setprecision(17) << system.get_MHF_psiLF() << "\n";
            std::cout << " M_LF(psiLF): " << std::setprecision(17) << system.get_MLF_psiLF() << "\n";
            std::cout << "\n\n Residual L2 norm: " << system.calculate_norm(*system.rhs, L2) << "\n";
            std::cout << " Residual discrete L2 norm: " << system.calculate_norm(*system.rhs, DISCRETE_L2) << "\n";
            std::cout << " Super-adjoint L2 norm: " << system.calculate_norm(dual_solution, L2) << "\n";
            std::cout << " Super-adjoint discrete L2 norm: " << system.calculate_norm(dual_solution, DISCRETE_L2) << "\n";
            std::cout << "\n\n QoI error estimate: " << std::setprecision(17) << QoI_error_estimate << "\n\n";

            //DEBUG
            std::cout << "\n------------ herp derp ------------" << std::endl;
            //libMesh::out.precision(16);
            //dual_solution.print();
            //system.get_adjoint_rhs().print();

            AutoPtr<NumericVector<Number> > adjresid = system.solution->clone();
            (system.matrix)->vector_mult(*adjresid,system.get_adjoint_solution(0));
            SparseMatrix<Number>& adjmat = *system.matrix;
            (system.matrix)->get_transpose(adjmat);
            adjmat.vector_mult(*adjresid,system.get_adjoint_solution(0));
            //std::cout << "******************** matrix-superadj product (libmesh) ************************" << std::endl;
            //adjresid->print();
            adjresid->add(-1.0, system.get_adjoint_rhs(0));
            //std::cout << "******************** superadjoint system residual (libmesh) ***********************" << std::endl;
            //adjresid->print();
            std::cout << "\n\nadjoint system residual (discrete L2): " << system.calculate_norm(*adjresid,DISCRETE_L2) << std::endl;
            std::cout << "adjoint system residual (L2, all): " << system.calculate_norm(*adjresid,L2) << std::endl;
            std::cout << "adjoint system residual (L2, 0): " << system.calculate_norm(*adjresid,0,L2) << std::endl;
            std::cout << "adjoint system residual (L2, 1): " << system.calculate_norm(*adjresid,1,L2) << std::endl;
            std::cout << "adjoint system residual (L2, 2): " << system.calculate_norm(*adjresid,2,L2) << std::endl;
            std::cout << "adjoint system residual (L2, 3): " << system.calculate_norm(*adjresid,3,L2) << std::endl;
            std::cout << "adjoint system residual (L2, 4): " << system.calculate_norm(*adjresid,4,L2) << std::endl;
            std::cout << "adjoint system residual (L2, 5): " << system.calculate_norm(*adjresid,5,L2) << std::endl;
            /*
            	AutoPtr<NumericVector<Number> > sadj_matlab = system.solution->clone();
            	AutoPtr<NumericVector<Number> > adjresid_matlab = system.solution->clone();
            	if(FILE *fp=fopen("superadj_matlab.txt","r")){
              	Real value;
              	int counter = 0;
              	int flag = 1;
              	while(flag != -1){
              		flag = fscanf(fp,"%lf",&value);
              		if(flag != -1){
            				sadj_matlab->set(counter, value);
            				counter += 1;
              		}
              	}
              	fclose(fp);
            	}
            	(system.matrix)->vector_mult(*adjresid_matlab,*sadj_matlab);
            	//std::cout << "******************** matrix-superadj product (matlab) ***********************" << std::endl;
            	//adjresid_matlab->print();
            	adjresid_matlab->add(-1.0, system.get_adjoint_rhs(0));
            	//std::cout << "******************** superadjoint system residual (matlab) ***********************" << std::endl;
            	//adjresid_matlab->print();
            	std::cout << "\n\nmatlab import adjoint system residual (discrete L2): " << system.calculate_norm(*adjresid_matlab,DISCRETE_L2) << "\n" << std::endl;
            */
            /*
            	AutoPtr<NumericVector<Number> > sadj_fwd_hack = system.solution->clone();
            	AutoPtr<NumericVector<Number> > adjresid_fwd_hack = system.solution->clone();
            	if(FILE *fp=fopen("superadj_forward_hack.txt","r")){
              	Real value;
              	int counter = 0;
              	int flag = 1;
              	while(flag != -1){
              		flag = fscanf(fp,"%lf",&value);
              		if(flag != -1){
            				sadj_fwd_hack->set(counter, value);
            				counter += 1;
              		}
              	}
              	fclose(fp);
            	}
            	(system.matrix)->vector_mult(*adjresid_fwd_hack,*sadj_fwd_hack);
            	//std::cout << "******************** matrix-superadj product (fwd_hack) ***********************" << std::endl;
            	//adjresid_fwd_hack->print();
            	adjresid_fwd_hack->add(-1.0, system.get_adjoint_rhs(0));
            	//std::cout << "******************** superadjoint system residual (fwd_hack) ***********************" << std::endl;
            	//adjresid_fwd_hack->print();
            	std::cout << "\n\nfwd_hack import adjoint system residual (discrete L2): " << system.calculate_norm(*adjresid_fwd_hack,DISCRETE_L2) << "\n" << std::endl;
            	std::cout << "fwd_hack adjoint system residual (L2, 0): " << system.calculate_norm(*adjresid_fwd_hack,0,L2) << std::endl;
            	std::cout << "fwd_hack adjoint system residual (L2, 1): " << system.calculate_norm(*adjresid_fwd_hack,1,L2) << std::endl;
            	std::cout << "fwd_hack adjoint system residual (L2, 2): " << system.calculate_norm(*adjresid_fwd_hack,2,L2) << std::endl;
            	std::cout << "fwd_hack adjoint system residual (L2, 3): " << system.calculate_norm(*adjresid_fwd_hack,3,L2) << std::endl;
            	std::cout << "fwd_hack adjoint system residual (L2, 4): " << system.calculate_norm(*adjresid_fwd_hack,4,L2) << std::endl;
            	std::cout << "fwd_hack adjoint system residual (L2, 5): " << system.calculate_norm(*adjresid_fwd_hack,5,L2) << std::endl;
            */
            //std::cout << "************************ system.matrix ***********************" << std::endl;
            //system.matrix->print();

            std::cout << "\n------------ herp derp ------------" << std::endl;

            // The cell wise breakdown
            ErrorVector cell_wise_error;
            cell_wise_error.resize((system.rhs)->size());
            for(unsigned int i = 0; i < (system.rhs)->size() ; i++)
            {
                if(i < system.get_mesh().n_elem())
                    cell_wise_error[i] = fabs(-0.5*((system.rhs)->el(i) * dual_solution(i))
                                              + system.get_MHF_psiLF(i) - system.get_MLF_psiLF(i));
                else
                    cell_wise_error[i] = fabs(-0.5*((system.rhs)->el(i) * dual_solution(i)));

                /*csv from 'save data' from gmv output gives a few values at each node point (value
                for every element that shares that node), yet paraview display only seems to show one
                of them -> the value in an element is given at each of the nodes that it has, hence the
                repetition; what is displayed in paraview is each element's value; even though MHF_psiLF
                and MLF_psiLF are stored by element this seems to give elemental contributions that
                agree with if we had taken the superadj-residual dot product by integrating over elements*/

                /*at higher mesh resolutions and lower k, weird-looking artifacts start to appear and
                it no longer agrees with output from manual integration of superadj-residual...*/
            }
            // Plot it
            std::ostringstream error_gmv;
            error_gmv << "error.gmv";
            cell_wise_error.plot_error(error_gmv.str(), equation_systems.get_mesh());

            //alternate element-wise breakdown, outputed as values matched to element centroids; for matlab plotz
            primal_solution.swap(dual_solution);
            system.postprocess(1);
            primal_solution.swap(dual_solution);
            system.postprocess(2);
            std::cout << "\n\n -0.5*M'_HF(psiLF)(superadj): " << std::setprecision(17) << system.get_half_adj_weighted_resid() << "\n";
            primal_solution.swap(dual_solution);

            std::string write_error_here = infileForMesh("error_est_output_file", "error_est_breakdown.dat");
            std::ofstream output(write_error_here);
            for(unsigned int i = 0 ; i < system.get_mesh().n_elem(); i++) {
                Point elem_cent = system.get_mesh().elem(i)->centroid();
                if(output.is_open()) {
                    output << elem_cent(0) << " " << elem_cent(1) << " "
                           << fabs(system.get_half_adj_weighted_resid(i) + system.get_MHF_psiLF(i) - system.get_MLF_psiLF(i)) << "\n";
                }
            }
            output.close();

        } // End if at max adaptive steps

#ifdef LIBMESH_HAVE_EXODUS_API
        // Write out this timestep if we're requested to
        if ((t_step+1)%write_interval == 0)
        {
            std::ostringstream file_name;
            /*
                // We write the file in the ExodusII format.
                file_name << "out_"
                          << std::setw(3)
                          << std::setfill('0')
                          << std::right
                          << t_step+1
                          << ".e";
            			//this should write out the primal which should be the same as what's read in...
            			ExodusII_IO(mesh).write_timestep(file_name.str(),
            							                        equation_systems,
            							                        1, //number of time steps written to file
            							                        system.time);
            */
        }
#endif // #ifdef LIBMESH_HAVE_EXODUS_API
    }

    // All done.
    return 0;

} //end main
Пример #3
0
LinearSolver::Status_Sol CtcPolytopeHull::run_simplex(IntervalVector& box,
		LinearSolver::Sense sense, int var, Interval& obj, double bound) {
	int nvar=nb_var;
	int nctr=mylinearsolver->getNbRows();
	// the linear solver is always called in a minimization mode : in case of maximization of var , the opposite of var is minimized
	if(sense==LinearSolver::MINIMIZE)
		mylinearsolver->setVarObj(var, 1.0);
	else
		mylinearsolver->setVarObj(var, -1.0);

	//	mylinearsolver->writeFile("coucou.lp");
	//	system("cat coucou.lp");
	LinearSolver::Status_Sol stat = mylinearsolver->solve();
	//	cout << " stat solver " << stat << endl;

	if(stat == LinearSolver::OPTIMAL) {
		if( ((sense==LinearSolver::MINIMIZE) && (  mylinearsolver->getObjValue() <=bound)) ||
				((sense==LinearSolver::MAXIMIZE) && ((-mylinearsolver->getObjValue())>=bound))) {
			stat = LinearSolver::UNKNOWN;
		}
	}

	// Neumaier - Shcherbina postprocessing
	if(stat == LinearSolver::OPTIMAL) {

		// the dual solution : used to compute the bound
		Vector dual_solution(mylinearsolver->getNbRows());
		LinearSolver::Status stat_dual = mylinearsolver->getDualSol(dual_solution);

		Matrix A_trans (nb_var,mylinearsolver->getNbRows()) ;
		LinearSolver::Status stat_A = mylinearsolver->getCoefConstraint_trans(A_trans);

		/*	IntervalMatrix IA_trans (nb_var,mylinearsolver->getNbRows());
		for (int i=0;i<nvar; i++){
		  for(int j=0; j<nctr; j++)
		    IA_trans[i][j]= A_trans[i][j];
		}*/
		IntervalVector B(mylinearsolver->getNbRows());
		LinearSolver::Status stat_B = mylinearsolver->getB(B);

		bool minimization=false;
		if (sense==LinearSolver::MINIMIZE)
			minimization=true;
		//	  cout << "B " << B << endl;
		//	  cout << "A_trans " << IA_trans << endl;

		if ((stat_dual==LinearSolver::OK) && (stat_A==LinearSolver::OK) && (stat_B==LinearSolver::OK))
			NeumaierShcherbina_postprocessing( mylinearsolver->getNbRows(), var, obj, box, A_trans, B, dual_solution, minimization);
		else
			stat = LinearSolver::UNKNOWN;

	}

	// infeasibility test  cf Neumaier Shcherbina paper
	if(stat == LinearSolver::INFEASIBLE_NOTPROVED) {

		Vector infeasible_dir(mylinearsolver->getNbRows());
		LinearSolver::Status stat1 = mylinearsolver->getInfeasibleDir(infeasible_dir);

		Matrix A_trans (nb_var,mylinearsolver->getNbRows()) ;
		LinearSolver::Status stat2 = mylinearsolver->getCoefConstraint_trans(A_trans);

		IntervalVector B(mylinearsolver->getNbRows());
		LinearSolver::Status stat3 = mylinearsolver->getB(B);

		if ((stat1==LinearSolver::OK) && (stat2==LinearSolver::OK) && (stat3==LinearSolver::OK) &&
				(NeumaierShcherbina_infeasibilitytest (mylinearsolver->getNbRows(), box, A_trans, B, infeasible_dir))) {
			stat = LinearSolver::INFEASIBLE;
		}
	}

	// Reset the objective of the LP solver
	mylinearsolver->setVarObj(var, 0.0);

	return stat;

}