bool KinematicsSolver::getBestSolution(ColumnVector& cartesian,
		ColumnVector& currentQ, ColumnVector& bestSolution) {

	if (this->solve(cartesian, currentQ)) {
		SolutionSet* set = selector->getBest();
		ColumnVector soln(6);
		for (int i = 0; i < 6; i++) {
			soln(i + 1) = set->theta[i];
		}
		bestSolution = soln;
		return true;
	}

	return false;
}
 /**
  * Create query solution.
  */
 QuerySolution* createQuerySolution() {
     std::auto_ptr<QuerySolution> soln(new QuerySolution());
     soln->cacheData.reset(new SolutionCacheData());
     soln->cacheData->solnType = SolutionCacheData::COLLSCAN_SOLN;
     soln->cacheData->tree.reset(new PlanCacheIndexTree());
     return soln.release();
 }
void CircuitState::zero()
{
	uint i;

	for(i=0; i < cir->stateLen; i++)
		soln(i) = 0;
	time = 0;
}
bool
RichardsMultiphaseProblem::updateSolution(NumericVector<Number>& vec_solution, NumericVector<Number>& ghosted_solution)
{
  bool updatedSolution = false;  // this gets set to true if we needed to enforce the bound at any node

  unsigned int sys_num = getNonlinearSystem().number();

  // For parallel procs i believe that i have to use local_nodes_begin, rather than just nodes_begin
  // _mesh comes from SystemBase (_mesh = getNonlinearSystem().subproblem().mesh(), and subproblem is this object)
  MeshBase::node_iterator nit = _mesh.getMesh().local_nodes_begin();
  const MeshBase::node_iterator nend = _mesh.getMesh().local_nodes_end();

  for ( ; nit != nend; ++nit)
  {
    const Node & node = *(*nit);

    // dofs[0] is the dof number of the bounded variable at this node
    // dofs[1] is the dof number of the lower variable at this node
    std::vector<unsigned int> dofs(2);
    dofs[0] = node.dof_number(sys_num, _bounded_var_num, 0);
    dofs[1] = node.dof_number(sys_num, _lower_var_num, 0);

    // soln[0] is the value of the bounded variable at this node
    // soln[1] is the value of the lower variable at this node
    std::vector<Number> soln(2);
    vec_solution.get(dofs, soln);

    // do the bounding
    if (soln[0] < soln[1])
    {
      /*
      dof_id_type nd = node.id();
      Moose::out << "nd = " << nd << " dof_bounded = " << dofs[0] << " dof_lower = " << dofs[1] << "\n";
      Moose::out << " bounded_value = " << soln[0] << " lower_value = " << soln[1] << "\n";
      */
      vec_solution.set(dofs[0], soln[1]); // set the bounded variable equal to the lower value
      updatedSolution = true;
    }

  }

  // The above vec_solution.set calls potentially added "set" commands to a queue
  // The following actions the queue (doing MPI commands if necessary), so
  // vec_solution will actually be modified by this following command
  vec_solution.close();

  // if any proc updated the solution, all procs will know about it
  _communicator.max(updatedSolution);

  if (updatedSolution)
  {
    ghosted_solution = vec_solution;
    ghosted_solution.close();
  }

  return updatedSolution;

}
示例#5
0
//==========================================================================================================================
//	Test to verify the evaluate method with a vector input.
//==========================================================================================================================
		int EvaluateVectorTest()
		{
			TestUtil testFramework( "PolyFit", "Evaluate", __FILE__, __LINE__ );
			std::string failMesg;

			int n = 4;
			gpstk::PolyFit<double> test(n);
			gpstk::Vector<double> soln(3,0.), eval(3,0.);
			double indep[6] = {0, 1, 2, 3, 4, 5}, dep[6] = {0, 1, 4, 9, 16, 25};

			eval[0] = 6;
			eval[1] = 8;
			eval[2] = 10;
			
			for(int i=0; i<6; i++)
			{
				test.Add(dep[i],indep[i]);
			}


			soln = test.Evaluate(eval);
			//std::cout << "Solution is: " << soln << std::endl;
			n = 0;			
			for (int i = 0; i<3; i++)
			{

				// Using relative error since the soln >> 1
				if (fabs(soln[i] - eval[i]*eval[i])/(eval[i]*eval[i]) > eps) 
				{
					n += 1; // Increment the return value for each wrong value
				}
			}
			failMesg = "Was the solution computed correct?";
			testFramework.assert(n==0, failMesg, __LINE__);

			return testFramework.countFails(); // Return the result of the test.
		}
示例#6
0
    QuerySolution* makeCollectionScan(const CanonicalQuery& query, bool tailable) {
        auto_ptr<QuerySolution> soln(new QuerySolution());
        soln->filter.reset(query.root()->shallowClone());
        // BSONValue, where are you?
        soln->filterData = query.getQueryObj();

        // Make the (only) node, a collection scan.
        CollectionScanNode* csn = new CollectionScanNode();
        csn->name = query.ns();
        csn->filter = soln->filter.get();
        csn->tailable = tailable;

        const BSONObj& sortObj = query.getParsed().getSort();
        // TODO: We need better checking for this.  Should be done in CanonicalQuery and we should
        // be able to assume it's correct.
        if (!sortObj.isEmpty()) {
            BSONElement natural = sortObj.getFieldDotted("$natural");
            csn->direction = natural.numberInt() >= 0 ? 1 : -1;
        }

        // Add this solution to the list of solutions.
        soln->root.reset(csn);
        return soln.release();
    }
示例#7
0
    // static
    QuerySolution* QueryPlannerAnalysis::analyzeDataAccess(const CanonicalQuery& query,
                                                   const QueryPlannerParams& params,
                                                   QuerySolutionNode* solnRoot) {
        auto_ptr<QuerySolution> soln(new QuerySolution());
        soln->filterData = query.getQueryObj();
        verify(soln->filterData.isOwned());
        soln->ns = query.ns();
        soln->indexFilterApplied = params.indexFiltersApplied;

        solnRoot->computeProperties();

        // solnRoot finds all our results.  Let's see what transformations we must perform to the
        // data.

        // If we're answering a query on a sharded system, we need to drop documents that aren't
        // logically part of our shard (XXX GREG elaborate more precisely)
        if (params.options & QueryPlannerParams::INCLUDE_SHARD_FILTER) {
            // XXX TODO: use params.shardKey to do fetch analysis instead of always fetching.
            if (!solnRoot->fetched()) {
                FetchNode* fetch = new FetchNode();
                fetch->children.push_back(solnRoot);
                solnRoot = fetch;
            }
            ShardingFilterNode* sfn = new ShardingFilterNode();
            sfn->children.push_back(solnRoot);
            solnRoot = sfn;
        }

        solnRoot = analyzeSort(query, params, solnRoot, &soln->hasSortStage);
        // This can happen if we need to create a blocking sort stage and we're not allowed to.
        if (NULL == solnRoot) { return NULL; }

        // If we can (and should), add the keep mutations stage.

        // We cannot keep mutated documents if:
        //
        // 1. The query requires an index to evaluate the predicate ($text).  We can't tell whether
        // or not the doc actually satisfies the $text predicate since we can't evaluate a
        // text MatchExpression.
        //
        // 2. The query implies a sort ($geoNear).  It would be rather expensive and hacky to merge
        // the document at the right place.
        //
        // 3. There is an index-provided sort.  Ditto above comment about merging.
        // XXX; do we want some kind of static init for a set of stages we care about & pass that
        // set into hasNode?
        bool cannotKeepFlagged = hasNode(solnRoot, STAGE_TEXT)
                              || hasNode(solnRoot, STAGE_GEO_NEAR_2D)
                              || hasNode(solnRoot, STAGE_GEO_NEAR_2DSPHERE)
                              || (!query.getParsed().getSort().isEmpty() && !soln->hasSortStage);

        // Only these stages can produce flagged results.  A stage has to hold state past one call
        // to work(...) in order to possibly flag a result.
        bool couldProduceFlagged = hasNode(solnRoot, STAGE_GEO_2D)
                                || hasNode(solnRoot, STAGE_AND_HASH)
                                || hasNode(solnRoot, STAGE_AND_SORTED)
                                || hasNode(solnRoot, STAGE_FETCH);

        bool shouldAddMutation = !cannotKeepFlagged && couldProduceFlagged;

        if (shouldAddMutation && (params.options & QueryPlannerParams::KEEP_MUTATIONS)) {
            KeepMutationsNode* keep = new KeepMutationsNode();

            // We must run the entire expression tree to make sure the document is still valid.
            keep->filter.reset(query.root()->shallowClone());

            if (STAGE_SORT == solnRoot->getType()) {
                // We want to insert the invalidated results before the sort stage, if there is one.
                verify(1 == solnRoot->children.size());
                keep->children.push_back(solnRoot->children[0]);
                solnRoot->children[0] = keep;
            }
            else {
                keep->children.push_back(solnRoot);
                solnRoot = keep;
            }
        }

        // Project the results.
        if (NULL != query.getProj()) {
            QLOG() << "PROJECTION: fetched status: " << solnRoot->fetched() << endl;
            QLOG() << "PROJECTION: Current plan is:\n" << solnRoot->toString() << endl;
            if (query.getProj()->requiresDocument()) {
                QLOG() << "PROJECTION: claims to require doc adding fetch.\n";
                // If the projection requires the entire document, somebody must fetch.
                if (!solnRoot->fetched()) {
                    FetchNode* fetch = new FetchNode();
                    fetch->children.push_back(solnRoot);
                    solnRoot = fetch;
                }
            }
            else {
                QLOG() << "PROJECTION: requires fields\n";
                const vector<string>& fields = query.getProj()->getRequiredFields();
                bool covered = true;
                for (size_t i = 0; i < fields.size(); ++i) {
                    if (!solnRoot->hasField(fields[i])) {
                        QLOG() << "PROJECTION: not covered cuz doesn't have field "
                             << fields[i] << endl;
                        covered = false;
                        break;
                    }
                }
                QLOG() << "PROJECTION: is covered?: = " << covered << endl;
                // If any field is missing from the list of fields the projection wants,
                // a fetch is required.
                if (!covered) {
                    FetchNode* fetch = new FetchNode();
                    fetch->children.push_back(solnRoot);
                    solnRoot = fetch;
                }
            }

            // We now know we have whatever data is required for the projection.
            ProjectionNode* projNode = new ProjectionNode();
            projNode->children.push_back(solnRoot);
            projNode->fullExpression = query.root();
            projNode->projection = query.getParsed().getProj();
            solnRoot = projNode;
        }
        else {
            // If there's no projection, we must fetch, as the user wants the entire doc.
            if (!solnRoot->fetched()) {
                FetchNode* fetch = new FetchNode();
                fetch->children.push_back(solnRoot);
                solnRoot = fetch;
            }
        }

        if (0 != query.getParsed().getSkip()) {
            SkipNode* skip = new SkipNode();
            skip->skip = query.getParsed().getSkip();
            skip->children.push_back(solnRoot);
            solnRoot = skip;
        }

        // When there is both a blocking sort and a limit, the limit will
        // be enforced by the blocking sort.
        // Otherwise, we need to limit the results in the case of a hard limit
        // (ie. limit in raw query is negative)
        if (0 != query.getParsed().getNumToReturn() &&
            !soln->hasSortStage &&
            !query.getParsed().wantMore()) {

            LimitNode* limit = new LimitNode();
            limit->limit = query.getParsed().getNumToReturn();
            limit->children.push_back(solnRoot);
            solnRoot = limit;
        }

        soln->root.reset(solnRoot);
        return soln.release();
    }
示例#8
0
int main(int argc, char *argv[]) {

  Teuchos::GlobalMPISession mpiSession(&argc, &argv);

  // 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
  if (iprint > 0)
    outStream = Teuchos::rcp(&std::cout, false);
  else
    outStream = Teuchos::rcp(&bhs, false);

  int errorFlag  = 0;

  // *** Example body.

  try {
    
    std::string filename = "input.xml";
    Teuchos::RCP<Teuchos::ParameterList> parlist = Teuchos::rcp( new Teuchos::ParameterList() );
    Teuchos::updateParametersFromXmlFile( filename, parlist.ptr() );

    RealT V_th      = parlist->get("Thermal Voltage", 0.02585);
    RealT lo_Vsrc   = parlist->get("Source Voltage Lower Bound", 0.0);
    RealT up_Vsrc   = parlist->get("Source Voltage Upper Bound", 1.0);
    RealT step_Vsrc = parlist->get("Source Voltage Step", 1.e-2);

    RealT true_Is = parlist->get("True Saturation Current", 1.e-12);
    RealT true_Rs = parlist->get("True Saturation Resistance", 0.25);
    RealT init_Is = parlist->get("Initial Saturation Current", 1.e-12);
    RealT init_Rs = parlist->get("Initial Saturation Resistance", 0.25);
    RealT lo_Is   = parlist->get("Saturation Current Lower Bound", 1.e-16);
    RealT up_Is   = parlist->get("Saturation Current Upper Bound", 1.e-1);
    RealT lo_Rs   = parlist->get("Saturation Resistance Lower Bound", 1.e-2);
    RealT up_Rs   = parlist->get("Saturation Resistance Upper Bound", 30.0);

    // bool use_lambertw   = parlist->get("Use Analytical Solution",true); 
    bool use_scale      = parlist->get("Use Scaling For Epsilon-Active Sets",true);
    bool use_sqp        = parlist->get("Use SQP", true);
    // bool use_linesearch = parlist->get("Use Line Search", true);
    // bool datatype       = parlist->get("Get Data From Input File",false);
    // bool use_adjoint    = parlist->get("Use Adjoint Gradient Computation",false);
    // int  use_hessvec    = parlist->get("Use Hessian-Vector Implementation",1); // 0 - FD, 1 - exact, 2 - GN
    // bool plot           = parlist->get("Generate Plot Data",false);
    // RealT noise         = parlist->get("Measurement Noise",0.0);

    
    EqualityConstraint_DiodeCircuit<RealT> con(V_th,lo_Vsrc,up_Vsrc,step_Vsrc);

    RealT alpha = 1.e-4; // regularization parameter (unused)
    int ns = 101; // number of Vsrc components
    int nz = 2; // number of optimization variables

    Objective_DiodeCircuit<RealT> obj(alpha,ns,nz);
    
    // Initialize iteration vectors.
    Teuchos::RCP<std::vector<RealT> > z_rcp    = Teuchos::rcp( new std::vector<RealT> (nz, 0.0) );
    Teuchos::RCP<std::vector<RealT> > yz_rcp   = Teuchos::rcp( new std::vector<RealT> (nz, 0.0) );
    Teuchos::RCP<std::vector<RealT> > soln_rcp = Teuchos::rcp( new std::vector<RealT> (nz, 0.0) );
    (*z_rcp)[0]     = init_Is;
    (*z_rcp)[1]     = init_Rs;
    (*yz_rcp)[0]    = init_Is;
    (*yz_rcp)[1]    = init_Rs;
    (*soln_rcp)[0]  = true_Is;
    (*soln_rcp)[1]  = true_Rs;
    ROL::StdVector<RealT> z(z_rcp);
    ROL::StdVector<RealT> yz(yz_rcp);
    ROL::StdVector<RealT> soln(soln_rcp);
    Teuchos::RCP<ROL::Vector<RealT> > zp  = Teuchos::rcp(&z,false);
    Teuchos::RCP<ROL::Vector<RealT> > yzp = Teuchos::rcp(&yz,false);

    Teuchos::RCP<std::vector<RealT> > u_rcp  = Teuchos::rcp( new std::vector<RealT> (ns, 0.0) );
    Teuchos::RCP<std::vector<RealT> > yu_rcp = Teuchos::rcp( new std::vector<RealT> (ns, 0.0) );
    std::ifstream input_file("measurements.dat");
    RealT temp, temp_scale;
    for (int i=0; i<ns; i++) {
      input_file >> temp;
      input_file >> temp;
      temp_scale = pow(10,int(log10(temp)));
      (*u_rcp)[i] = temp_scale*(RealT)rand()/(RealT)RAND_MAX;
      (*yu_rcp)[i] = temp_scale*(RealT)rand()/(RealT)RAND_MAX;
    }
    input_file.close();
    ROL::StdVector<RealT> u(u_rcp);
    ROL::StdVector<RealT> yu(yu_rcp);
    Teuchos::RCP<ROL::Vector<RealT> > up  = Teuchos::rcp(&u,false);
    Teuchos::RCP<ROL::Vector<RealT> > yup = Teuchos::rcp(&yu,false);

    Teuchos::RCP<std::vector<RealT> > jv_rcp  = Teuchos::rcp( new std::vector<RealT> (ns, 1.0) );
    ROL::StdVector<RealT> jv(jv_rcp);
    Teuchos::RCP<ROL::Vector<RealT> > jvp = Teuchos::rcp(&jv,false);

    ROL::Vector_SimOpt<RealT> x(up,zp);
    ROL::Vector_SimOpt<RealT> y(yup,yzp);

    // Check derivatives
    obj.checkGradient(x,x,y,true,*outStream);
    obj.checkHessVec(x,x,y,true,*outStream);

    con.checkApplyJacobian(x,y,jv,true,*outStream);
    con.checkApplyAdjointJacobian(x,yu,jv,x,true,*outStream);
    con.checkApplyAdjointHessian(x,yu,y,x,true,*outStream);
    // Check consistency of Jacobians and adjoint Jacobians.
    con.checkAdjointConsistencyJacobian_1(jv,yu,u,z,true,*outStream);
    con.checkAdjointConsistencyJacobian_2(jv,yz,u,z,true,*outStream);
    // Check consistency of solves.
    con.checkSolve(u,z,jv,true,*outStream);
    con.checkInverseJacobian_1(jv,yu,u,z,true,*outStream);
    con.checkInverseAdjointJacobian_1(yu,jv,u,z,true,*outStream);

    // Initialize reduced objective function.
    Teuchos::RCP<std::vector<RealT> > p_rcp  = Teuchos::rcp( new std::vector<RealT> (ns, 0.0) );
    ROL::StdVector<RealT> p(p_rcp);
    Teuchos::RCP<ROL::Vector<RealT> > pp  = Teuchos::rcp(&p,false);
    Teuchos::RCP<ROL::Objective_SimOpt<RealT> > pobj = Teuchos::rcp(&obj,false);
    Teuchos::RCP<ROL::EqualityConstraint_SimOpt<RealT> > pcon = Teuchos::rcp(&con,false);
    ROL::Reduced_Objective_SimOpt<RealT> robj(pobj,pcon,up,pp);
    // Check derivatives.
    *outStream << "Derivatives of reduced objective" << std::endl;
    robj.checkGradient(z,z,yz,true,*outStream);
    robj.checkHessVec(z,z,yz,true,*outStream);
    
    // Bound constraints
    RealT tol = 1.e-12;
    Teuchos::RCP<std::vector<RealT> > g0_rcp = Teuchos::rcp( new std::vector<RealT> (nz, 0.0) );;
    ROL::StdVector<RealT> g0p(g0_rcp);
    robj.gradient(g0p,z,tol);
    *outStream << std::scientific <<  "Initial gradient = " << (*g0_rcp)[0] << " " << (*g0_rcp)[1] << "\n";
    *outStream << std::scientific << "Norm of Gradient = " << g0p.norm() << "\n";

    // Define scaling for epsilon-active sets (used in inequality constraints)
    RealT scale;
    if(use_scale){ scale = 1.0e-2/g0p.norm();}
    else{ scale = 1.0;}
    *outStream << std::scientific << "Scaling: " << scale << "\n";

    /// Define constraints on Is and Rs
    BoundConstraint_DiodeCircuit<RealT> bcon(scale,lo_Is,up_Is,lo_Rs,up_Rs);
    //bcon.deactivate();
    
    // Optimization 
    *outStream << "\n Initial guess " << (*z_rcp)[0] << " " << (*z_rcp)[1] << std::endl;
      
    if (!use_sqp){    
      // Trust Region
      ROL::Algorithm<RealT> algo_tr("Trust Region",*parlist);
      std::clock_t timer_tr = std::clock();
      algo_tr.run(z,robj,bcon,true,*outStream);
      *outStream << "\n Solution " << (*z_rcp)[0] << " " << (*z_rcp)[1] << "\n" << std::endl;
      *outStream << "Trust-Region required " << (std::clock()-timer_tr)/(RealT)CLOCKS_PER_SEC
                 << " seconds.\n";
    }
    else{
      // SQP.
      //Teuchos::RCP<std::vector<RealT> > gz_rcp = Teuchos::rcp( new std::vector<RealT> (nz, 0.0) );
      //ROL::StdVector<RealT> gz(gz_rcp);
      //Teuchos::RCP<ROL::Vector<RealT> > gzp = Teuchos::rcp(&gz,false);
      Teuchos::RCP<std::vector<RealT> > gu_rcp = Teuchos::rcp( new std::vector<RealT> (ns, 0.0) );
      ROL::StdVector<RealT> gu(gu_rcp);
      Teuchos::RCP<ROL::Vector<RealT> > gup = Teuchos::rcp(&gu,false);
      //ROL::Vector_SimOpt<RealT> g(gup,gzp);
      ROL::Vector_SimOpt<RealT> g(gup,zp);
      Teuchos::RCP<std::vector<RealT> > c_rcp = Teuchos::rcp( new std::vector<RealT> (ns, 0.0) );
      Teuchos::RCP<std::vector<RealT> > l_rcp = Teuchos::rcp( new std::vector<RealT> (ns, 0.0) );
      ROL::StdVector<RealT> c(c_rcp);
      ROL::StdVector<RealT> l(l_rcp);
      
      ROL::Algorithm<RealT> algo_cs("Composite Step",*parlist);
      //x.zero();
      std::clock_t timer_cs = std::clock();
      algo_cs.run(x,g,l,c,obj,con,true,*outStream);
      *outStream << "\n Solution " << (*z_rcp)[0] << " " << (*z_rcp)[1] << "\n" << std::endl;
      *outStream << "Composite Step required " << (std::clock()-timer_cs)/(RealT)CLOCKS_PER_SEC
		 << " seconds.\n";
    }
    soln.axpy(-1.0, z);
    *outStream << "Norm of error: " << soln.norm() << std::endl;
    if (soln.norm() > 1e4*ROL::ROL_EPSILON) {
      errorFlag = 1;
    }
  }
  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;

}
示例#9
0
int
verify_solution(const simple_mesh_description<typename VectorType::GlobalOrdinalType>& mesh,
                const VectorType& x, double tolerance, bool verify_whole_domain = false)
{
  typedef typename VectorType::GlobalOrdinalType GlobalOrdinal;
  typedef typename VectorType::ScalarType Scalar;

  int global_nodes_x = mesh.global_box[0][1]+1;
  int global_nodes_y = mesh.global_box[1][1]+1;
  int global_nodes_z = mesh.global_box[2][1]+1;
  Box box;
  copy_box(mesh.local_box, box);

  //num-owned-nodes in each dimension is num-elems+1
  //only if num-elems > 0 in that dimension *and*
  //we are at the high end of the global range in that dimension:
  if (box[0][1] > box[0][0] && box[0][1] == mesh.global_box[0][1]) ++box[0][1];
  if (box[1][1] > box[1][0] && box[1][1] == mesh.global_box[1][1]) ++box[1][1];
  if (box[2][1] > box[2][0] && box[2][1] == mesh.global_box[2][1]) ++box[2][1];

  std::vector<GlobalOrdinal> rows;
  std::vector<Scalar> row_coords;

  int roffset = 0;
  for(int iz=box[2][0]; iz<box[2][1]; ++iz) {
   for(int iy=box[1][0]; iy<box[1][1]; ++iy) {
    for(int ix=box[0][0]; ix<box[0][1]; ++ix) {
      GlobalOrdinal row_id =
          get_id<GlobalOrdinal>(global_nodes_x, global_nodes_y, global_nodes_z,
                                ix, iy, iz);
      Scalar x, y, z;
      get_coords(row_id, global_nodes_x, global_nodes_y, global_nodes_z, x, y, z);

      bool verify_this_point = false;
      if (verify_whole_domain) verify_this_point = true;
      else if (std::abs(x - 0.5) < 0.05 && std::abs(y - 0.5) < 0.05 && std::abs(z - 0.5) < 0.05) {
        verify_this_point = true;
      }

      if (verify_this_point) {
        rows.push_back(roffset);
        row_coords.push_back(x);
        row_coords.push_back(y);
        row_coords.push_back(z);
      }

      ++roffset;
    }
   }
  }

  int return_code = 0;

  const int num_terms = 300;

  err_info<Scalar> max_error;
  max_error.err = 0.0;

  for(size_t i=0; i<rows.size(); ++i) {
    Scalar computed_soln = x.coefs[rows[i]];
    Scalar x = row_coords[i*3];
    Scalar y = row_coords[i*3+1];
    Scalar z = row_coords[i*3+2];
    Scalar analytic_soln = 0.0;
    //set exact boundary-conditions:
    if (x == 1.0) {
      //x==1 is first, we want soln to be 1 even around the edges
      //of the x==1 plane where y and/or z may be 0 or 1...
      analytic_soln = 1;
    }
    else if (x == 0.0 || y == 0.0 || z == 0.0) {
      analytic_soln = 0;
    }
    else if (y == 1.0 || z == 1.0) {
      analytic_soln = 0;
    }
    else {
      analytic_soln = soln(x, y, z, num_terms, num_terms);
    }

#ifdef MINIFE_DEBUG_VERBOSE
std::cout<<"("<<x<<","<<y<<","<<z<<") row "<<rows[i]<<": computed: "<<computed_soln<<",  analytic: "<<analytic_soln<<std::endl;
#endif
    Scalar err = std::abs(analytic_soln - computed_soln);
    if (err > max_error.err) {
      max_error.err = err;
      max_error.computed = computed_soln;
      max_error.analytic = analytic_soln;
      max_error.coords[0] = x;
      max_error.coords[1] = y;
      max_error.coords[2] = z;
    }
  }

  Scalar local_max_err = max_error.err;
  Scalar global_max_err = 0;
#ifdef HAVE_MPI
  MPI_Allreduce(&local_max_err, &global_max_err, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
#else
  global_max_err = local_max_err;
#endif

  if (local_max_err == global_max_err) {
    if (max_error.err > tolerance) {
      std::cout << "max absolute error is "<<max_error.err<<":"<<std::endl;
      std::cout << "   at position ("<<max_error.coords[0]<<","<<max_error.coords[1]<<","<<max_error.coords[2]<<"), "<<std::endl;
      std::cout << "   computed solution: "<<max_error.computed<<",  analytic solution: "<<max_error.analytic<<std::endl;
    }
    else {
      std::cout << "solution matches analytic solution to within "<<tolerance<<" or better."<<std::endl;
    }
  }

  if (global_max_err > tolerance) {
    return_code = 1;
  }

  return return_code;
}
示例#10
0
文件: main.cpp 项目: dwillcox/BoxLib
int main(int argc, char* argv[])
{
  BoxLib::Initialize(argc,argv);

  BL_PROFILE_VAR("main()", pmain);

  std::cout << std::setprecision(15);

  solver_type = BoxLib_C;
  bc_type = Periodic;

  Real     a = 0.0;
  Real     b = 1.0;

  // ---- First use the number of processors to decide how many grids you have.
  // ---- We arbitrarily decide to have one grid per MPI process in a uniform
  // ---- cubic domain, so we require that the number of processors be N^3.
  // ---- This requirement is somewhat arbitrary, but convenient for now.

  int nprocs = ParallelDescriptor::NProcs();

  // N is the cube root of the number of processors
  int N(0);
  for(int i(1); i*i*i <= nprocs; ++i) {
    if(i*i*i == nprocs) {
      N = i;
    }
  }

  if(N == 0) {  // not a cube
    if(ParallelDescriptor::IOProcessor()) {
      std::cerr << "**** Error:  nprocs = " << nprocs << " is not currently supported." << std::endl;
    }
    BoxLib::Error("We require that the number of processors be a perfect cube");
  }
  if(ParallelDescriptor::IOProcessor()) {
    std::cout << "N = " << N << std::endl;
  }


  // ---- make a box, then a boxarray with maxSize
  int domain_hi = (N*maxGrid) - 1;
  Box domain(IntVect(0,0,0), IntVect(domain_hi,domain_hi,domain_hi));
  BoxArray bs(domain);
  bs.maxSize(maxGrid);

  // This defines the physical size of the box.  Right now the box is [0,1] in each direction.
  RealBox real_box;
  for (int n = 0; n < BL_SPACEDIM; n++) {
    real_box.setLo(n, 0.0);
    real_box.setHi(n, 1.0);
  }
 
  // This says we are using Cartesian coordinates
  int coord = 0;
  
  // This sets the boundary conditions to be periodic or not
  int is_per[BL_SPACEDIM];
  
  if (bc_type == Dirichlet || bc_type == Neumann) {
    for (int n = 0; n < BL_SPACEDIM; n++) is_per[n] = 0;
  } 
  else {
    for (int n = 0; n < BL_SPACEDIM; n++) is_per[n] = 1;
  }
 
  // This defines a Geometry object which is useful for writing the plotfiles
  Geometry geom(domain,&real_box,coord,is_per);

  for ( int n=0; n<BL_SPACEDIM; n++ ) {
    dx[n] = ( geom.ProbHi(n) - geom.ProbLo(n) )/domain.length(n);
  }

  if (ParallelDescriptor::IOProcessor()) {
     std::cout << "Domain size     : " << N << std::endl;
     std::cout << "Max_grid_size   : " << maxGrid << std::endl;
     std::cout << "Number of grids : " << bs.size() << std::endl;
  }

  // Allocate and define the right hand side.
  MultiFab rhs(bs, Ncomp, 0, Fab_allocate); 
  setup_rhs(rhs, geom, a, b);

  MultiFab alpha(bs, Ncomp, 0, Fab_allocate);
  MultiFab beta[BL_SPACEDIM];
  for ( int n=0; n<BL_SPACEDIM; ++n ) {
    BoxArray bx(bs);
    beta[n].define(bx.surroundingNodes(n), Ncomp, 1, Fab_allocate);
  }

  setup_coeffs(bs, alpha, beta, geom);

  MultiFab anaSoln;
  if (comp_norm) {
    anaSoln.define(bs, Ncomp, 0, Fab_allocate);
    compute_analyticSolution(anaSoln);
  }

  // Allocate the solution array 
  // Set the number of ghost cells in the solution array.
  MultiFab soln(bs, Ncomp, 1, Fab_allocate);

  solve(soln, anaSoln, a, b, alpha, beta, rhs, bs, geom, BoxLib_C);

  BL_PROFILE_VAR_STOP(pmain);

  BoxLib::Finalize();
}
示例#11
0
    // static
    QuerySolution* QueryPlannerAnalysis::analyzeDataAccess(const CanonicalQuery& query,
                                                   const QueryPlannerParams& params,
                                                   QuerySolutionNode* solnRoot) {
        auto_ptr<QuerySolution> soln(new QuerySolution());
        soln->filterData = query.getQueryObj();
        verify(soln->filterData.isOwned());
        soln->ns = query.ns();
        soln->indexFilterApplied = params.indexFiltersApplied;

        solnRoot->computeProperties();

        // solnRoot finds all our results.  Let's see what transformations we must perform to the
        // data.

        // If we're answering a query on a sharded system, we need to drop documents that aren't
        // logically part of our shard.
        if (params.options & QueryPlannerParams::INCLUDE_SHARD_FILTER) {
            // TODO: We could use params.shardKey to do fetch analysis instead of always fetching.
            if (!solnRoot->fetched()) {
                FetchNode* fetch = new FetchNode();
                fetch->children.push_back(solnRoot);
                solnRoot = fetch;
            }
            ShardingFilterNode* sfn = new ShardingFilterNode();
            sfn->children.push_back(solnRoot);
            solnRoot = sfn;
        }

        bool hasSortStage = false;
        solnRoot = analyzeSort(query, params, solnRoot, &hasSortStage);

        // This can happen if we need to create a blocking sort stage and we're not allowed to.
        if (NULL == solnRoot) { return NULL; }

        // A solution can be blocking if it has a blocking sort stage or
        // a hashed AND stage.
        bool hasAndHashStage = hasNode(solnRoot, STAGE_AND_HASH);
        soln->hasBlockingStage = hasSortStage || hasAndHashStage;

        // If we can (and should), add the keep mutations stage.

        // We cannot keep mutated documents if:
        //
        // 1. The query requires an index to evaluate the predicate ($text).  We can't tell whether
        // or not the doc actually satisfies the $text predicate since we can't evaluate a
        // text MatchExpression.
        //
        // 2. The query implies a sort ($geoNear).  It would be rather expensive and hacky to merge
        // the document at the right place.
        //
        // 3. There is an index-provided sort.  Ditto above comment about merging.
        //
        // TODO: do we want some kind of pre-planning step where we look for certain nodes and cache
        // them?  We do lookups in the tree a few times.  This may not matter as most trees are
        // shallow in terms of query nodes.
        bool cannotKeepFlagged = hasNode(solnRoot, STAGE_TEXT)
                              || hasNode(solnRoot, STAGE_GEO_NEAR_2D)
                              || hasNode(solnRoot, STAGE_GEO_NEAR_2DSPHERE)
                              || (!query.getParsed().getSort().isEmpty() && !hasSortStage);

        // Only these stages can produce flagged results.  A stage has to hold state past one call
        // to work(...) in order to possibly flag a result.
        bool couldProduceFlagged = hasNode(solnRoot, STAGE_GEO_2D)
                                || hasAndHashStage
                                || hasNode(solnRoot, STAGE_AND_SORTED)
                                || hasNode(solnRoot, STAGE_FETCH);

        bool shouldAddMutation = !cannotKeepFlagged && couldProduceFlagged;

        if (shouldAddMutation && (params.options & QueryPlannerParams::KEEP_MUTATIONS)) {
            KeepMutationsNode* keep = new KeepMutationsNode();

            // We must run the entire expression tree to make sure the document is still valid.
            keep->filter.reset(query.root()->shallowClone());

            if (STAGE_SORT == solnRoot->getType()) {
                // We want to insert the invalidated results before the sort stage, if there is one.
                verify(1 == solnRoot->children.size());
                keep->children.push_back(solnRoot->children[0]);
                solnRoot->children[0] = keep;
            }
            else {
                keep->children.push_back(solnRoot);
                solnRoot = keep;
            }
        }

        // Project the results.
        if (NULL != query.getProj()) {
            QLOG() << "PROJECTION: fetched status: " << solnRoot->fetched() << endl;
            QLOG() << "PROJECTION: Current plan is:\n" << solnRoot->toString() << endl;

            ProjectionNode::ProjectionType projType = ProjectionNode::DEFAULT;
            BSONObj coveredKeyObj;

            if (query.getProj()->requiresDocument()) {
                QLOG() << "PROJECTION: claims to require doc adding fetch.\n";
                // If the projection requires the entire document, somebody must fetch.
                if (!solnRoot->fetched()) {
                    FetchNode* fetch = new FetchNode();
                    fetch->children.push_back(solnRoot);
                    solnRoot = fetch;
                }
            }
            else if (!query.getProj()->wantIndexKey()) {
                // The only way we're here is if it's a simple projection.  That is, we can pick out
                // the fields we want to include and they're not dotted.  So we want to execute the
                // projection in the fast-path simple fashion.  Just don't know which fast path yet.
                QLOG() << "PROJECTION: requires fields\n";
                const vector<string>& fields = query.getProj()->getRequiredFields();
                bool covered = true;
                for (size_t i = 0; i < fields.size(); ++i) {
                    if (!solnRoot->hasField(fields[i])) {
                        QLOG() << "PROJECTION: not covered due to field "
                             << fields[i] << endl;
                        covered = false;
                        break;
                    }
                }

                QLOG() << "PROJECTION: is covered?: = " << covered << endl;

                // If any field is missing from the list of fields the projection wants,
                // a fetch is required.
                if (!covered) {
                    FetchNode* fetch = new FetchNode();
                    fetch->children.push_back(solnRoot);
                    solnRoot = fetch;

                    // It's simple but we'll have the full document and we should just iterate
                    // over that.
                    projType = ProjectionNode::SIMPLE_DOC;
                    QLOG() << "PROJECTION: not covered, fetching.";
                }
                else {
                    if (solnRoot->fetched()) {
                        // Fetched implies hasObj() so let's run with that.
                        projType = ProjectionNode::SIMPLE_DOC;
                        QLOG() << "PROJECTION: covered via FETCH, using SIMPLE_DOC fast path";
                    }
                    else {
                        // If we're here we're not fetched so we're covered.  Let's see if we can
                        // get out of using the default projType.  If there's only one leaf
                        // underneath and it's giving us index data we can use the faster covered
                        // impl.
                        vector<QuerySolutionNode*> leafNodes;
                        getLeafNodes(solnRoot, &leafNodes);

                        if (1 == leafNodes.size()) {
                            // Both the IXSCAN and DISTINCT stages provide covered key data.
                            if (STAGE_IXSCAN == leafNodes[0]->getType()) {
                                projType = ProjectionNode::COVERED_ONE_INDEX;
                                IndexScanNode* ixn = static_cast<IndexScanNode*>(leafNodes[0]);
                                coveredKeyObj = ixn->indexKeyPattern;
                                QLOG() << "PROJECTION: covered via IXSCAN, using COVERED fast path";
                            }
                            else if (STAGE_DISTINCT == leafNodes[0]->getType()) {
                                projType = ProjectionNode::COVERED_ONE_INDEX;
                                DistinctNode* dn = static_cast<DistinctNode*>(leafNodes[0]);
                                coveredKeyObj = dn->indexKeyPattern;
                                QLOG() << "PROJECTION: covered via DISTINCT, using COVERED fast path";
                            }
                        }
                    }
                }
            }

            // We now know we have whatever data is required for the projection.
            ProjectionNode* projNode = new ProjectionNode();
            projNode->children.push_back(solnRoot);
            projNode->fullExpression = query.root();
            projNode->projection = query.getParsed().getProj();
            projNode->projType = projType;
            projNode->coveredKeyObj = coveredKeyObj;
            solnRoot = projNode;
        }
        else {
            // If there's no projection, we must fetch, as the user wants the entire doc.
            if (!solnRoot->fetched()) {
                FetchNode* fetch = new FetchNode();
                fetch->children.push_back(solnRoot);
                solnRoot = fetch;
            }
        }

        if (0 != query.getParsed().getSkip()) {
            SkipNode* skip = new SkipNode();
            skip->skip = query.getParsed().getSkip();
            skip->children.push_back(solnRoot);
            solnRoot = skip;
        }

        // When there is both a blocking sort and a limit, the limit will
        // be enforced by the blocking sort.
        // Otherwise, we need to limit the results in the case of a hard limit
        // (ie. limit in raw query is negative)
        if (0 != query.getParsed().getNumToReturn() &&
            !hasSortStage &&
            !query.getParsed().wantMore()) {

            LimitNode* limit = new LimitNode();
            limit->limit = query.getParsed().getNumToReturn();
            limit->children.push_back(solnRoot);
            solnRoot = limit;
        }

        soln->root.reset(solnRoot);
        return soln.release();
    }
示例#12
0
文件: main.cpp 项目: qinyubo/BoxLib
int main(int argc, char* argv[])
{
  BoxLib::Initialize(argc,argv);

  BL_PROFILE_VAR("main()", pmain);

  std::cout << std::setprecision(15);

  ParmParse ppmg("mg");  
  ppmg.query("v", verbose);
  ppmg.query("maxorder", maxorder);
  
  ParmParse pp;

  {
    std::string solver_type_s;
    pp.get("solver_type",solver_type_s);
    if (solver_type_s == "BoxLib_C") {
      solver_type = BoxLib_C;
    }
    else if (solver_type_s == "BoxLib_C4") {
      solver_type = BoxLib_C4;
    }
    else if (solver_type_s == "BoxLib_F") {
#ifdef USE_F90_SOLVERS
      solver_type = BoxLib_F;      
#else
      BoxLib::Error("Set USE_FORTRAN=TRUE in GNUmakefile");
#endif
    }
    else if (solver_type_s == "Hypre") {
#ifdef USEHYPRE
      solver_type = Hypre;
#else
      BoxLib::Error("Set USE_HYPRE=TRUE in GNUmakefile");
#endif
    }
    else if (solver_type_s == "All") {
      solver_type = All;
    }  
    else {
      if (ParallelDescriptor::IOProcessor()) {
	std::cout << "Don't know this solver type: " << solver_type << std::endl;
      }
      BoxLib::Error("");
    }
  }

  {
    std::string bc_type_s;
    pp.get("bc_type",bc_type_s);
    if (bc_type_s == "Dirichlet") {
      bc_type = Dirichlet;
#ifdef USEHPGMG
      domain_boundary_condition = BC_DIRICHLET;
#endif
    }
    else if (bc_type_s == "Neumann") {
      bc_type = Neumann;
#ifdef USEHPGMG
      BoxLib::Error("HPGMG does not support Neumann boundary conditions");
#endif
    }
    else if (bc_type_s == "Periodic") {
      bc_type = Periodic;
#ifdef USEHPGMG
      domain_boundary_condition = BC_PERIODIC;
#endif
    }
    else {
      if (ParallelDescriptor::IOProcessor()) {
	std::cout << "Don't know this boundary type: " << bc_type << std::endl;
      }
      BoxLib::Error("");
    }
  }

  pp.query("tol_rel", tolerance_rel);
  pp.query("tol_abs", tolerance_abs);
  pp.query("maxiter", maxiter);
  pp.query("plot_rhs" , plot_rhs);
  pp.query("plot_beta", plot_beta);
  pp.query("plot_soln", plot_soln);
  pp.query("plot_asol", plot_asol);
  pp.query("plot_err", plot_err);
  pp.query("comp_norm", comp_norm);

  Real a, b;
  pp.get("a",  a);
  pp.get("b",  b);

  pp.get("n_cell",n_cell);
  pp.get("max_grid_size",max_grid_size);

  // Define a single box covering the domain
  IntVect dom_lo(D_DECL(0,0,0));
  IntVect dom_hi(D_DECL(n_cell-1,n_cell-1,n_cell-1));
  Box domain(dom_lo,dom_hi);

  // Initialize the boxarray "bs" from the single box "bx"
  BoxArray bs(domain);

  // Break up boxarray "bs" into chunks no larger than "max_grid_size" along a direction
  bs.maxSize(max_grid_size);

  // This defines the physical size of the box.  Right now the box is [0,1] in each direction.
  RealBox real_box;
  for (int n = 0; n < BL_SPACEDIM; n++) {
    real_box.setLo(n, 0.0);
    real_box.setHi(n, 1.0);
  }
 
  // This says we are using Cartesian coordinates
  int coord = 0;
  
  // This sets the boundary conditions to be periodic or not
  Array<int> is_per(BL_SPACEDIM,1);
  
  if (bc_type == Dirichlet || bc_type == Neumann) {
    if (ParallelDescriptor::IOProcessor()) {
      std::cout << "Using Dirichlet or Neumann boundary conditions." << std::endl;
    }
    for (int n = 0; n < BL_SPACEDIM; n++) is_per[n] = 0;
  } 
  else {
    if (ParallelDescriptor::IOProcessor()) {
      std::cout << "Using periodic boundary conditions." << std::endl;
    }
    for (int n = 0; n < BL_SPACEDIM; n++) is_per[n] = 1;
  }
 
  // This defines a Geometry object which is useful for writing the plotfiles
  Geometry geom(domain,&real_box,coord,is_per.dataPtr());

  for ( int n=0; n<BL_SPACEDIM; n++ ) {
    dx[n] = ( geom.ProbHi(n) - geom.ProbLo(n) )/domain.length(n);
  }

  if (ParallelDescriptor::IOProcessor()) {
    std::cout << "Grid resolution : " << n_cell << " (cells)" << std::endl;
    std::cout << "Domain size     : " << real_box.hi(0) - real_box.lo(0) << " (length unit) " << std::endl;
    std::cout << "Max_grid_size   : " << max_grid_size << " (cells)" << std::endl;
    std::cout << "Number of grids : " << bs.size() << std::endl;
  }

  // Allocate and define the right hand side.
  bool do_4th = (solver_type==BoxLib_C4 || solver_type==All);
  int ngr = (do_4th ? 1 : 0);
  MultiFab rhs(bs, Ncomp, ngr); 
  setup_rhs(rhs, geom);

  // Set up the Helmholtz operator coefficients.
  MultiFab alpha(bs, Ncomp, 0);
  PArray<MultiFab> beta(BL_SPACEDIM, PArrayManage);
  for ( int n=0; n<BL_SPACEDIM; ++n ) {
    BoxArray bx(bs);
    beta.set(n, new MultiFab(bx.surroundingNodes(n), Ncomp, 0, Fab_allocate));
  }

  // The way HPGMG stores face-centered data is completely different than the
  // way BoxLib does it, and translating between the two directly via indexing
  // magic is a nightmare. Happily, the way this tutorial calculates
  // face-centered values is by first calculating cell-centered values and then
  // interpolating to the cell faces. HPGMG can do the same thing, so rather
  // than converting directly from BoxLib's face-centered data to HPGMG's, just
  // give HPGMG the cell-centered data and let it interpolate itself.

  MultiFab beta_cc(bs,Ncomp,1); // cell-centered beta
  setup_coeffs(bs, alpha, beta, geom, beta_cc);

  MultiFab alpha4, beta4;
  if (do_4th) {
    alpha4.define(bs, Ncomp, 4, Fab_allocate);
    beta4.define(bs, Ncomp, 3, Fab_allocate);
    setup_coeffs4(bs, alpha4, beta4, geom);
  }

  MultiFab anaSoln;
  if (comp_norm || plot_err || plot_asol) {
    anaSoln.define(bs, Ncomp, 0, Fab_allocate);
    compute_analyticSolution(anaSoln,Array<Real>(BL_SPACEDIM,0.5));
    
    if (plot_asol) {
      writePlotFile("ASOL", anaSoln, geom);
    }
  }

  // Allocate the solution array 
  // Set the number of ghost cells in the solution array.
  MultiFab soln(bs, Ncomp, 1);
  MultiFab soln4;
  if (do_4th) {
    soln4.define(bs, Ncomp, 3, Fab_allocate);
  }
  MultiFab gphi(bs, BL_SPACEDIM, 0);

#ifdef USEHYPRE
  if (solver_type == Hypre || solver_type == All) {
    if (ParallelDescriptor::IOProcessor()) {
      std::cout << "----------------------------------------" << std::endl;
      std::cout << "Solving with Hypre " << std::endl;
    }

    solve(soln, anaSoln, gphi, a, b, alpha, beta, beta_cc, rhs, bs, geom, Hypre);
  }
#endif

  if (solver_type == BoxLib_C || solver_type == All) {
    if (ParallelDescriptor::IOProcessor()) {
      std::cout << "----------------------------------------" << std::endl;
      std::cout << "Solving with BoxLib C++ solver " << std::endl;
    }
    solve(soln, anaSoln, gphi, a, b, alpha, beta, beta_cc, rhs, bs, geom, BoxLib_C);
  }

  if (solver_type == BoxLib_C4 || solver_type == All) {
    if (ParallelDescriptor::IOProcessor()) {
      std::cout << "----------------------------------------" << std::endl;
      std::cout << "Solving with BoxLib C++ 4th order solver " << std::endl;
    }

    solve4(soln4, anaSoln, a, b, alpha4, beta4, rhs, bs, geom);
  }

#ifdef USE_F90_SOLVERS
  if (solver_type == BoxLib_F || solver_type == All) {
    if (ParallelDescriptor::IOProcessor()) {
      std::cout << "----------------------------------------" << std::endl;
      std::cout << "Solving with BoxLib F90 solver " << std::endl;
    }

    solve(soln, anaSoln, gphi, a, b, alpha, beta, beta_cc, rhs, bs, geom, BoxLib_F);
  }
#endif

#ifdef USEHPGMG
  if (solver_type == HPGMG || solver_type == All) {
    if (ParallelDescriptor::IOProcessor()) {
      std::cout << "----------------------------------------" << std::endl;
      std::cout << "Solving with HPGMG solver " << std::endl;
    }

    solve(soln, anaSoln, gphi, a, b, alpha, beta, beta_cc, rhs, bs, geom, HPGMG);
  }
#endif

  if (ParallelDescriptor::IOProcessor()) {
    std::cout << "----------------------------------------" << std::endl;
  }
  
  BL_PROFILE_VAR_STOP(pmain);

  BoxLib::Finalize();
}
示例#13
0
文件: seq.cpp 项目: daniel-kish/MPI
int main(int argc, char**argv)
{
				int block_sz = atoi(argv[1]);
				int blocks_nr = atoi(argv[2]);
				int edge_sz = atoi(argv[3]);

				std::vector<Block> bs(blocks_nr, Block(block_sz,edge_sz) );
				Edge e(edge_sz,blocks_nr,block_sz); 

				for (int i=0; i < bs.size(); ++i)
								bs[i].fill();
				e.fill();

				//    for (int i=0; i < bs.size(); ++i)
				//		std::cout << bs[i] << '\n';
				//	std::cout << e << '\n';

				std::vector<Block> bs0 = bs;
				Edge e0 = e; 

				double total_time=0.0;
				clock_t st, end;
				st = clock();
				for (int i=0; i < bs.size(); ++i)
								bs[i].fwd();
				end = clock();

				total_time += double((end - st)) / CLOCKS_PER_SEC;

				for (int b=0; b < bs.size(); ++b)
				{
								for (int br=0; br < bs[b].rows; ++br)
								{
												double& diag = bs[b](br,br);
												RowNO r;
												r.v = &diag;
												r.sz = bs[b].cols-br;
												r.row_no = bs[b].rows*b + br;

												st = clock();
												elim_col(e,r);
												end = clock();
												total_time += double((end - st)) / CLOCKS_PER_SEC;
								}
				}
				st = clock();
				e.fwd();
				e.bwd();

				for (int i=0; i < bs.size(); ++i){
								bs[i].bwd(e.edge_soln);
				}

				end = clock();
				total_time += double((end - st)) / CLOCKS_PER_SEC;
				std::cout << "elapsed " << total_time << '\n';

				std::vector<double> soln(bs[0].rows*bs.size() + edge_sz);

				for (int i=0; i < bs.size(); ++i)
								for (int k=0; k < bs[i].sol.size(); ++k)
												soln[i*block_sz+k] = bs[i].sol[k];

				for (int k=0; k < e.edge_soln.size(); ++k)
								soln[blocks_nr*block_sz+k] = e.edge_soln[k];

				//	for (int k=0; k < soln.size(); ++k)
				//	    std::cout << soln[k] << '\n';

				std::vector<double> Rhs;

				for(int i = 0; i < bs0.size(); ++i)
				{
								for(int r=0; r < bs0[i].rows; ++r)
												Rhs.push_back(bs0[i](r,bs0[i].cols-1));
				}

				for(int i = 0; i < e0.rows; ++i)
				{
								Rhs.push_back(e0(i,e0.cols-1));
				}

				std::vector<double> rhs = mult(bs0,e0,soln);


				double residue=0.0;
				for (int i=0; i < rhs.size(); ++i)
								residue += fabs(rhs[i] - Rhs[i]);
				std::cout << "\n\nres = " << residue << '\n';
}
示例#14
0
int
main (int   argc,
      char* argv[])
{
    BoxLib::Initialize(argc,argv);

    std::cout << std::setprecision(10);

    if (argc < 2)
    {
      std::cerr << "usage:  " << argv[0] << " inputsfile [options]" << '\n';
      exit(-1);
    }

    ParmParse pp;
    
    int n;

    BoxArray bs;
    
#if BL_SPACEDIM == 2
    Box domain(IntVect(0,0),IntVect(11,11));
    std::string boxfile("gr.2_small_a") ;
#elif BL_SPACEDIM == 3
    Box domain(IntVect(0,0,0),IntVect(11,11,11));
    std::string boxfile("grids/gr.3_2x3x4") ;
#endif
    pp.query("boxes", boxfile);

    std::ifstream ifs(boxfile.c_str(), std::ios::in);

    if (!ifs)
    {
        std::string msg = "problem opening grids file: ";
        msg += boxfile.c_str();
        BoxLib::Abort(msg.c_str());
    }

    ifs >> domain;

    if (ParallelDescriptor::IOProcessor())
	std::cout << "domain: " << domain << std::endl;

    bs.readFrom(ifs);

    if (ParallelDescriptor::IOProcessor())
	std::cout << "grids:\n" << bs << std::endl;

    Geometry geom(domain);
    const Real* H = geom.CellSize();
    int ratio=2; pp.query("ratio", ratio);

    // allocate/init soln and rhs
    int Ncomp=BL_SPACEDIM;
    int Nghost=0;
    int Ngrids=bs.size();
    MultiFab soln(bs, Ncomp, Nghost, Fab_allocate); soln.setVal(0.0);
    MultiFab out(bs, Ncomp, Nghost, Fab_allocate); 
    MultiFab rhs(bs, Ncomp, Nghost, Fab_allocate); rhs.setVal(0.0);
    for(MFIter rhsmfi(rhs); rhsmfi.isValid(); ++rhsmfi)
    {
	FORT_FILLRHS(rhs[rhsmfi].dataPtr(),
		     ARLIM(rhs[rhsmfi].loVect()),ARLIM(rhs[rhsmfi].hiVect()),
		     H,&Ncomp);
    }
    
    // Create the boundary object
    MCViscBndry vbd(bs,geom);

    BCRec phys_bc;
    Array<int> lo_bc(BL_SPACEDIM), hi_bc(BL_SPACEDIM);
    pp.getarr("lo_bc",lo_bc,0,BL_SPACEDIM);
    pp.getarr("hi_bc",hi_bc,0,BL_SPACEDIM);
    for (int i = 0; i < BL_SPACEDIM; i++)
    {
        phys_bc.setLo(i,lo_bc[i]);
        phys_bc.setHi(i,hi_bc[i]);
    }

    
    // Create the BCRec's interpreted by ViscBndry objects
#if BL_SPACEDIM==2
    Array<BCRec> pbcarray(4);
    pbcarray[0] = BCRec(D_DECL(REFLECT_ODD,REFLECT_EVEN,EXT_DIR),
			D_DECL(EXT_DIR,EXT_DIR,EXT_DIR));
    pbcarray[1] = BCRec(D_DECL(REFLECT_EVEN,REFLECT_ODD,EXT_DIR),
			D_DECL(EXT_DIR,EXT_DIR,EXT_DIR));
    pbcarray[2] = BCRec(D_DECL(EXT_DIR,EXT_DIR,EXT_DIR),
			D_DECL(EXT_DIR,EXT_DIR,EXT_DIR));
    pbcarray[3] = BCRec(D_DECL(EXT_DIR,EXT_DIR,EXT_DIR),
			D_DECL(EXT_DIR,EXT_DIR,EXT_DIR));
#elif BL_SPACEDIM==3
    Array<BCRec> pbcarray(12);

#if 1
    pbcarray[0] = BCRec(EXT_DIR,EXT_DIR,EXT_DIR,EXT_DIR,EXT_DIR,EXT_DIR);
    pbcarray[1] = BCRec(EXT_DIR,EXT_DIR,EXT_DIR,EXT_DIR,EXT_DIR,EXT_DIR);
    pbcarray[2] = BCRec(EXT_DIR,EXT_DIR,EXT_DIR,EXT_DIR,EXT_DIR,EXT_DIR);
    pbcarray[3] = BCRec(D_DECL(EXT_DIR,EXT_DIR,EXT_DIR),
			D_DECL(EXT_DIR,EXT_DIR,EXT_DIR));
    pbcarray[4] = BCRec(D_DECL(EXT_DIR,EXT_DIR,EXT_DIR),
			D_DECL(EXT_DIR,EXT_DIR,EXT_DIR));
    pbcarray[5] = BCRec(D_DECL(EXT_DIR,EXT_DIR,EXT_DIR),
			D_DECL(EXT_DIR,EXT_DIR,EXT_DIR));
    pbcarray[6] = BCRec(D_DECL(EXT_DIR,EXT_DIR,EXT_DIR),
			D_DECL(EXT_DIR,EXT_DIR,EXT_DIR));
    pbcarray[7] = BCRec(D_DECL(EXT_DIR,EXT_DIR,EXT_DIR),
			D_DECL(EXT_DIR,EXT_DIR,EXT_DIR));
    pbcarray[8] = BCRec(D_DECL(EXT_DIR,EXT_DIR,EXT_DIR),
			D_DECL(EXT_DIR,EXT_DIR,EXT_DIR));
    pbcarray[9] = BCRec(D_DECL(EXT_DIR,EXT_DIR,EXT_DIR),
			D_DECL(EXT_DIR,EXT_DIR,EXT_DIR));
    pbcarray[10] = BCRec(D_DECL(EXT_DIR,EXT_DIR,EXT_DIR),
			 D_DECL(EXT_DIR,EXT_DIR,EXT_DIR));
    pbcarray[11] = BCRec(D_DECL(EXT_DIR,EXT_DIR,EXT_DIR),
			 D_DECL(EXT_DIR,EXT_DIR,EXT_DIR));
#else
    for (int i = 0; i < 12; i++)
        pbcarray[i] = phys_bc;
#endif
#endif
    
    Nghost = 1; // need space for bc info
    MultiFab fine(bs,Ncomp,Nghost,Fab_allocate);
    for(MFIter finemfi(fine); finemfi.isValid(); ++finemfi)
    {
	FORT_FILLFINE(fine[finemfi].dataPtr(),
		      ARLIM(fine[finemfi].loVect()),ARLIM(fine[finemfi].hiVect()),
		      H,&Ncomp);
    }

    // Create "background coarse data"
    Box crse_bx = Box(domain).coarsen(ratio).grow(1);
    BoxArray cba(crse_bx);
    cba.maxSize(32);
    Real h_crse[BL_SPACEDIM];
    for (n=0; n<BL_SPACEDIM; n++) h_crse[n] = H[n]*ratio;

    MultiFab crse_mf(cba, Ncomp, 0);
//    FArrayBox crse_fab(crse_bx,Ncomp);

    for (MFIter mfi(crse_mf); mfi.isValid(); ++mfi)
    {
        FORT_FILLCRSE(crse_mf[mfi].dataPtr(),
                      ARLIM(crse_mf[mfi].loVect()),ARLIM(crse_mf[mfi].hiVect()),
                      h_crse,&Ncomp);
    }


    
    // Create coarse boundary register, fill w/data from coarse FAB
    int bndry_InRad=0;
    int bndry_OutRad=1;
    int bndry_Extent=1;
    BoxArray cbs = BoxArray(bs).coarsen(ratio);
    BndryRegister cbr(cbs,bndry_InRad,bndry_OutRad,bndry_Extent,Ncomp);
    for (OrientationIter face; face; ++face)
    {
	Orientation f = face();
	FabSet& bnd_fs(cbr[f]);
	bnd_fs.copyFrom(crse_mf, 0, 0, 0, Ncomp);
    }
  
    // Interpolate crse data to fine boundary, where applicable
    int cbr_Nstart=0;
    int fine_Nstart=0;
    int bndry_Nstart=0;
    vbd.setBndryValues(cbr,cbr_Nstart,fine,fine_Nstart,
		       bndry_Nstart,Ncomp,ratio,pbcarray);
  
    Nghost = 1; // other variables don't need extra space
    
    DivVis lp(vbd,H);
    
    Real a = 0.0;
    Real b[BL_SPACEDIM];
    b[0] = 1.0;
    b[1] = 1.0;
#if BL_SPACEDIM>2
    b[2] = 1.0;
#endif
    MultiFab  acoefs;
    int NcompA = (BL_SPACEDIM == 2  ?  2  :  1);
    acoefs.define(bs, NcompA, Nghost, Fab_allocate);
    acoefs.setVal(a);
    MultiFab bcoefs[BL_SPACEDIM];
    for (n=0; n<BL_SPACEDIM; ++n)
    {
	BoxArray bsC(bs);
	bcoefs[n].define(bsC.surroundingNodes(n), 1,
			 Nghost, Fab_allocate);
#if 1
	for(MFIter bmfi(bcoefs[n]); bmfi.isValid(); ++bmfi)
	{
	    FORT_MAKEMU(bcoefs[n][bmfi].dataPtr(),
			ARLIM(bcoefs[n][bmfi].loVect()),ARLIM(bcoefs[n][bmfi].hiVect()),H,n);
	}
#else
	bcoefs[n].setVal(b[n]);
#endif
    } // -->> over dimension
    lp.setCoefficients(acoefs, bcoefs);
#if 1
    lp.maxOrder(4);
#endif
    
    Nghost = 1;
    MultiFab tsoln(bs, Ncomp, Nghost, Fab_allocate); 
    tsoln.setVal(0.0);
#if 1
    tsoln.copy(fine);
#endif
#if 0
    // testing apply
    lp.apply(out,tsoln);
    Box subbox = out[0].box();
    Real n1 = out[0].norm(subbox,1,0,BL_SPACEDIM)*pow(H[0],BL_SPACEDIM);
    ParallelDescriptor::ReduceRealSum(n1);
    if (ParallelDescriptor::IOProcessor())
    {
	cout << "n1 output is "<<n1<<std::endl;
    }
    out.minus(rhs,0,BL_SPACEDIM,0);
    // special to single grid prob
    Real n2 = out[0].norm(subbox,1,0,BL_SPACEDIM)*pow(H[0],BL_SPACEDIM);
    ParallelDescriptor::ReduceRealSum(n2);
    if (ParallelDescriptor::IOProcessor())
    {
	cout << "n2 difference is "<<n2<<std::endl;
    }
#if 0
    subbox.grow(-1);
    Real n3 = out[0].norm(subbox,0,0,BL_SPACEDIM)*pow(H[0],BL_SPACEDIM);
    ParallelDescriptor::ReduceRealMax(n3);
    if (ParallelDescriptor::IOProcessor())
    {
	cout << "n3 difference is "<<n3<<std::endl;
    }
#endif
    
#endif
    
    const IntVect refRatio(D_DECL(2,2,2));
    const Real bgVal = 1.0;
    
#if 1
#ifndef NDEBUG
    // testing flux computation
    BoxArray xfluxbox(bs);
    xfluxbox.surroundingNodes(0);
    MultiFab xflux(xfluxbox,Ncomp,Nghost,Fab_allocate);
    xflux.setVal(1.e30);
    BoxArray yfluxbox(bs);
    yfluxbox.surroundingNodes(1);
    MultiFab yflux(yfluxbox,Ncomp,Nghost,Fab_allocate);
    yflux.setVal(1.e30);
#if BL_SPACEDIM>2
    BoxArray zfluxbox(bs);
    zfluxbox.surroundingNodes(2);
    MultiFab zflux(zfluxbox,Ncomp,Nghost,Fab_allocate);
    zflux.setVal(1.e30);
#endif
    lp.compFlux(xflux,
		yflux,
#if BL_SPACEDIM>2
		zflux,
#endif
		tsoln);
    
    // Write fluxes
    //writeMF(&xflux,"xflux.mfab");
    //writeMF(&yflux,"yflux.mfab");
#if BL_SPACEDIM>2
    //writeMF(&zflux,"zflux.mfab");
#endif
    
#endif
#endif
    
    Real tolerance = 1.0e-10; pp.query("tol", tolerance);
    Real tolerance_abs = 1.0e-10; pp.query("tol_abs", tolerance_abs);

#if 0
    cout << "Bndry Data object:" << std::endl;
    cout << lp.bndryData() << std::endl;
#endif
    
#if 0
    bool use_mg_pre = false;
    MCCGSolver cg(lp,use_mg_pre);
    cg.solve(soln,rhs,tolerance,tolerance_abs);
#else
    MCMultiGrid mg(lp);
    mg.solve(soln,rhs,tolerance,tolerance_abs);
#endif

#if 0
    cout << "MCLinOp object:" << std::endl;
    cout << lp << std::endl;
#endif
    
    VisMF::Write(soln,"soln");
    
#if 0
    // apply operator to soln to see if really satisfies eqn
    tsoln.copy(soln);
    lp.apply(out,tsoln);
    soln.copy(out);
    // Output "apply" results on soln
    VisMF::Write(soln,"apply");

    // Compute truncation
    for (MFIter smfi(soln); smfi.isValid(); ++smfi)
    {
	soln[smfi] -= fine[smfi];
    }
    for( int icomp=0; icomp < BL_SPACEDIM ; icomp++ )
    {
	Real solnMin = soln.min(icomp);
	Real solnMax = soln.max(icomp);
	ParallelDescriptor::ReduceRealMin(solnMin);
	ParallelDescriptor::ReduceRealMax(solnMax);
	if (ParallelDescriptor::IOProcessor())
	{
	    cout << icomp << "  "<<solnMin << " " << solnMax <<std::endl;
	}
    }
    // Output truncation
    VisMF::Write(soln,"trunc");
#endif

    int dumpLp=0; pp.query("dumpLp",dumpLp);
    bool write_lp = (dumpLp == 1 ? true : false);
    if (write_lp)
	std::cout << lp << std::endl;

    // Output trunc
    ParallelDescriptor::EndParallel();
}