void TBSpaceAllocator::FreeSpace(Space *space)
{
	m_used_space_list.Remove(space);
	m_available_space += space->width;

	// Find where in m_free_space_list we should insert the space,
	// or which existing space we can extend.
	Space *preceeding = nullptr;
	Space *succeeding = nullptr;
	for (Space *fs = m_free_space_list.GetFirst(); fs; fs = fs->GetNext())
	{
		if (fs->x < space->x)
			preceeding = fs;
		if (fs->x > space->x)
		{
			succeeding = fs;
			break;
		}
	}
	if (preceeding && preceeding->x + preceeding->width == space->x)
	{
		preceeding->width += space->width;
		delete space;
	}
	else if (succeeding && succeeding->x == space->x + space->width)
	{
		succeeding->x -= space->width;
		succeeding->width += space->width;
		delete space;
	}
	else
	{
		if (preceeding)
			m_free_space_list.AddAfter(space, preceeding);
		else if (succeeding)
			m_free_space_list.AddBefore(space, succeeding);
		else
		{
			assert(!m_free_space_list.HasLinks());
			m_free_space_list.AddLast(space);
		}
	}
	// Merge free spaces
	Space *fs = m_free_space_list.GetFirst();
	while (fs)
	{
		Space *next_fs = fs->GetNext();
		if (!next_fs)
			break;
		if (fs->x + fs->width == next_fs->x)
		{
			fs->width += next_fs->width;
			m_free_space_list.Delete(next_fs);
			continue;
		}
		fs = next_fs;
	}

#ifdef TB_RUNTIME_DEBUG_INFO
	// Check that free space is in order
	Space *tmp = m_free_space_list.GetFirst();
	int x = 0;
	while (tmp)
	{
		assert(tmp->x >= x);
		x = tmp->x + tmp->width;
		tmp = tmp->GetNext();
	}
#endif // TB_RUNTIME_DEBUG_INFO
}
Esempio n. 2
0
  ExecStatus
  SuperOfInter<View0,View1,View2>::propagate(Space& home, const ModEventDelta& med) {

    bool allassigned = x0.assigned() && x1.assigned() && x2.assigned();

    ModEvent me0 = View0::me(med);
    ModEvent me1 = View1::me(med);
    ModEvent me2 = View2::me(med);

    bool modified = false;

    do {
      // glb(x2) >= glb(x0) ^ glb(x1)
      if ( modified || Rel::testSetEventLB(me0,me1)) {
        GlbRanges<View0> lb0(x0);
        GlbRanges<View1> lb1(x1);
        Iter::Ranges::Inter<GlbRanges<View0>,GlbRanges<View1> >
          is(lb0, lb1);

        GECODE_ME_CHECK_MODIFIED(modified,x2.includeI(home,is));
      }

      // lub(x0) -= glb(x1)-lub(x2)
      // lub(x1) -= glb(x0)-lub(x2)
      if ( modified || Rel::testSetEventAnyB(me0,me1,me2)) {
         modified = false;
        GlbRanges<View1> lb12(x1);
        LubRanges<View2> ub22(x2);
        Iter::Ranges::Diff<GlbRanges<View1>, LubRanges<View2> >
          diff1(lb12, ub22);

        GECODE_ME_CHECK_MODIFIED(modified, x0.excludeI(home,diff1));

        GlbRanges<View0> lb01(x0);
        LubRanges<View2> ub23(x2);
        Iter::Ranges::Diff<GlbRanges<View0>, LubRanges<View2> >
          diff2(lb01, ub23);

        GECODE_ME_CHECK_MODIFIED(modified, x1.excludeI(home,diff2));
      } else {
         modified = false;
      }

      // Cardinality propagation
      if ( modified ||
            Rel::testSetEventCard(me0,me1,me2) ||
           Rel::testSetEventUB(me0,me1)
           ) {

        LubRanges<View0> ub0(x0);
        LubRanges<View1> ub1(x1);
        Iter::Ranges::Union<LubRanges<View0>, LubRanges<View1> > u(ub0,ub1);

        unsigned int m = Iter::Ranges::size(u);

        if (m < x0.cardMin() + x1.cardMin()) {
          GECODE_ME_CHECK_MODIFIED(modified,
                            x2.cardMin( home,
                                        x0.cardMin()+x1.cardMin() - m ) );
        }
        if (m + x2.cardMax() > x1.cardMin()) {
          GECODE_ME_CHECK_MODIFIED(modified,
                            x0.cardMax( home,
                                        m+x2.cardMax()-x1.cardMin() )  );
        }
        if (m + x2.cardMax() > x0.cardMin()) {
          GECODE_ME_CHECK_MODIFIED(modified,
                            x1.cardMax( home,
                                        m+x2.cardMax()-x0.cardMin() )  );
        }
      }
    } while (modified);


    if (shared(x0,x1,x2)) {
      if (allassigned) {
        return home.ES_SUBSUMED(*this);
      } else {
        return ES_NOFIX;
      }
    } else {
      if (x0.assigned() + x1.assigned() + x2.assigned() >= 2) {
         return home.ES_SUBSUMED(*this);
      } else {
        return ES_FIX;
      }
    }

  }
Esempio n. 3
0
 ExecStatus
 NthRoot<A,B>::propagate(Space& home, const ModEventDelta&) {
   GECODE_ME_CHECK(x1.eq(home,nth_root(x0.domain(),m_n)));
   GECODE_ME_CHECK(x0.eq(home,pow(x1.domain(),m_n)));
   return x0.assigned() ? home.ES_SUBSUMED(*this) : ES_FIX;
 }
Esempio n. 4
0
int main(int argc, char **argv) {
	int res = ERR_SUCCESS;

#ifdef WITH_PETSC
	PetscInitialize(&argc, &argv, (char *) PETSC_NULL, PETSC_NULL);
#endif
	set_verbose(false);

	if (argc < 5) error("Not enough parameters.");

	H1ShapesetLobattoHex shapeset;

	printf("* Loading mesh '%s'\n", argv[1]);
	Mesh mesh;
	Mesh3DReader mloader;
	if (!mloader.load(argv[1], &mesh)) error("Loading mesh file '%s'\n", argv[1]);

	printf("* Setting the space up\n");
	H1Space space(&mesh, &shapeset);
	space.set_bc_types(bc_types);
	space.set_essential_bc_values(essential_bc_values);

	int o[3] = { 0, 0, 0 };
	sscanf(argv[2], "%d", o + 0);
	sscanf(argv[3], "%d", o + 1);
	sscanf(argv[4], "%d", o + 2);
	order3_t order(o[0], o[1], o[2]);
	printf("  - Setting uniform order to (%d, %d, %d)\n", order.x, order.y, order.z);
	space.set_uniform_order(order);

	WeakForm wf;
	wf.add_matrix_form(bilinear_form<double, scalar>, bilinear_form<ord_t, ord_t>, SYM, ANY);
	wf.add_vector_form(linear_form<double, scalar>, linear_form<ord_t, ord_t>, ANY);

	LinearProblem lp(&wf);
	lp.set_space(&space);

	bool done = false;
	int iter = 0;
	do {
		Timer assemble_timer("Assembling stiffness matrix");
		Timer solve_timer("Solving stiffness matrix");

		printf("\n=== Iter #%d ================================================================\n", iter);

		printf("\nSolution\n");

#if defined WITH_UMFPACK
		UMFPackMatrix mat;
		UMFPackVector rhs;
		UMFPackLinearSolver solver(&mat, &rhs);
#elif defined WITH_PARDISO
		PardisoMatrix mat;
		PardisoVector rhs;
		PardisoLinearSolver solver(&mat, &rhs);
#elif defined WITH_PETSC
		PetscMatrix mat;
		PetscVector rhs;
		PetscLinearSolver solver(&mat, &rhs);
#elif defined WITH_MUMPS
		MumpsMatrix mat;
		MumpsVector rhs;
		MumpsSolver solver(&mat, &rhs);
#endif

		int ndofs = space.assign_dofs();
		printf("  - Number of DOFs: %d\n", ndofs);

		// assemble stiffness matrix
		printf("  - Assembling... "); fflush(stdout);
		assemble_timer.reset();
		assemble_timer.start();
		lp.assemble(&mat, &rhs);
		assemble_timer.stop();
		printf("done in %s (%lf secs)\n", assemble_timer.get_human_time(), assemble_timer.get_seconds());

		// solve the stiffness matrix
		printf("  - Solving... "); fflush(stdout);
		solve_timer.reset();
		solve_timer.start();
		bool solved = solver.solve();
		solve_timer.stop();
		if (solved)
			printf("done in %s (%lf secs)\n", solve_timer.get_human_time(), solve_timer.get_seconds());
		else {
			res = ERR_FAILURE;
			printf("failed\n");
			break;
		}

		printf("Reference solution\n");

#if defined WITH_UMFPACK
		UMFPackLinearSolver rsolver(&mat, &rhs);
#elif defined WITH_PARDISO
		PardisoLinearSolver rsolver(&mat, &rhs);
#elif defined WITH_PETSC
		PetscLinearSolver rsolver(&mat, &rhs);
#elif defined WITH_MUMPS
		MumpsSolver rsolver(&mat, &rhs);
#endif

		Mesh rmesh;
		rmesh.copy(mesh);
		rmesh.refine_all_elements(H3D_H3D_H3D_REFT_HEX_XYZ);

		Space *rspace = space.dup(&rmesh);
		rspace->copy_orders(space, 1);

		LinearProblem rlp(&wf);
		rlp.set_space(rspace);

		int rndofs = rspace->assign_dofs();
		printf("  - Number of DOFs: %d\n", rndofs);

		printf("  - Assembling... "); fflush(stdout);
		assemble_timer.reset();
		assemble_timer.start();
		rlp.assemble(&mat, &rhs);
		assemble_timer.stop();
		printf("done in %s (%lf secs)\n", assemble_timer.get_human_time(), assemble_timer.get_seconds());

		printf("  - Solving... "); fflush(stdout);
		solve_timer.reset();
		solve_timer.start();
		bool rsolved = rsolver.solve();
		solve_timer.stop();
		if (rsolved)
			printf("done in %s (%lf secs)\n", solve_timer.get_human_time(), solve_timer.get_seconds());
		else {
			res = ERR_FAILURE;
			printf("failed\n");
			break;
		}

		Solution sln(&mesh);
		sln.set_coeff_vector(&space, solver.get_solution());

		Solution rsln(&rmesh);
		rsln.set_coeff_vector(rspace, rsolver.get_solution());

		printf("Adaptivity:\n");
		H1Adapt hp(&space);
		double tol = hp.calc_error(&sln, &rsln) * 100;
		printf("  - tolerance: "); fflush(stdout);
		printf("% lf\n", tol);
		if (tol < TOLERANCE) {
			printf("\nDone\n");
			ExactSolution ex_sln(&mesh, exact_solution);
			// norm
			double h1_sln_norm = h1_norm(&sln);
			double h1_err_norm = h1_error(&sln, &ex_sln);
			printf("  - H1 solution norm:   % le\n", h1_sln_norm);
			printf("  - H1 error norm:      % le\n", h1_err_norm);

			double l2_sln_norm = l2_norm(&sln);
			double l2_err_norm = l2_error(&sln, &ex_sln);
			printf("  - L2 solution norm:   % le\n", l2_sln_norm);
			printf("  - L2 error norm:      % le\n", l2_err_norm);

			if (h1_err_norm > EPS || l2_err_norm > EPS) {
				// calculated solution is not enough precise
				res = ERR_FAILURE;
			}

			break;
		}

		Timer t("");
		printf("  - adapting... "); fflush(stdout);
		t.start();
		hp.adapt(THRESHOLD);
		t.stop();
		printf("done in %lf secs (refined %d element(s))\n", t.get_seconds(), hp.get_num_refined_elements());

		iter++;
	} while (!done);


#ifdef WITH_PETSC
	PetscFinalize();
#endif

	return res;
}
Esempio n. 5
0
	//Prints middle row with two spaces on either edge of the baord
	//those spaces are in spaces[space1Index] and spaces[space2Index]
	void Game_Board::printMiddleRow(int space1Index, int space2Index){

		//print out each spaces name, centered and ending with a |
		int padding = SPACE_WIDTH-2;

		for(int i = 0; i < SPACES_IN_ROW; i++){
			if(i == 0){
				Space current = spaces[space1Index];
				std::cout << "|" << std::left << std::setw(padding) << centerString(current.getName()) << "|";
			} else if(i == 10){
				Space current = spaces[space2Index];
				std::cout << "|" << std::left << std::setw(padding) << centerString(current.getName()) << "|";
			}else{
				int x = 1;
				if(i == 9) x = 2;
				for(int j = 0; j < SPACE_WIDTH - x; j++){
					std::cout << " ";
				}
			}
		}
		std::cout << std::endl; // right side ending bracket

		//print out each spaces Owner, centered and ending with a |
		for(int i = 0; i < SPACES_IN_ROW; i++){
			if(i == 0){
				Space current = spaces[space1Index];
				if(current.isOwnable()){
					std::string owner = current.getOwner();
					std::string ownerLine = "Owner: " + owner;
					std::cout << "|" << std::left << std::setw(padding) << centerString(ownerLine) << "|";
				}else{
					std::cout << "|";
					for(int j = 0; j < SPACE_WIDTH - 2; j++){
						std::cout << " ";
					}
					std::cout << "|";
				}
			} else if(i == 10){
				Space current = spaces[space2Index];
				if(current.isOwnable()){
					std::string owner = current.getOwner();
					std::string ownerLine = "Owner: " + owner;
					std::cout << "|" << std::left << std::setw(padding) << centerString(ownerLine) << "|";
				} else{
					std::cout << "|";
					for(int j = 0; j < SPACE_WIDTH - 2; j++){
						std::cout << " ";
					}
					std::cout << "|";
				}
			}else{
				int x = 1;
				if(i == 9) x = 2;
				for(int j = 0; j < SPACE_WIDTH - x; j++){
					std::cout << " ";
				}
			}
		}
		std::cout << std::endl;

		for(int i = 0; i < SPACES_IN_ROW; i++){
			if(i == 0 || i == 10){
				std::cout << "|";
				for(int j = 0; j < SPACE_WIDTH-2; j++){
					std::cout << " ";
				}
				std::cout << "|";
			}else{
				int x = 1;
				if(i == 9) x = 2;
				for(int j = 0; j < SPACE_WIDTH - x; j++){
					std::cout << " ";
				}
			}
		}
		std::cout << std::endl;

		//Prints out the players currently on each space
		for(int i = 0; i < SPACES_IN_ROW; i++){
			if(i == 0){
				Space current = spaces[space1Index];
				std::string result = current.playersOnSpaceToString();
				std::cout << "|" << std::left << std::setw(padding) << centerString(result) << "|";
			} else if(i == 10){
				Space current = spaces[space2Index];
				std::string result = current.playersOnSpaceToString();
				std::cout << "|" << std::left << std::setw(padding) << centerString(result) << "|";
			}else{
				int x = 1;
				if(i == 9) x = 2;
				for(int j = 0; j < SPACE_WIDTH - x; j++){
					std::cout << " ";
				}
			}
		}
		std::cout << std::endl;

	}
Esempio n. 6
0
int main()
{
    // Create space, set Dirichlet BC, enumerate basis functions.
    Space* space = new Space(A, B, NELEM, DIR_BC_LEFT, DIR_BC_RIGHT, P_INIT, NEQ, NEQ);

    // Enumerate basis functions, info for user.
    int ndof = Space::get_num_dofs(space);
    info("ndof: %d", ndof);

    // Initialize the weak formulation.
    WeakForm wf(2);
    wf.add_matrix_form(0, 0, jacobian_0_0);
    wf.add_matrix_form(0, 1, jacobian_0_1);
    wf.add_matrix_form(1, 0, jacobian_1_0);
    wf.add_matrix_form(1, 1, jacobian_1_1);
    wf.add_vector_form(0, residual_0);
    wf.add_vector_form(1, residual_1);

    // Initialize the FE problem.
    bool is_linear = false;
    DiscreteProblem *dp = new DiscreteProblem(&wf, space, is_linear);

    // Newton's loop.
    // Fill vector coeff_vec using dof and coeffs arrays in elements.
    double *coeff_vec = new double[Space::get_num_dofs(space)];
    get_coeff_vector(space, coeff_vec);

    // Set up the solver, matrix, and rhs according to the solver selection.
    SparseMatrix* matrix = create_matrix(matrix_solver);
    Vector* rhs = create_vector(matrix_solver);
    Solver* solver = create_linear_solver(matrix_solver, matrix, rhs);

    int it = 1;
    while (1) {
        // Obtain the number of degrees of freedom.
        int ndof = Space::get_num_dofs(space);

        // Assemble the Jacobian matrix and residual vector.
        dp->assemble(coeff_vec, matrix, rhs);

        // Calculate the l2-norm of residual vector.
        double res_l2_norm = get_l2_norm(rhs);

        // Info for user.
        info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(space), res_l2_norm);

        // If l2 norm of the residual vector is within tolerance, then quit.
        // NOTE: at least one full iteration forced
        //       here because sometimes the initial
        //       residual on fine mesh is too small.
        if(res_l2_norm < NEWTON_TOL && it > 1) break;

        // Multiply the residual vector with -1 since the matrix
        // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n).
        for(int i=0; i<ndof; i++) rhs->set(i, -rhs->get(i));

        // Solve the linear system.
        if(!solver->solve())
            error ("Matrix solver failed.\n");

        // Add \deltaY^{n+1} to Y^n.
        for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i];

        // If the maximum number of iteration has been reached, then quit.
        if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge.");

        // Copy coefficients from vector y to elements.
        set_coeff_vector(coeff_vec, space);

        it++;
    }

    // Plot the solution.
    Linearizer l(space);
    l.plot_solution("solution.gp");

    // Plot the resulting space.
    space->plot("space.gp");

    info("Done.");
    return 0;
}
Esempio n. 7
0
  void
  TreeCanvas::inspectCurrentNode(bool fix, int inspectorNo) {
    QMutexLocker locker(&mutex);

    if (currentNode->isHidden()) {
      toggleHidden();
      return;
    }

    int failedInspectorType = -1;
    int failedInspector = -1;
    bool needCentering = false;
    try {
      switch (currentNode->getStatus()) {
      case UNDETERMINED:
          {
            unsigned int kids =  
              currentNode->getNumberOfChildNodes(*na,curBest,stats,c_d,a_d);
            int depth = -1;
            for (VisualNode* p = currentNode; p != NULL; p=p->getParent(*na))
              depth++;
            if (kids > 0) {
              needCentering = true;
              depth++;
            }
            stats.maxDepth =
              std::max(stats.maxDepth, depth);
            if (currentNode->getStatus() == SOLVED) {
              assert(currentNode->hasCopy());
              emit solution(currentNode->getWorkingSpace());
              currentNode->purge(*na);
            }
            emit statusChanged(currentNode,stats,true);
            for (int i=0; i<moveInspectors.size(); i++) {
              if (moveInspectors[i].second) {
                failedInspectorType = 0;
                failedInspector = i;
                moveInspectors[i].first->
                  inspect(*currentNode->getWorkingSpace());
                failedInspectorType = -1;
              }
            }
          }
          break;
      case FAILED:
      case STOP:
      case UNSTOP:
      case BRANCH:
      case SOLVED:
        {
          // SizeCursor sc(currentNode);
          // PreorderNodeVisitor<SizeCursor> pnv(sc);
          // int nodes = 1;
          // while (pnv.next()) { nodes++; }
          // std::cout << "sizeof(VisualNode): " << sizeof(VisualNode)
          //           << std::endl;
          // std::cout << "Size: " << (pnv.getCursor().s)/1024 << std::endl;
          // std::cout << "Nodes: " << nodes << std::endl;
          // std::cout << "Size / node: " << (pnv.getCursor().s)/nodes
          //           << std::endl;

          Space* curSpace;
        
          if (fix) {
            if (currentNode->isRoot() && currentNode->getStatus() == FAILED)
              break;
            curSpace = currentNode->getSpace(*na,curBest,c_d,a_d);
            if (currentNode->getStatus() == SOLVED &&
                curSpace->status() != SS_SOLVED) {
              // in the presence of weakly monotonic propagators, we may have to
              // use search to find the solution here
              Space* dfsSpace = Gecode::dfs(curSpace);
              delete curSpace;
              curSpace = dfsSpace;
            }          
          } else {
            if (currentNode->isRoot())
              break;
            VisualNode* p = currentNode->getParent(*na);
            curSpace = p->getSpace(*na,curBest,c_d,a_d);
            switch (curSpace->status()) {
            case SS_SOLVED:
            case SS_FAILED:
              break;
            case SS_BRANCH:
              curSpace->commit(*p->getChoice(), 
                               currentNode->getAlternative(*na));
              break;
            default:
              GECODE_NEVER;
            }
          }

          if (inspectorNo==-1) {
            for (int i=0; i<doubleClickInspectors.size(); i++) {
              if (doubleClickInspectors[i].second) {
                failedInspectorType = 1;
                failedInspector = i;
                doubleClickInspectors[i].first->inspect(*curSpace);
                failedInspectorType = -1;
              }
            }
          } else {
            failedInspectorType = 1;
            failedInspector = inspectorNo;
            doubleClickInspectors[inspectorNo].first->inspect(*curSpace);
            failedInspectorType = -1;
          }
          delete curSpace;
        }
        break;
      }
    } catch (Exception e) {
      switch (failedInspectorType) {
      case 0:
        std::cerr << "Exception in move inspector "
                  << failedInspector;
        break;
      case 1:
        std::cerr << "Exception in double-click inspector "
                  << failedInspector;
        break;
      default:
        std::cerr << "Exception ";
        break;
      }
      std::cerr << ": " << e.what() << "." << std::endl;
      std::cerr << "Stopping..." << std::endl;
      std::exit(EXIT_FAILURE);
    }

    currentNode->dirtyUp(*na);
    update();
    if (needCentering)
      centerCurrentNode();
  }
Esempio n. 8
0
  ExecStatus
  ReProp<View,rm>::propagate(Space& home, const ModEventDelta& med) {
    // Add assigned views to value set
    if (View::me(med) == ME_INT_VAL)
      add(home,vs,x);

    if (b.one()) {
      if (rm == RM_PMI)
        return home.ES_SUBSUMED(*this);
      ValSet vsc(vs);
      vs.flush();
      GECODE_REWRITE(*this,Prop<View>::post(home,vsc,x,y));
    }

    if (b.zero()) {
      if (rm != RM_IMP) {
        ValSet::Ranges vsr(vs);
        GECODE_ME_CHECK(y.minus_r(home,vsr,false));
        for (int i=x.size(); i--; )
          GECODE_ES_CHECK(Rel::Nq<View>::post(home,x[i],y));
      }
      return home.ES_SUBSUMED(*this);
    }

    // Eliminate views from x
    eliminate(home);
    
    switch (vs.compare(y)) {
    case Iter::Ranges::CS_SUBSET:
      if (rm != RM_IMP)
        GECODE_ME_CHECK(b.one(home));
      return home.ES_SUBSUMED(*this);
    case Iter::Ranges::CS_DISJOINT:
      if (x.size() == 0) {
        if (rm != RM_PMI)
          GECODE_ME_CHECK(b.zero(home));
        return home.ES_SUBSUMED(*this);
      }
      break;
    case Iter::Ranges::CS_NONE:
      break;
    default:
      GECODE_NEVER;
    }

    // Check whether y is in union of x and value set
    if (x.size() > 0) {
      Region r(home);

      ValSet::Ranges vsr(vs);
      ViewRanges<View> xsr(x[x.size()-1]);
      Iter::Ranges::NaryUnion  u(r,vsr,xsr);
      for (int i=x.size()-1; i--; ) {
        ViewRanges<View> xir(x[i]);
        u |= xir;
      }

      ViewRanges<View> yr(y);
      
      if (Iter::Ranges::disjoint(u,yr)) {
        if (rm != RM_PMI)
          GECODE_ME_CHECK(b.zero(home));
        return home.ES_SUBSUMED(*this);
      }
    }

    return ES_FIX;
  }
Esempio n. 9
0
Point::Point(const Point & point, const Space & space):
space(space){
    x = space.getLocalX(point.physicalX());
    y = space.getLocalY(point.physicalY());
}
Esempio n. 10
0
int main() {
  // Three macroelements are defined above via the interfaces[] array.
  // poly_orders[]... initial poly degrees of macroelements.
  // material_markers[]... material markers of macroelements.
  // subdivisions[]... equidistant subdivision of macroelements.
  int poly_orders[N_MAT] = {P_init_inner, P_init_outer, P_init_reflector };
  int material_markers[N_MAT] = {Marker_inner, Marker_outer, Marker_reflector };
  int subdivisions[N_MAT] = {N_subdiv_inner, N_subdiv_outer, N_subdiv_reflector };

  // Create space.
  Space* space = new Space(N_MAT, interfaces, poly_orders, material_markers, subdivisions, N_GRP, N_SLN);
  // Enumerate basis functions, info for user.
  info("N_dof = %d", Space::get_num_dofs(space));

  // Initial approximation: u = 1.
  double K_EFF_old;
  double init_val = 1.0;
  set_vertex_dofs_constant(space, init_val, 0);
  
  // Initialize the weak formulation.
  WeakForm wf;
  wf.add_matrix_form(jacobian_vol_inner, NULL, Marker_inner);
  wf.add_matrix_form(jacobian_vol_outer, NULL, Marker_outer);
  wf.add_matrix_form(jacobian_vol_reflector, NULL, Marker_reflector);
  wf.add_vector_form(residual_vol_inner, NULL, Marker_inner);
  wf.add_vector_form(residual_vol_outer, NULL, Marker_outer);
  wf.add_vector_form(residual_vol_reflector, NULL, Marker_reflector);
  wf.add_vector_form_surf(residual_surf_left, BOUNDARY_LEFT);
  wf.add_matrix_form_surf(jacobian_surf_right, BOUNDARY_RIGHT);
  wf.add_vector_form_surf(residual_surf_right, BOUNDARY_RIGHT);

  // Initialize the FE problem.
  bool is_linear = false;
  DiscreteProblem *dp = new DiscreteProblem(&wf, space, is_linear);

  // Source iteration (power method).
  for (int i = 0; i < Max_SI; i++)
  {	
    // Obtain fission source.
    int current_solution = 0, previous_solution = 1;
    copy_dofs(current_solution, previous_solution, space);
		
    // Obtain the number of degrees of freedom.
    int ndof = Space::get_num_dofs(space);

    // Fill vector coeff_vec using dof and coeffs arrays in elements.
  double *coeff_vec = new double[Space::get_num_dofs(space)];
    get_coeff_vector(space, coeff_vec);
  
    // Set up the solver, matrix, and rhs according to the solver selection.
    SparseMatrix* matrix = create_matrix(matrix_solver);
    Vector* rhs = create_vector(matrix_solver);
    Solver* solver = create_linear_solver(matrix_solver, matrix, rhs);
  
    int it = 1;
  while (1) {
    // Obtain the number of degrees of freedom.
    int ndof = Space::get_num_dofs(space);

      // Assemble the Jacobian matrix and residual vector.
      dp->assemble(matrix, rhs);

      // Calculate the l2-norm of residual vector.
      double res_l2_norm = get_l2_norm(rhs);

      // Info for user.
      info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(space), res_l2_norm);

      // If l2 norm of the residual vector is within tolerance, then quit.
      // NOTE: at least one full iteration forced
      //       here because sometimes the initial
      //       residual on fine mesh is too small.
      if(res_l2_norm < NEWTON_TOL && it > 1) break;

      // Multiply the residual vector with -1 since the matrix 
      // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n).
      for(int i=0; i<ndof; i++) rhs->set(i, -rhs->get(i));

      // Solve the linear system.
      if(!solver->solve())
        error ("Matrix solver failed.\n");

      // Add \deltaY^{n+1} to Y^n.
      for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i];

      // If the maximum number of iteration has been reached, then quit.
      if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge.");
      
      // Copy coefficients from vector y to elements.
      set_coeff_vector(coeff_vec, space);

      it++;
    }
    
    // Cleanup.
    delete matrix;
    delete rhs;
    delete solver;
	  delete [] coeff_vec;
    
    // Update the eigenvalue.
    K_EFF_old = K_EFF;
    K_EFF = calc_fission_yield(space);		
    info("K_EFF_%d = %f", i, K_EFF);
		
    if (fabs(K_EFF - K_EFF_old)/K_EFF < TOL_SI) break;
  }
	
  // Plot the critical (i.e. steady-state) neutron flux.
  Linearizer l(space);
  l.plot_solution("solution.gp");
  
  // Normalize so that the absolute neutron flux generates 320 Watts of energy
  // (note that, using the symmetry condition at the origin, we've solved for  
  // flux only in the right half of the reactor).
  normalize_to_power(space, 320/2.);	

  // Plot the solution and space.
  l.plot_solution("solution_320W.gp");	
  space->plot("space.gp");

  info("K_EFF = %f", K_EFF);

  info("Done.");
  return 0;
}
Esempio n. 11
0
  ExecStatus
  timetabling(Space& home, Propagator& p, TaskArray<Task>& t) {
    Region r(home);

    bool assigned;
    if (Event* e = Event::events(r,t,assigned)) {
      // Whether resource is free
      bool free = true;
      // Set of current but not required tasks
      Support::BitSet<Region> tasks(r,static_cast<unsigned int>(t.size()));

      // Process events
      do {
        // Current time
        int time = e->time();

        // Process events for completion of required part
        for ( ; (e->type() == Event::LRT) && (e->time() == time); e++)
          if (t[e->idx()].mandatory()) {
            tasks.set(static_cast<unsigned int>(e->idx()));
            free = true;
          }

        // Process events for completion of task
        for ( ; (e->type() == Event::LCT) && (e->time() == time); e++)
          tasks.clear(static_cast<unsigned int>(e->idx()));

        // Process events for start of task
        for ( ; (e->type() == Event::EST) && (e->time() == time); e++)
          tasks.set(static_cast<unsigned int>(e->idx()));

        // Process events for zero-length task
        for ( ; (e->type() == Event::ZRO) && (e->time() == time); e++)
          if (!free)
            return ES_FAILED;

        // Norun start time
        int nrstime = time;
        // Process events for start of required part
        for ( ; (e->type() == Event::ERT) && (e->time() == time); e++)
          if (t[e->idx()].mandatory()) {
            tasks.clear(static_cast<unsigned int>(e->idx()));
            if (!free)
              return ES_FAILED;
            free = false;
            nrstime = time+1;
          } else if (t[e->idx()].optional() && !free) {
            GECODE_ME_CHECK(t[e->idx()].excluded(home));
          }

        if (!free)
          for (Iter::Values::BitSet<Support::BitSet<Region> > j(tasks);
               j(); ++j)
            // Task j cannot run from time to next time - 1
            if (t[j.val()].mandatory())
              GECODE_ME_CHECK(t[j.val()].norun(home, nrstime, e->time() - 1));

      } while (e->type() != Event::END);
    }

    if (assigned)
      return home.ES_SUBSUMED(p);

    return ES_NOFIX;
  }
Esempio n. 12
0
//-------------------------------------------------------------------------------------
PyObject* Space::__py_DelSpaceData(PyObject* self, PyObject* args)
{
	SPACE_ID spaceID = 0;

	if(PyTuple_Size(args) != 2)
	{
		PyErr_Format(PyExc_AssertionError, "KBEngine::delSpaceData: (argssize != (spaceID, key)) is error!");
		PyErr_PrintEx(0);
		return 0;
	}
	
	char* key = NULL;
	if(PyArg_ParseTuple(args, "Is", &spaceID, &key) == -1)
	{
		PyErr_Format(PyExc_AssertionError, "KBEngine::delSpaceData: args is error!");
		PyErr_PrintEx(0);
		return 0;
	}

	if(key == NULL)
	{
		PyErr_Format(PyExc_AssertionError, "KBEngine::delSpaceData: key not is string!");
		PyErr_PrintEx(0);
		return 0;
	}

	if(strlen(key) == 0)
	{
		PyErr_Format(PyExc_AssertionError, "KBEngine::delSpaceData: key is empty!");
		PyErr_PrintEx(0);
		return 0;
	}

	Space* space = Spaces::findSpace(spaceID);
	if(space == NULL)
	{
		PyErr_Format(PyExc_AssertionError, "KBEngine::delSpaceData: (spaceID=%u) not found!", 
			spaceID);

		PyErr_PrintEx(0);
		return 0;
	}

	if(!space->hasSpaceData(key))
	{
		PyErr_Format(PyExc_AssertionError, "KBEngine::delSpaceData: (spaceID=%u, key=%s) not found!", 
			spaceID, key);

		PyErr_PrintEx(0);
		return 0;
	}
	
	if(kbe_stricmp(key, "_mapping") == 0)
	{
		PyErr_Format(PyExc_AssertionError, "KBEngine::delSpaceData: key{_mapping} is protected!", 
			spaceID);

		PyErr_PrintEx(0);
		return 0;
	}

	space->delSpaceData(key);
	S_Return;
}
Esempio n. 13
0
  ExecStatus
  ReSubset<View0,View1,rm>::propagate(Space& home, const ModEventDelta&) {
    if (b.one()) {
      if (rm == RM_PMI)
        return home.ES_SUBSUMED(*this);
      GECODE_REWRITE(*this,(Subset<View0,View1>::post(home(*this),x0,x1)));
    }
    if (b.zero()) {
      if (rm == RM_IMP)
        return home.ES_SUBSUMED(*this);        
      GECODE_REWRITE(*this,(NoSubset<View0,View1>::post(home(*this),x0,x1)));
    }

    // check whether cardinalities still allow subset
    if (x0.cardMin() > x1.cardMax()) {
      if (rm != RM_PMI)
        GECODE_ME_CHECK(b.zero_none(home));
      return home.ES_SUBSUMED(*this);
    }

    // check lub(x0) subset glb(x1)
    {
      LubRanges<View0> x0ub(x0);
      GlbRanges<View1> x1lb(x1);
      Iter::Ranges::Diff<LubRanges<View0>,GlbRanges<View1> > d(x0ub,x1lb);
      if (!d()) {
        if (rm != RM_IMP)
          GECODE_ME_CHECK(b.one_none(home));
        return home.ES_SUBSUMED(*this);
      }
    }

    // check glb(x0) subset lub(x1)
    {
      GlbRanges<View0> x0lb(x0);
      LubRanges<View1> x1ub(x1);
      Iter::Ranges::Diff<GlbRanges<View0>,LubRanges<View1> > d(x0lb,x1ub);
      if (d()) {
        if (rm != RM_PMI)
          GECODE_ME_CHECK(b.zero_none(home));
        return home.ES_SUBSUMED(*this);
      } else if (x0.assigned() && x1.assigned()) {
        if (rm != RM_IMP)
          GECODE_ME_CHECK(b.one_none(home));
        return home.ES_SUBSUMED(*this);
      }
    }

    if (x0.cardMin() > 0) {
      LubRanges<View0> x0ub(x0);
      LubRanges<View1> x1ub(x1);
      Iter::Ranges::Inter<LubRanges<View0>,LubRanges<View1> >
        i(x0ub,x1ub);
      if (!i()) {
        if (rm != RM_PMI)
          GECODE_ME_CHECK(b.zero_none(home));
        return home.ES_SUBSUMED(*this);
      }
    }

    return ES_FIX;
  }
Esempio n. 14
0
bool CreateDesertSpace(Space &sp, Element &e, UdmDesertMap &des_map, DesertUdmMap &inv_des_map, UdmElementSet &elements, bool root)
{
	static long parent;			//id of the parent element
	long old_parent;			//save old parent
	static long space;			//id of the space
	short decomposition;		//0:leaf, 1: and, 2: or
	//element.decomposition():	
	//			has no children: leaf
	//			has children and decomposition is false:	or node
	//			has children and decomposition is true:		and node

	set<Element> ev_set;

	//static and non-static variables
	//for progress indication 
	//(this is weird in case of a recursive function)
	//CDesertStatusDlg * st_dlg = GetStatusDlg(NULL);
	static short percent_done;
	static short percent_to_do;
	short percent_to_do_save;
	if (root) 
	{
		percent_done = 0;
		percent_to_do = 100;
	}

	
	if (root)
	{
		
		//compute decomposition value
		//mapping from boolean decomposition value
		//to desert style short decomposition
		set<Element> e_children = sp.Element_kind_children();
		set<Element>::iterator i;
		
		if (e_children.empty()) decomposition = 0;
		else
		{
			if (sp.decomposition()) decomposition  = 1;
			else decomposition = 2;
		}

		//debug trace
		TRACE ("CreateDesertSpace invoked: parent: %d, Space: %s , decomposition: %d\n", parent, ((string)sp.name()).c_str(), decomposition);

		//
		//create the space & the root element in the space
		//
		space =  CreateSpace(((string)sp.name()).c_str());
		//space =  CreateSpace(((string)sp.name()).c_str(), sp.id(), sp.externalID());
		
/*
		parent = CreateElement(
			((string)sp.name()).c_str(), 
			space, 
			decomposition, 
			-1, 
			sp.id(),
			sp.externalID());
*/
				
		parent = CreateElement(
			((string)sp.name()).c_str(), 
			space, 
			decomposition, 
			-1, 
			sp.externalID());

		//map the UDM, desert object pairs
		
		DoMap(sp, des_map, inv_des_map, parent);

		
		//recursion here
		
		//update progress bar
		if (e_children.empty())
		{
			//leaf node
			percent_done += percent_to_do;
			//st_dlg->StepInState(percent_done);
		}//eo if (e_children.empty())

		else
		{

			//recursive hack for overall performance
			//percent to done is always smaller
			int no_of_children = e_children.size();
			percent_to_do_save = percent_to_do;
			percent_to_do = (short)((float)percent_to_do / (float)no_of_children);
				

			//recursive step
			for (i = e_children.begin(); i != e_children.end(); i++)
			{
				Element new_e = *i;
				CreateDesertSpace(sp, new_e, des_map, inv_des_map, elements, false);
			};//eo for (i...)

			//still part of the recursive hack
			//set back the percent_to_do when a recursive loop is done

			percent_to_do = percent_to_do_save;
		}//eo else if (e_children.begin() == e_children.end() )
		
	}//eo if (root)
	else
	{
		
		//compute decomposition value
		//mapping boolean decomposition value
		//to desert style decomposition value
		set<Element> e_children = e.Element_kind_children();
		set<Element>::iterator i;
		
		if (e_children.empty()) decomposition = 0;
		else
		{
			if (e.decomposition()) decomposition  = 1;
			else decomposition = 2;
		}

		//debug trace
		TRACE ("CreateDesertSpace invoked: parent: %d, Element: %s \n", parent, ((string)e.name()).c_str());

		//create new elenent
		long new_parent = CreateElement(
			((string)e.name()).c_str(),
			space,
			decomposition,
			parent,
			e.externalID());

	/*	long new_parent = CreateElement(
			((string)e.name()).c_str(),
			space,
			decomposition,
			parent,
			e.id(),
			e.externalID());*/

		//insert association in the map
		DoMap(e, des_map, inv_des_map, new_parent);
		//2nd set of elements, we need when mapping associations
		elements.insert(e);

		
		//recursion here
		
		if (e_children.empty() )
		{
			//leaf node
			percent_done += percent_to_do;
			//st_dlg->StepInState(percent_done);
		}//eo if (e_children.empty())
		else
		{

			//recursive hack for overall performance
			//percent to done is always smaller
			int no_of_children = e_children.size();
			percent_to_do_save = percent_to_do;
			percent_to_do = (short)((float)percent_to_do / (float)no_of_children);

			//saving old parent and setting the new parent for Create() calls 
			//when invoking myself recursively
			old_parent = parent;
			parent = new_parent;

			//check recursively all the children
		
			for (i = e_children.begin(); i != e_children.end(); i++)
			{
				Element new_e = *i;
				CreateDesertSpace(sp, new_e, des_map, inv_des_map, elements, false);
			};//eo for (i...)
			//recursive & static hack
			//setting back parent&percent_to_do

			parent = old_parent;
			percent_to_do = percent_to_do_save;

		}//eo else if (e_children.empty())
		
		
	}//eo else if (root) 
	return true;
};
Esempio n. 15
0
  ExecStatus
  QEqv<BVA,BVB,BVC>::propagate(Space& home, const ModEventDelta&) {
#define GECODE_INT_STATUS(S0,S1,S2) \
  ((BVA::S0<<(2*BVA::BITS))|(BVB::S1<<(1*BVB::BITS))|(BVC::S2<<(0*BVC::BITS)))
    switch ((x0.status() << (2*BVA::BITS)) | (x1.status() << (1*BVB::BITS)) |
            (x2.status() << (0*BVC::BITS))) {
    case GECODE_INT_STATUS(NONE,NONE,NONE):
      GECODE_NEVER;
    case GECODE_INT_STATUS(NONE,NONE,ZERO):
    case GECODE_INT_STATUS(NONE,NONE,ONE):
      return ES_FIX;
    case GECODE_INT_STATUS(NONE,ZERO,NONE):
      if (q0 == FORALL) 
      {
        GECODE_ME_CHECK(x2.zero_none(home)); break;
      }
      return ES_FIX;
    case GECODE_INT_STATUS(NONE,ZERO,ZERO):
      if (q0 == FORALL) return ES_FAILED;
      GECODE_ME_CHECK(x0.one_none(home)); break;
    case GECODE_INT_STATUS(NONE,ZERO,ONE):
      if (q0 == FORALL) return ES_FAILED;
      GECODE_ME_CHECK(x0.zero_none(home)); break;
    case GECODE_INT_STATUS(NONE,ONE,NONE):
      if (q0 == FORALL) 
      {
        GECODE_ME_CHECK(x2.zero_none(home)); break;
      }
      return ES_FIX;
    case GECODE_INT_STATUS(NONE,ONE,ZERO):
      if (q0 == FORALL) return ES_FAILED;
      GECODE_ME_CHECK(x0.zero_none(home)); break;
    case GECODE_INT_STATUS(NONE,ONE,ONE):
      if (q0 == FORALL) return ES_FAILED;
      GECODE_ME_CHECK(x0.one_none(home)); break;
    case GECODE_INT_STATUS(ZERO,NONE,NONE):
      if (q1 == FORALL) 
      {
        GECODE_ME_CHECK(x2.zero_none(home)); break;
      }
      return ES_FIX;
    case GECODE_INT_STATUS(ZERO,NONE,ZERO):
      if (q1 == FORALL) return ES_FAILED;
      GECODE_ME_CHECK(x1.one_none(home)); break;
    case GECODE_INT_STATUS(ZERO,NONE,ONE):
      if (q1 == FORALL) return ES_FAILED;
      GECODE_ME_CHECK(x1.zero_none(home)); break;
    case GECODE_INT_STATUS(ZERO,ZERO,NONE):
      GECODE_ME_CHECK(x2.one_none(home)); break;
    case GECODE_INT_STATUS(ZERO,ZERO,ZERO):
      return ES_FAILED;
    case GECODE_INT_STATUS(ZERO,ZERO,ONE):
      break;
    case GECODE_INT_STATUS(ZERO,ONE,NONE):
      GECODE_ME_CHECK(x2.zero_none(home)); break;
    case GECODE_INT_STATUS(ZERO,ONE,ZERO):
      break;
    case GECODE_INT_STATUS(ZERO,ONE,ONE):
      return ES_FAILED;
    case GECODE_INT_STATUS(ONE,NONE,NONE):
      if (q1 == FORALL) 
      {
        GECODE_ME_CHECK(x2.zero_none(home)); break;
      }
      return ES_FIX;
    case GECODE_INT_STATUS(ONE,NONE,ZERO):
      if (q1 == FORALL) return ES_FAILED;
      GECODE_ME_CHECK(x1.zero_none(home)); break;
    case GECODE_INT_STATUS(ONE,NONE,ONE):
      if (q1 == FORALL) return ES_FAILED;
      GECODE_ME_CHECK(x1.one_none(home)); break;
    case GECODE_INT_STATUS(ONE,ZERO,NONE):
      GECODE_ME_CHECK(x2.zero_none(home)); break;
    case GECODE_INT_STATUS(ONE,ZERO,ZERO):
      break;
    case GECODE_INT_STATUS(ONE,ZERO,ONE):
      return ES_FAILED;
    case GECODE_INT_STATUS(ONE,ONE,NONE):
      GECODE_ME_CHECK(x2.one_none(home)); break;
    case GECODE_INT_STATUS(ONE,ONE,ZERO):
      return ES_FAILED;
    case GECODE_INT_STATUS(ONE,ONE,ONE):
      break;
    default:
      GECODE_NEVER;
    }
    return home.ES_SUBSUMED(*this);
#undef GECODE_INT_STATUS
  }
Esempio n. 16
0
int main() 
{
  // Time measurement.
  TimePeriod cpu_time;
  cpu_time.tick();

  // Create coarse mesh, set Dirichlet BC, enumerate basis functions.
  Space* space = new Space(A, B, NELEM, DIR_BC_LEFT, DIR_BC_RIGHT, P_INIT, NEQ);

  // Enumerate basis functions, info for user.
  int ndof = Space::get_num_dofs(space);
  info("ndof: %d", ndof);

  // Initialize the weak formulation.
  WeakForm wf;
  wf.add_matrix_form(jacobian);
  wf.add_vector_form(residual);

  // Initialize the FE problem.
  bool is_linear = false;
  DiscreteProblem *dp_coarse = new DiscreteProblem(&wf, space, is_linear);
  if(JFNK == 0)
  {
    // Newton's loop on coarse mesh.
    // Fill vector coeff_vec using dof and coeffs arrays in elements.
    double *coeff_vec_coarse = new double[Space::get_num_dofs(space)];
    get_coeff_vector(space, coeff_vec_coarse);

    // Set up the solver, matrix, and rhs according to the solver selection.
    SparseMatrix* matrix_coarse = create_matrix(matrix_solver);
    Vector* rhs_coarse = create_vector(matrix_solver);
    Solver* solver_coarse = create_linear_solver(matrix_solver, matrix_coarse, rhs_coarse);

    int it = 1;
    while (1) 
    {
      // Obtain the number of degrees of freedom.
      int ndof_coarse = Space::get_num_dofs(space);

      // Assemble the Jacobian matrix and residual vector.
      dp_coarse->assemble(coeff_vec_coarse, matrix_coarse, rhs_coarse);

      // Calculate the l2-norm of residual vector.
      double res_l2_norm = get_l2_norm(rhs_coarse);

      // Info for user.
      info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(space), res_l2_norm);

      // If l2 norm of the residual vector is within tolerance, then quit.
      // NOTE: at least one full iteration forced
      //       here because sometimes the initial
      //       residual on fine mesh is too small.
      if(res_l2_norm < NEWTON_TOL_COARSE && it > 1) break;

      // Multiply the residual vector with -1 since the matrix 
      // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n).
      for(int i = 0; i < ndof_coarse; i++) rhs_coarse->set(i, -rhs_coarse->get(i));

      // Solve the linear system.
      if(!solver_coarse->solve())
        error ("Matrix solver failed.\n");

      // Add \deltaY^{n+1} to Y^n.
      for (int i = 0; i < ndof_coarse; i++) coeff_vec_coarse[i] += solver_coarse->get_solution()[i];

      // If the maximum number of iteration has been reached, then quit.
      if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge.");
      
      // Copy coefficients from vector y to elements.
      set_coeff_vector(coeff_vec_coarse, space);
      
      it++;
    }
    
    // Cleanup.
    delete matrix_coarse;
    delete rhs_coarse;
    delete solver_coarse;
    delete [] coeff_vec_coarse;
  }
  else
    jfnk_cg(dp_coarse, space, MATRIX_SOLVER_TOL, MATRIX_SOLVER_MAXITER,
            JFNK_EPSILON, NEWTON_TOL_COARSE, NEWTON_MAX_ITER, matrix_solver);

  // Cleanup.
  delete dp_coarse;

  // DOF and CPU convergence graphs.
  SimpleGraph graph_dof_est, graph_cpu_est;
  SimpleGraph graph_dof_exact, graph_cpu_exact;

  // Adaptivity loop:
  int as = 1;
  double ftr_errors[MAX_ELEM_NUM];        // This array decides what 
                                          // elements will be refined.

  bool done = false;
  do
  {
    info("---- Adaptivity step %d:", as); 

    // Construct globally refined reference mesh and setup reference space.
    Space* ref_space = construct_refined_space(space);
 
    // Initialize the FE problem. 
    bool is_linear = false;
    DiscreteProblem* dp = new DiscreteProblem(&wf, ref_space, is_linear);
      
    if(JFNK == 0)
    {
      // Set up the solver, matrix, and rhs according to the solver selection.
      SparseMatrix* matrix = create_matrix(matrix_solver);
      Vector* rhs = create_vector(matrix_solver);
      Solver* solver = create_linear_solver(matrix_solver, matrix, rhs);
      
      // Newton's loop on the fine mesh.
      info("Solving on fine mesh:");
      // Fill vector coeff_vec using dof and coeffs arrays in elements.
      double *coeff_vec = new double[Space::get_num_dofs(ref_space)];
      get_coeff_vector(ref_space, coeff_vec);

        int it = 1;
        while (1) 
        {
          // Obtain the number of degrees of freedom.
          int ndof = Space::get_num_dofs(ref_space);

          // Assemble the Jacobian matrix and residual vector.
          dp->assemble(coeff_vec, matrix, rhs);

          // Calculate the l2-norm of residual vector.
          double res_l2_norm = get_l2_norm(rhs);

          // Info for user.
          info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(ref_space), res_l2_norm);

          // If l2 norm of the residual vector is within tolerance, then quit.
          // NOTE: at least one full iteration forced
          //       here because sometimes the initial
          //       residual on fine mesh is too small.
          if(res_l2_norm < NEWTON_TOL_REF && it > 1) break;

          // Multiply the residual vector with -1 since the matrix 
          // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n). 
          for(int i = 0; i < ndof; i++) rhs->set(i, -rhs->get(i));

          // Solve the linear system.
          if(!solver->solve())
            error ("Matrix solver failed.\n");

          // Add \deltaY^{n+1} to Y^n.
          for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i];

          // If the maximum number of iteration has been reached, then quit.
          if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge.");
        
          // Copy coefficients from vector y to elements.
          set_coeff_vector(coeff_vec, ref_space);

          it++;
      }
      // Cleanup.
      delete matrix;
      delete rhs;
      delete solver;
      delete [] coeff_vec;
    }
    else
      jfnk_cg(dp, ref_space, MATRIX_SOLVER_TOL, MATRIX_SOLVER_MAXITER,
              JFNK_EPSILON, NEWTON_TOL_COARSE, NEWTON_MAX_ITER, matrix_solver);
 
    // Cleanup.
    delete dp;
    
    // Starting with second adaptivity step, obtain new coarse 
    // mesh solution via projecting the fine mesh solution.
    if(as > 1)
    {
      info("Projecting the fine mesh solution onto the coarse mesh.");
      // Project the fine mesh solution (defined on space_ref) onto the coarse mesh (defined on space).
      OGProjection::project_global(space, ref_space, matrix_solver);
    }

    double max_qoi_err_est = 0;
    for (int i=0; i < space->get_n_active_elem(); i++)
    {
      if (GOAL_ORIENTED == 1) 
      {
        // Use quantity of interest.
        double qoi_est = quantity_of_interest(space, X_QOI);
        double qoi_ref_est = quantity_of_interest(ref_space, X_QOI);
        ftr_errors[i] = fabs(qoi_ref_est - qoi_est);
      }
      else 
      {
        // Use global norm
        double err_est_array[MAX_ELEM_NUM];
        ftr_errors[i] = calc_err_est(NORM, space, ref_space, err_est_array);
      }
      // Info for user.
      info("Elem [%d]: absolute error (est) = %g%%", i, ftr_errors[i]);

      // Time measurement.
      cpu_time.tick();

      // Calculating maximum of QOI FTR error for plotting purposes
      if (GOAL_ORIENTED == 1) 
      {
        if (ftr_errors[i] > max_qoi_err_est)
          max_qoi_err_est = ftr_errors[i];
      }
      else 
      {
        double qoi_est = quantity_of_interest(space, X_QOI);
        double qoi_ref_est = quantity_of_interest(ref_space, X_QOI);
        double err_est = fabs(qoi_ref_est - qoi_est);
        if (err_est > max_qoi_err_est)
          max_qoi_err_est = err_est;
      }
    }

    // Add entries to convergence graphs.
    if (EXACT_SOL_PROVIDED) 
    {
      double qoi_est = quantity_of_interest(space, X_QOI);
      double u[MAX_EQN_NUM], dudx[MAX_EQN_NUM];
      exact_sol(X_QOI, u, dudx);
      double err_qoi_exact = fabs(u[0] - qoi_est);
      // Info for user.
      info("Relative error (exact) = %g %%", err_qoi_exact);
      // Add entry to DOF and CPU convergence graphs.
      graph_dof_exact.add_values(Space::get_num_dofs(space), err_qoi_exact);
      graph_cpu_exact.add_values(cpu_time.accumulated(), err_qoi_exact);
    }
    
    // Add entry to DOF and CPU convergence graphs.
    graph_dof_est.add_values(Space::get_num_dofs(space), max_qoi_err_est);
    graph_cpu_est.add_values(cpu_time.accumulated(), max_qoi_err_est);

    // Decide whether the max. FTR error in the quantity of interest 
    // is sufficiently small.
    if(max_qoi_err_est < TOL_ERR_QOI) break;

    // Returns updated coarse and fine meshes, with the last 
    // coarse and fine mesh solutions on them, respectively. 
    // The coefficient vectors and numbers of degrees of freedom 
    // on both meshes are also updated. 
    adapt(NORM, ADAPT_TYPE, THRESHOLD, ftr_errors, space, ref_space);

    as++;

    // Plot meshes, results, and errors.
    adapt_plotting(space, ref_space, NORM, EXACT_SOL_PROVIDED, exact_sol);

    // Cleanup.
    delete ref_space;
  }
  while (done == false);

  info("Total running time: %g s", cpu_time.accumulated());

  // Save convergence graphs.
  graph_dof_est.save("conv_dof_est.dat");
  graph_cpu_est.save("conv_cpu_est.dat");
  graph_dof_exact.save("conv_dof_exact.dat");
  graph_cpu_exact.save("conv_cpu_exact.dat");

  // Test variable.
  bool success = true;
  info("ndof = %d.", Space::get_num_dofs(space));
  if (Space::get_num_dofs(space) > 150) success = false;

  if (success)
  {
    info("Success!");
    return ERROR_SUCCESS;
  }
  else
  {
    info("Failure!");
    return ERROR_FAILURE;
  }
}
Esempio n. 17
0
int main() {
    // Time measurement.
    TimePeriod cpu_time;
    cpu_time.tick();

    // Create coarse mesh, set Dirichlet BC, enumerate basis functions.
    Space* space = new Space(A, B, NELEM, DIR_BC_LEFT, DIR_BC_RIGHT, P_INIT, NEQ, NEQ);

    // Enumerate basis functions, info for user.
    int ndof = Space::get_num_dofs(space);
    info("ndof: %d", ndof);

    // Initialize the weak formulation.
    WeakForm wf;
    wf.add_matrix_form(jacobian);
    wf.add_vector_form(residual);

    // Initialize the FE problem.
    bool is_linear = false;
    DiscreteProblem *dp_coarse = new DiscreteProblem(&wf, space, is_linear);

    // Newton's loop on coarse mesh.
    // Fill vector coeff_vec using dof and coeffs arrays in elements.
    double *coeff_vec_coarse = new double[Space::get_num_dofs(space)];
    get_coeff_vector(space, coeff_vec_coarse);

    // Set up the solver, matrix, and rhs according to the solver selection.
    SparseMatrix* matrix_coarse = create_matrix(matrix_solver);
    Vector* rhs_coarse = create_vector(matrix_solver);
    Solver* solver_coarse = create_linear_solver(matrix_solver, matrix_coarse, rhs_coarse);

    int it = 1;
    while (1)
    {
        // Obtain the number of degrees of freedom.
        int ndof_coarse = Space::get_num_dofs(space);

        // Assemble the Jacobian matrix and residual vector.
        dp_coarse->assemble(coeff_vec_coarse, matrix_coarse, rhs_coarse);

        // Calculate the l2-norm of residual vector.
        double res_l2_norm = get_l2_norm(rhs_coarse);

        // Info for user.
        info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(space), res_l2_norm);

        // If l2 norm of the residual vector is within tolerance, then quit.
        // NOTE: at least one full iteration forced
        //       here because sometimes the initial
        //       residual on fine mesh is too small.
        if(res_l2_norm < NEWTON_TOL_COARSE && it > 1) break;

        // Multiply the residual vector with -1 since the matrix
        // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n).
        for(int i=0; i<ndof_coarse; i++) rhs_coarse->set(i, -rhs_coarse->get(i));

        // Solve the linear system.
        if(!solver_coarse->solve())
            error ("Matrix solver failed.\n");

        // Add \deltaY^{n+1} to Y^n.
        for (int i = 0; i < ndof_coarse; i++) coeff_vec_coarse[i] += solver_coarse->get_solution()[i];

        // If the maximum number of iteration has been reached, then quit.
        if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge.");

        // Copy coefficients from vector y to elements.
        set_coeff_vector(coeff_vec_coarse, space);

        it++;
    }

    // Cleanup.
    delete matrix_coarse;
    delete rhs_coarse;
    delete solver_coarse;
    delete [] coeff_vec_coarse;
    delete dp_coarse;

    // DOF and CPU convergence graphs.
    SimpleGraph graph_dof_est, graph_cpu_est;
    SimpleGraph graph_dof_exact, graph_cpu_exact;

    // Test variable.
    int success_test = 1;

    // Adaptivity loop:
    int as = 1;
    bool done = false;
    do
    {
        info("---- Adaptivity step %d:", as);

        // Construct globally refined reference mesh and setup reference space.
        Space* ref_space = construct_refined_space(space);

        // Initialize the FE problem.
        bool is_linear = false;
        DiscreteProblem* dp = new DiscreteProblem(&wf, ref_space, is_linear);

        // Set up the solver, matrix, and rhs according to the solver selection.
        SparseMatrix* matrix = create_matrix(matrix_solver);
        Vector* rhs = create_vector(matrix_solver);
        Solver* solver = create_linear_solver(matrix_solver, matrix, rhs);

        // Newton's loop on the fine mesh.
        info("Solving on fine mesh:");
        // Fill vector coeff_vec using dof and coeffs arrays in elements.
        double *coeff_vec = new double[Space::get_num_dofs(ref_space)];
        get_coeff_vector(ref_space, coeff_vec);

        int it = 1;
        while (1)
        {
            // Obtain the number of degrees of freedom.
            int ndof = Space::get_num_dofs(ref_space);

            // Assemble the Jacobian matrix and residual vector.
            dp->assemble(coeff_vec, matrix, rhs);

            // Calculate the l2-norm of residual vector.
            double res_l2_norm = get_l2_norm(rhs);

            // Info for user.
            info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(ref_space), res_l2_norm);

            // If l2 norm of the residual vector is within tolerance, then quit.
            // NOTE: at least one full iteration forced
            //       here because sometimes the initial
            //       residual on fine mesh is too small.
            if(res_l2_norm < NEWTON_TOL_REF && it > 1) break;

            // Multiply the residual vector with -1 since the matrix
            // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n).
            for(int i=0; i<ndof; i++) rhs->set(i, -rhs->get(i));

            // Solve the linear system.
            if(!solver->solve())
                error ("Matrix solver failed.\n");

            // Add \deltaY^{n+1} to Y^n.
            for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i];

            // If the maximum number of iteration has been reached, then quit.
            if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge.");

            // Copy coefficients from vector y to elements.
            set_coeff_vector(coeff_vec, ref_space);

            it++;
        }

        // Starting with second adaptivity step, obtain new coarse
        // mesh solution via projecting the fine mesh solution.
        if(as > 1)
        {
            info("Projecting the fine mesh solution onto the coarse mesh.");
            // Project the fine mesh solution (defined on space_ref) onto the coarse mesh (defined on space).
            OGProjection::project_global(space, ref_space, matrix_solver);
        }

        // Calculate element errors and total error estimate.
        info("Calculating error estimate.");
        double err_est_array[MAX_ELEM_NUM];
        double err_est_rel = calc_err_est(NORM, space, ref_space, err_est_array) * 100;

        // Report results.
        info("ndof_coarse: %d, ndof_fine: %d, err_est_rel: %g%%",
             Space::get_num_dofs(space), Space::get_num_dofs(ref_space), err_est_rel);

        // Time measurement.
        cpu_time.tick();

        // If exact solution available, also calculate exact error.
        if (EXACT_SOL_PROVIDED)
        {
            // Calculate element errors wrt. exact solution.
            double err_exact_rel = calc_err_exact(NORM, space, exact_sol, NEQ, A, B) * 100;

            // Info for user.
            info("Relative error (exact) = %g %%", err_exact_rel);

            // Add entry to DOF and CPU convergence graphs.
            graph_dof_exact.add_values(Space::get_num_dofs(space), err_exact_rel);
            graph_cpu_exact.add_values(cpu_time.accumulated(), err_exact_rel);
            if (as == 2)
                if (err_exact_rel > 1e-10) success_test = 0;
        }

        // Add entry to DOF and CPU convergence graphs.
        graph_dof_est.add_values(Space::get_num_dofs(space), err_est_rel);
        graph_cpu_est.add_values(cpu_time.accumulated(), err_est_rel);

        // Decide whether the relative error is sufficiently small.
        if(err_est_rel < TOL_ERR_REL) done = true;

        // Extra code for this test.
        if (as == 30)
        {
            if (err_est_rel > 1e-10) success_test = 0;
            if (space->get_n_active_elem() != 2) success_test = 0;
            Element *e = space->first_active_element();
            if (e->p != 2) success_test = 0;
            e = space->last_active_element();
            if (e->p != 2) success_test = 0;
            break;
        }

        // Returns updated coarse and fine meshes, with the last
        // coarse and fine mesh solutions on them, respectively.
        // The coefficient vectors and numbers of degrees of freedom
        // on both meshes are also updated.
        adapt(NORM, ADAPT_TYPE, THRESHOLD, err_est_array, space, ref_space);

        as++;

        // Plot meshes, results, and errors.
        adapt_plotting(space, ref_space, NORM, EXACT_SOL_PROVIDED, exact_sol);

        // Cleanup.
        delete solver;
        delete matrix;
        delete rhs;
        delete ref_space;
        delete dp;
        delete [] coeff_vec;

    }
    while (done == false);

    info("Total running time: %g s", cpu_time.accumulated());

    // Save convergence graphs.
    graph_dof_est.save("conv_dof_est.dat");
    graph_cpu_est.save("conv_cpu_est.dat");
    graph_dof_exact.save("conv_dof_exact.dat");
    graph_cpu_exact.save("conv_cpu_exact.dat");

    if (success_test)
    {
        info("Success!");
        return ERROR_SUCCESS;
    }
    else
    {
        info("Failure!");
        return ERROR_FAILURE;
    }
}
bool testFloatNbhoodReprMembership_datafiles()
{
    cout << "------------------------- ";
    cout << "testFloatNbhoodReprMembership_datafiles:" << endl;

    vector<string> files;
    files.push_back("01");
    files.push_back("02");
    files.push_back("03");
    files.push_back("04");
    files.push_back("06");
    files.push_back("07");
    files.push_back("08");
    files.push_back("09");
    files.push_back("10");
    files.push_back("11");
    files.push_back("12");
    files.push_back("13");
    files.push_back("14");
    files.push_back("15");
    files.push_back("16");
    files.push_back("17");
    files.push_back("18");
    files.push_back("19");
    files.push_back("20");
    files.push_back("21");
    files.push_back("22");

    for (size_t i = 0; i < files.size(); i ++) {
        string datafile, spacefile;
        datafile = "src/test/data/uint/grid_repr/" + files[i] + ".txt";
        spacefile = "src/test/data/uint/grid_repr/" + files[i] + "_space.txt";
        cout << datafile << ": " << endl;

        Space space = createSpaceFromSpacefile(spacefile, true);

        bool allOk = true;
        vector<vector<Coord> > wrongPnts;
        vector<bool> wrongColors;

        GridRepr gr(space);
        NbhoodRepr nr(space);

        /* Vytvoreni grid reprezentace z souboru */

        gr = GridRepr(space, datafile.c_str(), true);
        nr = gr;
        
        /* Testovani, zda pro vsechny body prostoru vraci color
        na nbhood reprezentaci stejnou hodnotu jako color na referencni
        grid reprezentaci */

        allOk = true;
        Space::Iterator it = space.createIterator(true);
        wrongPnts.clear();
        wrongColors.clear();
        while (!it.atEnd()) {

            bool nrCol = nr.color(*it);
            if (gr.color(*it) != nrCol) {
                allOk = false;
                wrongPnts.push_back(*it);
                wrongColors.push_back(nrCol);
            }
            if (nrCol) {
                // PRINT_POINT(*it)
            }
            ++ it;
        }
        if (!allOk) {
            cout << "----------------------------------------------------------" << endl;
            cout << "WRONG POINTS:" << endl;
            for (size_t i = 0; i < wrongPnts.size(); i ++) {
                PRINT_POINT(wrongPnts[i])
                cout << "wrong color: " << wrongColors[i] << endl;
            }
        }
        assert(allOk);
    }
    return true;
}
Esempio n. 19
0
 size_t
 ValueSequenceSymmetryImp<View>
 ::dispose(Space& home) {
   home.free(values, n_values);
   return sizeof(*this);
 }
Esempio n. 20
0
Space* Space::createSpace(FileHandle& pHandler,
                          size_t pStart, size_t pSize)
{
  Type type;
  void* memory;
  Space* result = NULL;
  size_t start, size = 0, total_offset;
  switch(type = policy(pStart, pSize)) {
    case ALLOCATED_ARRAY: {
      // adjust total_offset, start and size
      total_offset = pStart + pSize;
      start = pStart;
      if (total_offset > pHandler.size()) {
        if (pHandler.isWritable()) {
          size = pSize;
          pHandler.truncate(total_offset);
        }
        else if (pHandler.size() > start)
          size = pHandler.size() - start;
        else {
          // create a space out of a read-only file.
          fatal(diag::err_cannot_read_small_file) << pHandler.path()
                                                  << pHandler.size()
                                                  << start << size;
        }
      }
      else
        size = pSize;

      // malloc
      memory = (void*)malloc(size);
      if (!pHandler.read(memory, start, size))
        error(diag::err_cannot_read_file) << pHandler.path() << start << size;

      break;
    }
    case MMAPED: {
      // adjust total_offset, start and size
      total_offset = page_boundary(pStart + pSize);
      start = page_offset(pStart);
      if (total_offset > pHandler.size()) {
        if (pHandler.isWritable()) {
          size = page_boundary((pStart - start) + pSize);
          pHandler.truncate(total_offset);
        }
        else if (pHandler.size() > start)
          size = pHandler.size() - start;
        else {
          // create a space out of a read-only file.
          fatal(diag::err_cannot_read_small_file) << pHandler.path()
                                                  << pHandler.size()
                                                  << start << size;
        }
      }
      else
        size = page_boundary((pStart - start) + pSize);

      // mmap
      if (!pHandler.mmap(memory, start, size))
        error(diag::err_cannot_mmap_file) << pHandler.path() << start << size;

      break;
    }
    default:
      break;
  } // end of switch

  result = new Space(type, memory, size);
  result->setStart(start);
  return result;
}
Esempio n. 21
0
 ExecStatus
 Val<View>::propagate(Space& home, const ModEventDelta&) {
   GECODE_ES_CHECK((prop_val<View,true>(home,x)));
   return (x.size() < 2) ? home.ES_SUBSUMED(*this) : ES_FIX;
 }
Esempio n. 22
0
int main()
{
	srand((unsigned)time(NULL));		//initialize random number generator
	bool done = false;					//for game exit
	bool death = false;					//player death flag
	bool happyLeprechaun = false;		//Leprechaun mood flag
	int move = 0;						//move option
	Space* location = NULL;				//current location pointer
	int turnsRemaining = 30;			//counter for number of turns
	int hydration = 10;					//hydration "tank"
	bool flashlightOn = false;			//flashlight state
	int flashDeath = 0;					//counter for death by ghost in tower
	Object* backpack[4];				//pointer to backpack array
	for (int i = 0; i < 4; i++)
	{
		backpack[i] = NULL;				//set backpack object pointers to NULL
	}
	Object* currentObject = NULL;		//object currently being held by player

	//seed the world
	//create the spaces
	Space* ravine = new Ravine("Mossy ravine", "A narrow ravine with steep moss covered sides, a stream, and gently moving dense mist...", "You are in a ravine.", "You see a gently flowing stream, a dark wet cave to your left \nthat the stream comes out of, another cave behind you, \nand in front of you is a bridge to two stone stairways, \nboth leading up into the mist. \nAt the bridge there is a clear orb atop a marble obelisk,  \nand the following items:", "");
	Space* cave1 = new Cave("Wet Cave", "A pitch black, very wet cave with a stream flowing towards the entrance.", "You are in a very wet & dark cave.", "All you can see is dim light in the direction of the cave mouth and \na black orb atop a marble obelisk. \nYou will need a light source to see what else may be here.", "You can see the dim light in the direction of the cave mouth, \na giant menacing spider furter back in the cave, \na black orb atop a marble obelisk, and the following items:");
	Space* cave2 = new Cave("Dry Cave", "A pitch black cave", "You are in a dark cave.", "All you can see is dim light in the direction of the cave mouth and \na black orb atop a marble obelisk. \nYou will need a light source to see what else may be here.", "You can see the dim light in the direction of the cave mouth, \na giant menacing spider further back in the cave, \na black orb atop a marble obelisk, and the following items:");
	Space* tower1 = new Tower("Stone Tower", "A circular room with open windows at the top of a high stone tower.", "You are in a circular room at the top of a stone tower.", "You are in a dim circular room with windows at the top of a stone tower. \nIt is very misty outside. \nYou can see stairs going down, a white orb atop a marble obelisk, \na rope bridge leading into the mist, and the following items:", "");
	Space* treehouse1 = new Treehouse("Tree House", "A rustic, weathered tree house surrounded by mist.", "You are in a rustic, weathered tree house.", "You can see stairs going down, a bright green orb atop a wooden post, \na rope bridge leading into the mist, and the following items:", "");

	//set pointers of the spaces
	ravine->setPointers(cave1, cave2, tower1, treehouse1);
	cave1->setPointers(ravine, NULL, NULL, NULL);
	cave2->setPointers(ravine, NULL, NULL, NULL);
	tower1->setPointers(ravine, treehouse1, NULL, NULL);
	treehouse1->setPointers(ravine, tower1, NULL, NULL);

	//create objects
	Object* water1 = new Object(1, "Sealed water bottle");
	Object* water2 = new Object(1, "Sealed water bottle");
	Object* water3 = new Object(1, "Sealed water bottle");
	Object* water4 = new Object(2, "1/2 empty water bottle");
	Object* water5 = new Object(2, "1/2 empty water bottle");
	Object* orb = new Object(3, "Irish green glass orb.");
	Object* knife = new Object(4, "Hunting knife");
	Object* flashlight = new Object(5, "Flashlight");

	//place objects
	cave1->addObject(water1);	 //good water to wet cave
	cave1->addObject(knife);	 //knife to wet cave
	cave1->addObject(water5);	 //bad water to wet cave
	cave2->addObject(water2);	 //good water to dry cave
	cave2->addObject(orb);		 //green orb to dry cave
	cave2->addObject(water4);	 //bad water to dry cave
	tower1->addObject(flashlight); //flashlight to tower
	treehouse1->addObject(water3);	 //good water to treehouse

	//set start location
	location = ravine;

	//test spaces
	//cout << ravine->getName() << endl << ravine->getDescription() << endl << ravine->getEntryMessage() << endl << ravine->getLook1() << endl << ravine->getLook2() << endl;
	//cout << endl;
	//cout << cave1->getName() << endl << cave1->getDescription() << endl << cave1->getEntryMessage() << endl << cave1->getLook1() << endl << cave1->getLook2() << endl;
	//cout << endl;
	//cout << cave2->getName() << endl << cave2->getDescription() << endl << cave2->getEntryMessage() << endl << cave2->getLook1() << endl << cave2->getLook2() << endl;
	//cout << endl;
	//cout << tower1->getName() << endl << tower1->getDescription() << endl << tower1->getEntryMessage() << endl << tower1->getLook1() << endl << tower1->getLook2() << endl;
	//cout << endl;
	//cout << treehouse1->getName() << endl << treehouse1->getDescription() << endl << treehouse1->getEntryMessage() << endl << treehouse1->getLook1() << endl << treehouse1->getLook2() << endl;
	//cout << endl;

	//display instructions
	cout << endl;
	cout << endl;
	cout << "****************************************" << endl;
	cout << "Welcome to \"Make the Leprechaun Happy\" game" << endl;
	cout << endl;
	cout << "You will have 30 moves to find and please the Leprechaun. " << endl;
	cout << "Your current hydration level is 10. You loose one hydration level" << endl;
	cout << "every time you move or cancel a move." << endl;
	cout << "Drinking safe water adds 5 to your hydration level." << endl;
	cout << "This is important because if your hydration level reaches zero you die." << endl;
	cout << "You can only hold and use one item at a time, but you have a" << endl;
	cout << "backpack that holds up to three items." << endl;
	cout << "You can drop items wherever you are and they keep working..." << endl;
	cout << "Orbs exist in many places and you can touch them." << endl;
	cout << endl;
	cout << "Most importantly, if the Leprechaun doesn't laugh the world ends." << endl;
	cout << endl;
	cout << "Dangerous things exist here..." << endl;
	cout << endl;
	cout << "Please save the world!" << endl;
	cout << endl;
	cout << "HINT: " << endl;
	cout << "This puzzle / game can be solved in only 5 moves" << endl;
	cout << "and 5 \"actions\" (pick up, drop, use, touch)." << endl;
	cout << "Good luck..." << endl;
	cout << endl;
	cout << "Press enter to continue..." << endl;
	cin.get();
	cout << "You begin your journey in a cool and damp ravine." << endl;
	cout << "The steep walls are thickly covered in ferns and moss." << endl;
	cout << "A crystal clear stream gently flows by in front of you." << endl;
	cout << "Mist continually moves through the ravine creating a serene" << endl;
	cout << "feel, but visibility is limited... " << endl;
	cout << endl;
	cout << "Let the game begin..." << endl;
	

	while (done != true)
	{
		//death checks
		if (turnsRemaining < 1)
		{
			done = true;
			death = true;
		}
		else if (hydration < 1)
		{
			done = true;
			death = true;
		}
		//status update to user
		else cout << endl << "You have " << turnsRemaining << " turns left and your hydration level is " << hydration << "." << endl;
		cout << endl;
		if (hydration < 3 && hydration > 0) cout << "You are dangerously close to dying from dehydration..." << endl;
		cout << endl;
		if (!death)
		{
			cout << "Press enter to continue..." << endl;
			//cin.clear();
			//cin.ignore(256, '\n');
			cin.clear();
			//cin.get();
			cin.get();
			cout << endl;
			displayMenu();
			int menuChoice = 0;			//for menu/user inputs
			menuChoice = getInput();
			switch (menuChoice) {
			case 0:		//exit option
			{
				done = true;
				break;
			}
			case 1:		//look
			{
				if ((location == cave1 || location == cave2) && flashlightOn)
				{
					cout << endl << location->getLook2() << endl << endl;
					location->displayObjects();
				}
				else if ((location == cave1 || location == cave2) && !flashlightOn)
				{
					cout << endl << location->getLook1() << endl << endl;
				}
				else
				{
					//display location view
					cout << endl << location->getLook1() << endl << endl;
					//display objects present
					location->displayObjects();
				}
				cin.ignore(256, '\n');
				break;
			}
			case 2:		//move
			{
				move = location->move();
				switch (move)
				{
				case 1:
				{
					location = location->getPointer(1);
					cout << endl << location->getEntryMessage() << endl;
					turnsRemaining -= 1;
					hydration -= 1;
				}
				break;
				case 2:
				{
					location = location->getPointer(2);
					cout << endl << location->getEntryMessage() << endl;
					turnsRemaining -= 1;
					hydration -= 1;
				}
				break;
				case 3:
				{
					location = location->getPointer(3);
					cout << endl << location->getEntryMessage() << endl;
					turnsRemaining -= 1;
					hydration -= 1;
				}
				break;
				case 4:
				{
					location = location->getPointer(4);
					cout << endl << location->getEntryMessage() << endl;
					turnsRemaining -= 1;
					hydration -= 1;
				}
				break;
				case 5:
				{
					cout << endl << "You have not moved. You still lose hydration when you don't move." << endl;
					cout << endl << location->getEntryMessage() << endl;
					hydration -= 1;
				}
				break;
				case 9:
				{
					cout << endl << "You have been stung by a giant spider and are being packaged" << endl;
					cout << "for future enjoyment. Game over." << endl;
					cout << "Press enter to continue." << endl;
					death = true;
					done = true;
				}
				cin.ignore(256, '\n');
				break;
				} //end of move switch
			}
			break;
			case 3:		//use item
			{
				//test if object being held
				if (currentObject != NULL)
				{
					int id = currentObject->getId();
					switch (id)
					{
					case 1:		//sealed water bottle
					{
						cout << "You are holding a sealed water bottle." << endl;
						cout << "Do you want to drink it? (1 for Yes, 2 for No)" << endl;
						int choice = getInput();
						if (choice == 1)
						{
							hydration += 5;
							cout << "Your hydration level is now " << hydration << endl;
							currentObject->setId(6);
							currentObject->setName("Empty water bottle");
							cout << "FYI, you are holding an empty bottle." << endl;
						}
						else if (choice == 2)
						{
							cout << "OK, you did not drink the water. You are still holdling the bottle." << endl;
						}
						else cout << "Invalid response. Item has not been used." << endl << endl;
					}
					break;
					case 2:		//comprimised water bottle
					{
						cout << "You are holding a 1/2 full water bottle." << endl;
						cout << "Do you want to drink it? (1 for Yes, 2 for No)" << endl;
						int choice = getInput();
						if (choice == 1)
						{
							cout << "Bad choice...you are now dead." << endl;
							currentObject->setId(6);
							currentObject->setName("Empty water bottle");
							death = true;
							done = true;
						}
						else if (choice == 2)
						{
							cout << "OK, you did not drink the water. You are still holdling the bottle." << endl;
						}
						else cout << "Invalid response. Item has not been used." << endl << endl;
					}
					break;
					case 3:		//glass orb
					{
						cout << "You are holding a glass orb." << endl;
						cout << "Do you want to use it? (1 for Yes, 2 for No)" << endl;
						int choice = getInput();
						if (choice == 1)
						{
							if (location == tower1)
							{
								cout << "Congratulations you have completed the game." << endl;
								done = true;
							}
							else cout << "The orb doesn't seem to do anything here..." << endl;
						}
						else if (choice == 2)
						{
							cout << "OK, you are still holdling the orb." << endl;
						}
						else cout << "Invalid response. Orb has not been used." << endl << endl;
					}
					break;
					case 4:		//knife
					{
						cout << "You are holding a very sharp hunting knife." << endl;
						cout << "Do you want to use it? (1 for Yes, 2 for No)" << endl;
						int choice = getInput();
						if (choice == 1)
						{
							if (location == cave1 || location == cave2)
							{
								int choice;
								cout << "Enter 1 to kill yourself. This will save time..." << endl;
								cout << "Enter 2 to throw the kife towards the back of the cave." << endl;
								choice = getInput();
								if (choice == 1)
								{
									cout << "You are dead. Game over..." << endl;
									death = true;
									done = true;
								}
								else if (choice == 2) cout << "Congratulations, you have killed a giant spider." << endl;
								else cout << "Invalid choice nothing has been done, you are still holding the knife." << endl;
							}
							else
							{
								int choice;
								cout << "Enter 1 to kill yourself. This will save time..." << endl;
								cout << "Enter 2 to throw the kife." << endl;
								choice = getInput();
								if (choice == 1)
								{
									cout << "You are dead. Game over..." << endl;
									death = true;
									done = true;
								}
								else if (choice == 2)
								{
									cout << "Such bravado..." << endl;
									location->addObject(currentObject);
									currentObject = NULL;
								}
								else cout << "Invalid choice nothing has been done, you are still holding the knife." << endl;
							}
						}
						else if (choice == 2)
						{
							cout << "OK, you are still holdling the knife." << endl;
						}
						else cout << "Invalid response. Knife has not been used." << endl << endl;
					}
					break;
					case 5:		//flashlight
					{
						cout << "You are holding a flashlight." << endl;
						if (flashlightOn == true) cout << "It is already on...." << endl;
						if (location == tower1 && flashlightOn)
						{
							cout << "The tower ghost doesn't like flashlights." << endl;
							cout << "He turned it off." << endl;
							cout << "Press enter to continue..." << endl;
							//cin.clear();
							cin.ignore(256, '\n');
							cin.get();
							flashlightOn = false;
							flashDeath += 1;
							if (flashDeath >= 3)
							{
								cout << "You really pissed off the tower ghost. He pushed you out the" << endl;
								cout << "window to your death. Game over." << endl;
								death = true;
								done = true;
							}
						}
						cout << "Do you want the flashlight on or off? (1 for On, 2 for Off)" << endl;
						int choice = getInput();
						if (choice == 1)
						{
							flashlightOn = true;
							cout << "Flashlight on." << endl;
							if (location == cave1 || location == cave2)
							{
								cout << "You may want to have a look around..." << endl;
							}
							else if (location == tower1)
							{
								cout << "The tower ghost doesn't like flashlights." << endl;
								cout << "He turned it off and threw it out the window." << endl;
								cout << "Press enter to continue..." << endl;
								//cin.clear();
								//cin.ignore(256, '\n');
								cin.get();
								flashDeath += 1;
								flashlightOn = false;
								ravine->addObject(currentObject);
								currentObject = NULL;
								if (flashDeath >= 3)
								{
									cout << "You really pissed off the tower ghost. He pushed you out the" << endl;
									cout << "window to your death. Game over." << endl;
									death = true;
									done = true;
								}
							}
							else if (location == ravine)
							{
								cout << "A flashlight doesn't do much here..." << endl;
								cout << "Press enter to continue..." << endl;
								//cin.clear();
								//cin.ignore(256, '\n');
								cin.get();
							}
							else cout << "You might want to have a look around..." << endl;
						}
						else if (choice == 2)
						{
							cout << "Flashlight is off." << endl;
						}
						else cout << "Invalid response. No change to flashlight." << endl << endl;
					}
					break;
					case 6:
					{
						cout << "You are holding an empty water bottle." << endl;
						cout << "Not much you can do with that..." << endl;
					}
					break;
					default:
						cout << "Not a valid choice" << endl;
						break;
					}
				}
				else
				{
					cout << "You are not holding anything." << endl;
				}
				cin.ignore(256, '\n');
				break;
			}
			case 4:		//pick up item
			{
				//test if object already being held
				if (currentObject == NULL)
				{
					if ((location == cave1 || location == cave2) && !flashlightOn)	//in cave but no light
					{
						cout << "It's too dark to see any items. Some light may help." << endl;
					}
					//test for cave location and flashlight status   OR   any other location
					else if (((location == cave1 || location == cave2) && flashlightOn) || (location != cave1 || location != cave2))
					{
						//test for items
						if (location->objectsPresent())
						{
							int choice = -1;
							int getComplete = false;
							while (choice = -1 && getComplete == false)
							{
								location->displayObjects();		//display item list
								cout << endl;
								cout << "Enter the Item # and press enter." << endl;
								choice = getInput();			//user selects item
								if (choice > -1 && choice < 10)	//test for valid choice
								{
									if (location->getObject(choice) != NULL)
									{
										currentObject = (location->getObject(choice)); //add object to currentObject
										location->removeObject(choice);		//remove object from space
										cout << "You are now holding " << currentObject->getName() << endl;
										getComplete = true;
									}
									else
									{
										cout << "Incorrect choice. Try again" << endl;
										choice = -1;
									}
								}
							}
						}
						else
						{
							cout << "No items to pick up here." << endl;
						}
					}
					/*else if ((location == cave1 || location == cave2) && !flashlightOn)
					{
						cout << endl << location->getLook1() << endl << endl;
					}*/
					//else
						//{
						//	//display location view
						//	cout << endl << location->getLook1() << endl << endl;
						//	//display objects present
						//	location->displayObjects();
						//}
				}
				else
				{
					cout << "You cannot pick up another item because you are already holding something" << endl;
				}
				cin.ignore(256, '\n');
				break;
			}
			case 5:		//drop item
			{
				//test if object already being held
				if (currentObject != NULL)
				{
					//int complete = false;
					//add object to space
					location->addObject(currentObject);
					currentObject = NULL;
					cout << "You have dropped the item." << endl;
					//complete = true;
				}
				else
				{
					cout << "You are not holding anything, nothing to drop" << endl;
				}
				cin.ignore(256, '\n');
				break;
			}
			case 6:		//list backpack & item held
			{
				if (currentObject != NULL) cout << "You are holdling: " << endl << currentObject->getName() << endl;
				else cout << "You are not holding anything" << endl;
				cout << endl;
				bool noObjects = true;
				cout << "Backpack contents: " << endl;
				for (int i = 0; i < 4; i++)
				{
					if (backpack[i] != NULL)
					{
						cout << "Item # " << i << "   " << backpack[i]->getName() << endl;
						noObjects = false;
					}
				}
				if (noObjects) cout << "No items." << endl;
				cout << endl;
				cin.ignore(256, '\n');
				break;
			}
			case 7:		//put item in backpack
			{
				//test if object being held
				if (currentObject != NULL)
				{
					int complete = false;
					for (int i = 0; i < 4; i++)
					{
						if (!complete && backpack[i] == NULL)
						{
							backpack[i] = currentObject;
							complete = true;
						}
					}
					if (complete)
					{
						currentObject = NULL;
						cout << "The item has been placed in your backpack." << endl;
					}
					else cout << "Backpack is full. Item not placed in backpack.";
				}
				else
				{
					cout << "You are not holding anything to put in the backpack." << endl;
				}
				cin.ignore(256, '\n');
				break;
			}
			case 8:		//get item from backpack
			{
				//test if object already being held
				if (currentObject == NULL)
				{
					int choice = -1;
					int complete = false;
					//test for items
					bool isEmpty = true;
					for (int i = 0; i < 4; i++)
					{
						if (isEmpty && backpack[i] != NULL) isEmpty = false;
					}
					if (!isEmpty)
					{
						while (choice == -1 && complete == false)
						{
							//display item list
							for (int i = 0; i < 4; i++)
							{
								if (backpack[i] != NULL)
								{
									cout << "Item # " << i << "   " << backpack[i]->getName() << endl;
								}
							}
							cout << endl;
							cout << "Enter the Item # and press enter." << endl;
							choice = getInput();			//user selects item
							if (choice > -1 && choice < 4)	//test for valid choice
							{
								if (backpack[choice] != NULL)
								{
									currentObject = backpack[choice];
									backpack[choice] = NULL;			//remove object from backpack
									cout << "You are now holding " << currentObject->getName() << endl;
									complete = true;
								}
								else
								{
									cout << "Incorrect choice. Try again" << endl;
									choice = -1;
								}
							}
							else
							{
								cout << "Incorrect choice. Try again" << endl;
								choice = -1;
							}
						}
					}
					else
					{
						cout << "No items in backpack." << endl;
					}
				}
				else
				{
					cout << "You cannot get something from the backpack because you are already holding something" << endl;
				}
				cin.ignore(256, '\n');
				break;
			}
			case 9:		//special option
			{
				int specialResult = location->special();
				switch (specialResult)
				{
				case 1:			//cases 1 to 4 are result from transporting after touching ravine orb
					location = location->getPointer(specialResult);
					turnsRemaining -= 1;
					break;
				case 2:
					location = location->getPointer(specialResult);
					turnsRemaining -= 1;
					break;
				case 3:
					location = location->getPointer(specialResult);
					turnsRemaining -= 1;
					break;
				case 4:
					location = location->getPointer(specialResult);
					turnsRemaining -= 1;
					break;
				case 5:		//touching orb in a cave
					turnsRemaining -= 3;
					hydration -= 2;
					cout << location->getEntryMessage() << endl;
					break;
				case 6:		//touching orb in tower
					hydration += 1;
					cout << "The mist has increased your hydration level 1 point." << endl;
					cout << location->getEntryMessage() << endl;
					break;
				case 7:		//touching orb in treehouse
					if (currentObject == orb)
					{
						cout << "The Leprechaun looks at the orb in your hand and begins to laugh hysterically." << endl;
						cout << "He snatches the orb from your hand and jumps out of the window!" << endl;
						happyLeprechaun = true;
						done = true;
					}
					else
					{
						cout << "The Leprechaun looks at your hand, then to the ground. \nHe stands for a moment, then retreats to behind the chair." << endl;
					}
					break;
				}
				//cin.ignore(256, '\n');
				break;  //break out of menu case 9
			}
			default:
				cout << "Not a valid choice" << endl;
				cin.ignore(256, '\n');
				break;
			}	//end of menu loop
		}
	}	//end of game while loop
	if (hydration < 1) cout << "You died from dehydration." << endl;
	if (turnsRemaining < 1) cout << "You have died from exhaustion." << endl;
	if (death) cout << endl << "Sorry you didn't make it. Try again ;-)" << endl;
	if (happyLeprechaun) cout << endl << "You are a hero! \nYou made him happy! \nYou have saved the world! \n******* Well Done! *******" << endl;
	cout << "\n\n";
	return 0;
}
Esempio n. 23
0
COLORREF LocalIllumination::Illuminate(Space &space, ModelOBJ::Vertex &intersectPoint, Ray & ray, int triangleIndex, bool enableShadow)
{
	float color[3]; // RGB
	float ia_result=0.0f, id_result=0.0f, is_result = 0.0f;
	float i_result[3] = { 0, 0, 0 };
	ShadowRay shadowRay;

	const ModelOBJ & model = space.GetModel();
	const int materialIndex = model.getMaterialIndex(triangleIndex);
	const ModelOBJ::Material &material = model.getMaterial(materialIndex);
	const Triangle triangle = space.GetTriangle(triangleIndex);

	for (int light_i = 0; light_i < space.GetLightNum(); light_i++)
	{
		const Space::Light & light = space.GetLight(light_i);
		for (int color_i = 0; color_i < 3; color_i++)
		{
			ia_result = 0.0f;
			id_result = 0.0f;
			is_result = 0.0f;

			ia_result = material.ambient[color_i] * light.intesity[0][color_i];

			
			glm::vec3 lvec = Utils::GetVector(intersectPoint, light.position);
			float distance = glm::length(lvec);
			
			float distance2 = std::fmax(1, 0.2 * pow(distance, 2));
			lvec = lvec / distance;
			glm::vec3 nvec = triangle.GetNormalVector();
			glm::vec3 vvec = ray.GetDirVector() * -1.0f;
			vvec = vvec / glm::length(vvec);

			//Determine if the normal vector is on the same side with view vector
			float checkDirection = glm::dot(vvec, nvec); //
			if (checkDirection < 0.0f)
			{
				nvec = nvec * -1.0f;
			}

			float productOfNL = glm::dot(nvec, lvec);

			const ModelOBJ::Vertex& lightPos = light.position;

			bool shadow = false;
			if (enableShadow)
			{
				shadow = shadowRay.block(space, intersectPoint, lightPos, triangleIndex);
			}
			if (productOfNL < 0.0f || shadow)
			{ 
				
			}
			else
			{
				id_result = material.diffuse[color_i] * light.intesity[1][color_i] * productOfNL / distance2;
				id_result = id_result < 0.0f ? 0 : id_result;

				//Classical model of specular refelection
				/*vvec = vvec / glm::length(vvec);
				glm::vec3 rvec = glm::dot(nvec, lvec) * 2 * nvec - lvec;
				rvec = rvec / glm::length(rvec);

				is_result = material.specular[color_i] * light.intesity[color_i] * pow(glm::dot(rvec, vvec), material.shininess);
				is_result = is_result < 0 ? 0 : id_result;

				*/

				//Blinn-Phong's model of specular refelection
				glm::vec3 hvec = lvec + vvec;
				hvec = hvec / glm::length(hvec);

				is_result = material.specular[color_i] * light.intesity[2][color_i] * pow(glm::dot(nvec, hvec), material.shininess) / distance2;
				is_result = is_result < 0 ? 0 : id_result;
			}

			float tmp_i_result = (ia_result + id_result + is_result) * 255.0f;
			//clamp
			if (tmp_i_result > 255.0f)
			{
				tmp_i_result = 255.0f;
			}
			else if (tmp_i_result < 0.0f)
			{
				tmp_i_result = 0.0f;
			}

			i_result[color_i] += tmp_i_result;

		}
	}

	//clamp
	for (int color_i = 0; color_i < 3; color_i++)
	{
		if (i_result[color_i] > 255.0f)
		{
			i_result[color_i] = 255.0f;
		}
		else if (i_result[color_i] < 0.0f)
		{
			i_result[color_i] = 0.0f;
		}
	}

	return RGB(i_result[0], i_result[1], i_result[2]);
}
Esempio n. 24
0
/***********************************************************************************
 * main program                                                                    *
************************************************************************************/
int main(int argc, char **args)
{

#ifdef WITH_PETSC
    PetscInitialize(NULL, NULL, PETSC_NULL, PETSC_NULL);
    PetscPushErrorHandler(PetscIgnoreErrorHandler, PETSC_NULL);		// Disable PETSc error handler.
#endif

    // Load the inital mesh.
    Mesh mesh;
    Mesh3DReader mesh_loader;
    mesh_loader.load("hexahedron.mesh3d", &mesh);

    // Initial uniform  mesh refinements.
    printf("Performing %d initial mesh refinements.\n", INIT_REF_NUM);
    for (int i=0; i < INIT_REF_NUM; i++) mesh.refine_all_elements(H3D_H3D_H3D_REFT_HEX_XYZ);
    Word_t (nelem) = mesh.get_num_elements();
    printf("New number of elements is %d.\n", nelem);

    //Initialize the shapeset and the cache.
    H1ShapesetLobattoHex shapeset;

    //Matrix solver.
#if defined WITH_UMFPACK
    UMFPackMatrix mat;
    UMFPackVector rhs;
    UMFPackLinearSolver solver(&mat, &rhs);
#elif defined WITH_PETSC
    PetscMatrix mat;
    PetscVector rhs;
    PetscLinearSolver solver(&mat, &rhs);
#elif defined WITH_MUMPS
    MumpsMatrix mat;
    MumpsVector rhs;
    MumpsSolver solver(&mat, &rhs);
#endif

    // Graphs of DOF convergence.
    GnuplotGraph graph;
    graph.set_captions("", "Degrees of Freedom", "Error [%]");
    graph.set_log_y();
    graph.add_row("Total error", "k", "-", "O");

    // Create H1 space to setup the problem.
    H1Space space(&mesh, &shapeset);
    space.set_bc_types(bc_types);
    space.set_essential_bc_values(essential_bc_values);
    space.set_uniform_order(order3_t(P_INIT, P_INIT, P_INIT));

    // Initialize the weak formulation.
    WeakForm wf;
    wf.add_matrix_form(biform<double, double>, biform<ord_t, ord_t>, SYM, ANY);
    wf.add_vector_form(liform<double, double>, liform<ord_t, ord_t>, ANY);

    // Initialize the coarse mesh problem.
    LinProblem lp(&wf);
    lp.set_space(&space);

    // Adaptivity loop.
    int as = 0;
    bool done = false;
    do {
        printf("\n---- Adaptivity step %d:\n", as);

        printf("\nSolving on coarse mesh:\n");

        // Procedures for coarse mesh problem.
        // Assign DOF.
        int ndof = space.assign_dofs();
        printf("  - Number of DOF: %d\n", ndof);

        // Assemble stiffness matrix and rhs.
        printf("  - Assembling... ");
        fflush(stdout);
        if (lp.assemble(&mat, &rhs))
            printf("done in %lf secs.\n", lp.get_time());
        else
            error("failed!");

        // Solve the system.
        printf("  - Solving... ");
        fflush(stdout);
        bool solved = solver.solve();
        if (solved)
            printf("done in %lf secs.\n", solver.get_time());
        else
        {
            printf("Failed.\n");
            break;
        }

        // Construct a solution.
        Solution sln(&mesh);
        sln.set_fe_solution(&space, solver.get_solution());

        // Output the orders and the solution.
        if (do_output)
        {
            out_orders(&space, "order", as);
            out_fn(&sln, "sln", as);
        }

        // Solving fine mesh problem.
        printf("Solving on fine mesh:\n");

        // Matrix solver.
#if defined WITH_UMFPACK
        UMFPackLinearSolver rsolver(&mat, &rhs);
#elif defined WITH_PETSC
        PetscLinearSolver rsolver(&mat, &rhs);
#elif defined WITH_MUMPS
        MumpsSolver rsolver(&mat, &rhs);
#endif

        // Construct the refined mesh for reference(refined) solution.
        Mesh rmesh;
        rmesh.copy(mesh);
        rmesh.refine_all_elements(H3D_H3D_H3D_REFT_HEX_XYZ);

        // Setup space for the reference (globally refined) solution.
        Space *rspace = space.dup(&rmesh);
        rspace->copy_orders(space, 1);

        // Initialize the mesh problem for reference solution.
        LinProblem rlp(&wf);
        rlp.set_space(rspace);

        // Assign DOF.
        int rndof = rspace->assign_dofs();
        printf("  - Number of DOF: %d\n", rndof);

        // Assemble stiffness matric and rhs.
        printf("  - Assembling... ");
        fflush(stdout);
        if (rlp.assemble(&mat, &rhs))
            printf("done in %lf secs.\n", rlp.get_time());
        else
            error("failed!");

        // Solve the system.
        printf("  - Solving... ");
        fflush(stdout);
        bool rsolved = rsolver.solve();
        if (rsolved)
            printf("done in %lf secs.\n", rsolver.get_time());
        else
        {
            printf("failed.\n");
            break;
        }

        // Construct the reference(refined) solution.
        Solution rsln(&rmesh);
        rsln.set_fe_solution(rspace, rsolver.get_solution());

        // Compare coarse and fine mesh.
        // Calculate the error estimate wrt. refined mesh solution.
        double err = h1_error(&sln, &rsln);
        printf("  - H1 error: % lf\n", err * 100);

        // Save it to the graph.
        graph.add_value(0, ndof, err * 100);
        if (do_output)
            graph.save("conv.gp");

        // Calculate error estimates for adaptivity.
        printf("Adaptivity\n");
        printf("  - calculating error: ");
        fflush(stdout);
        H1Adapt hp(&space);
        double err_est = hp.calc_error(&sln, &rsln) * 100;
        printf("% lf %%\n", err_est);

        // If error is too large, adapt the mesh.
        if (err_est < ERR_STOP)
        {
            printf("\nDone\n");
            break;
        }
        printf("  - adapting... ");
        fflush(stdout);
        hp.adapt(THRESHOLD);
        printf("done in %lf secs (refined %d element(s)).\n", hp.get_adapt_time(), hp.get_num_refined_elements());

        if (rndof >= NDOF_STOP)
        {
            printf("\nDone.\n");
            break;
        }

        // Clean up.
        delete rspace;

        // Next adaptivity step.
        as++;

        mat.free();
        rhs.free();
    } while (!done);

#ifdef WITH_PETSC
    PetscFinalize();
#endif

    return 1;
}
Esempio n. 25
0
  ExecStatus
  ElementUnionConst<SView,RView>::propagate(Space& home, const ModEventDelta&) {
    Region r(home);

    bool* stillSelected = r.alloc<bool>(n_iv);

    bool loopVar;
    do {
      loopVar = false;
      for (int i=n_iv; i--;)
        stillSelected[i] = false;

      // Cache the upper bound iterator, as we have to
      // modify the upper bound while iterating
      LubRanges<RView> x1ub(x1);
      Iter::Ranges::Cache x1ubc(r,x1ub);
      Iter::Ranges::ToValues<Iter::Ranges::Cache>
        vx1ub(x1ubc);

      GlbRanges<RView> x1lb(x1);
      Iter::Ranges::Cache x1lbc(r,x1lb);
      Iter::Ranges::ToValues<Iter::Ranges::Cache>
        vx1(x1lbc);

      // In the first iteration, compute in before[i] the union
      // of all the upper bounds of the x_i. At the same time,
      // exclude inconsistent x_i from x1.

      GLBndSet sofarBefore(home);
      LUBndSet selectedInter(home, IntSet (Limits::min,
                                   Limits::max));
      GLBndSet* before =
        static_cast<GLBndSet*>(r.ralloc(sizeof(GLBndSet)*n_iv));

      unsigned int maxCard = 0;
      unsigned int minCard = Limits::card;

      while (vx1ub()) {
        int i = vx1ub.val();

        IntSetRanges candCardR(iv[i]);
        unsigned int candidateCard = Iter::Ranges::size(candCardR);

        IntSetRanges candlb(iv[i]);
        LubRanges<SView> x0ub(x0);
        Iter::Ranges::Diff<IntSetRanges,
          LubRanges<SView> > diff(candlb, x0ub);

        bool selectSingleInconsistent = false;
        if (x1.cardMax() <= 1) {
          GlbRanges<SView> x0lb(x0);
          IntSetRanges candub(iv[i]);
          Iter::Ranges::Diff<GlbRanges<SView>,
                             IntSetRanges > diff2(x0lb, candub);
          selectSingleInconsistent = diff2() || candidateCard < x0.cardMin();
        }

        // exclude inconsistent x_i
        // an x_i is inconsistent if
        //  * at most one x_i can be selected and there are
        //    elements in x_0 that can't be in x_i
        //    (selectSingleInconsistent)
        //  * its min cardinality is greater than maxCard of x0
        //  * inter is not empty (there are elements in x_i
        //    that can't be in x_0)
        if (selectSingleInconsistent ||
            candidateCard > x0.cardMax() ||
            diff()) {
          ModEvent me = (x1.exclude(home,i));
          loopVar |= me_modified(me);
          GECODE_ME_CHECK(me);
        } else {
          stillSelected[i] = true;
          // if x_i is consistent, check whether we know
          // that its index is in x1
          if (vx1() && vx1.val()==i) {
            // x0 >= candidate, candidate <= x0
            // GlbRanges<SView> candlb(candidate);
            IntSetRanges candlb(iv[i]);
            ModEvent me = x0.includeI(home,candlb);
            loopVar |= me_modified(me);
            GECODE_ME_CHECK(me);
            ++vx1;
          }
          new (&before[i]) GLBndSet(home);
          before[i].update(home,sofarBefore);
          IntSetRanges cub(iv[i]);
          sofarBefore.includeI(home,cub);
          IntSetRanges clb(iv[i]);
          selectedInter.intersectI(home,clb);
          maxCard = std::max(maxCard, candidateCard);
          minCard = std::min(minCard, candidateCard);
        }

        ++vx1ub;
      }

      if (x1.cardMax()==0) {
        // Selector is empty, hence the result must be empty
        {
          GECODE_ME_CHECK(x0.cardMax(home,0));
        }
        for (int i=n_iv; i--;)
          if (stillSelected[i])
            before[i].dispose(home);
        selectedInter.dispose(home);
        sofarBefore.dispose(home);
        return home.ES_SUBSUMED(*this);
      }

      if (x1.cardMin() > 0) {
        // Selector is not empty, hence the intersection of the
        // possibly selected lower bounds is contained in x0
        BndSetRanges si(selectedInter);
        ModEvent me = x0.includeI(home, si);
        loopVar |= me_modified(me);
        GECODE_ME_CHECK(me);
        me = x0.cardMin(home, minCard);
        loopVar |= me_modified(me);
        GECODE_ME_CHECK(me);
      }
      selectedInter.dispose(home);

      if (x1.cardMax() <= 1) {
        ModEvent me = x0.cardMax(home, maxCard);
        loopVar |= me_modified(me);
        GECODE_ME_CHECK(me);
      }

      {
        // x0 <= sofarBefore
        BndSetRanges sfB(sofarBefore);
        ModEvent me = x0.intersectI(home,sfB);
        loopVar |= me_modified(me);
        GECODE_ME_CHECK(me);
      }

      sofarBefore.dispose(home);

      GLBndSet sofarAfter(home);

      // In the second iteration, this time backwards, compute
      // sofarAfter as the union of all lub(x_j) with j>i
      for (int i=n_iv; i--;) {
        if (!stillSelected[i])
          continue;
        BndSetRanges b(before[i]);
        BndSetRanges s(sofarAfter);
        GlbRanges<SView> x0lb(x0);
        Iter::Ranges::Union<BndSetRanges, BndSetRanges> inter(b,s);
        Iter::Ranges::Diff<GlbRanges<SView>,
          Iter::Ranges::Union<BndSetRanges,BndSetRanges> > diff(x0lb, inter);
        if (diff()) {
          ModEvent me = (x1.include(home,i));
          loopVar |= me_modified(me);
          GECODE_ME_CHECK(me);

          // candidate != extra
          IntSetRanges ivi(iv[i]);
          if (!Iter::Ranges::subset(diff, ivi))
            GECODE_ME_CHECK(ME_SET_FAILED);
        }

        IntSetRanges iviub(iv[i]);
        sofarAfter.includeI(home,iviub);
        before[i].dispose(home);
      }
      sofarAfter.dispose(home);

    } while (loopVar);

    if (x1.assigned()) {
      assert(x0.assigned());
      return home.ES_SUBSUMED(*this);
    }

    return ES_FIX;
  }
Esempio n. 26
0
  Family operator()( int color, const Space& sub )
  {
    Space base, margin;
    Family adjs;

    for ( typename Space::const_iterator it = base_.begin()
        ; it != base_.end(); ++it
        )
    {
      typename Space::const_point pt( it );

      if ( color_[ pt.index ] == color ) base.join( pt.element );
    }
    for ( typename Space::const_iterator it = base.begin()
        ; it != base.end(); ++it
        )
    {
      typename Space::const_point pt0( it );
#ifdef ELAI_USE_C11
      const Space&& adj = std::move( adjacent_( pt0.element ) );
#else
      const Space adj = adjacent_( pt0.element );
#endif
      Neighbour neigh( Element( pt0.element, color ) );

      for ( typename Space::const_iterator jt = adj.begin()
          ; jt != adj.end(); ++jt
          )
      {
        typename Space::const_point pt( jt );
        const Element pt1( pt.element, color );

        if ( !base.contain( pt.element ) && !margin.contain( pt.element ) )
          margin.join( pt.element, Element( pt.element, color ) ); // ( BASE, RECOLORED )
        if ( !sub.contain( pt1 ) ) continue;
        neigh.join( pt1 );
      }
      adjs.join( neigh );
    }
    for ( typename Space::const_marginal_iterator it = margin.internal_begin()
        ; it != margin.internal_end(); ++it
        )
    {
      typename Space::const_internal_point pt0( it );
#ifdef ELAI_USE_C11
      const Space&& adj = std::move( adjacent_( pt0.element ) );
#else
      const Space adj = adjacent_( pt0.internal ); // BASE ELEMENT
#endif
      Neighbour neigh( pt0.external ); // RECOLORED ELEMENT

      for ( typename Space::const_iterator jt = adj.begin(); jt != adj.end(); ++jt )
      {
        typename Space::const_point pt( jt );
        const Element pt1( pt.element, color );

        if ( !sub.contain( pt1 ) ) continue;
        neigh.join( pt1 );
      }
      adjs.join( neigh );
    }

    return adjs;
  }
Esempio n. 27
0
forceinline ExecStatus
timetabling(Space& home, Propagator& p, Cap c, TaskArray<Task>& t) {
    int ccur = c.max();
    int cmax = ccur;
    int cmin = ccur;

    // Sort tasks by decreasing capacity
    TaskByDecCap<Task> tbdc;
    Support::quicksort(&t[0], t.size(), tbdc);

    Region r(home);

    bool assigned;
    if (Event* e = Event::events(r,t,assigned)) {
        // Set of current but not required tasks
        Support::BitSet<Region> tasks(r,static_cast<unsigned int>(t.size()));

        // Process events, use ccur as the capacity that is still free
        do {
            // Current time
            int time = e->time();

            // Process events for completion of required part
            for ( ; (e->type() == Event::LRT) && (e->time() == time); e++)
                if (t[e->idx()].mandatory()) {
                    tasks.set(static_cast<unsigned int>(e->idx()));
                    ccur += t[e->idx()].c();
                }
            // Process events for completion of task
            for ( ; (e->type() == Event::LCT) && (e->time() == time); e++)
                tasks.clear(static_cast<unsigned int>(e->idx()));
            // Process events for start of task
            for ( ; (e->type() == Event::EST) && (e->time() == time); e++)
                tasks.set(static_cast<unsigned int>(e->idx()));
            // Process events for zero-length task
            for ( ; (e->type() == Event::ZRO) && (e->time() == time); e++) {
                ccur -= t[e->idx()].c();
                if (ccur < cmin) cmin=ccur;
                if (ccur < 0)
                    return ES_FAILED;
                ccur += t[e->idx()].c();
            }

            // norun start time
            int nrstime = time;
            // Process events for start of required part
            for ( ; (e->type() == Event::ERT) && (e->time() == time); e++)
                if (t[e->idx()].mandatory()) {
                    tasks.clear(static_cast<unsigned int>(e->idx()));
                    ccur -= t[e->idx()].c();
                    if (ccur < cmin) cmin=ccur;
                    nrstime = time+1;
                    if (ccur < 0)
                        return ES_FAILED;
                } else if (t[e->idx()].optional() && (t[e->idx()].c() > ccur)) {
                    GECODE_ME_CHECK(t[e->idx()].excluded(home));
                }

            // Exploit that tasks are sorted according to capacity
            for (Iter::Values::BitSet<Support::BitSet<Region> > j(tasks);
                    j() && (t[j.val()].c() > ccur); ++j)
                // Task j cannot run from zltime to next time - 1
                if (t[j.val()].mandatory())
                    GECODE_ME_CHECK(t[j.val()].norun(home, nrstime, e->time() - 1));
        } while (e->type() != Event::END);

        GECODE_ME_CHECK(c.gq(home,cmax-cmin));
    }

    if (assigned)
        return home.ES_SUBSUMED(p);
    return ES_NOFIX;
}
std::auto_ptr<DiscreteBoundaryOperator<ResultType> >
AcaGlobalAssembler<BasisFunctionType, ResultType>::assembleDetachedWeakForm(
        const Space<BasisFunctionType>& testSpace,
        const Space<BasisFunctionType>& trialSpace,
        const std::vector<LocalAssembler*>& localAssemblers,
        const std::vector<const DiscreteBndOp*>& sparseTermsToAdd,
        const std::vector<ResultType>& denseTermsMultipliers,
        const std::vector<ResultType>& sparseTermsMultipliers,
        const AssemblyOptions& options,
        int symmetry)
{
#ifdef WITH_AHMED
    typedef AhmedDofWrapper<CoordinateType> AhmedDofType;
    typedef ExtendedBemCluster<AhmedDofType> AhmedBemCluster;
    typedef bemblcluster<AhmedDofType, AhmedDofType> AhmedBemBlcluster;
    typedef DiscreteAcaBoundaryOperator<ResultType> DiscreteAcaLinOp;

    const AcaOptions& acaOptions = options.acaOptions();
    const bool indexWithGlobalDofs = acaOptions.globalAssemblyBeforeCompression;
    const bool verbosityAtLeastDefault =
            (options.verbosityLevel() >= VerbosityLevel::DEFAULT);
    const bool verbosityAtLeastHigh =
            (options.verbosityLevel() >= VerbosityLevel::HIGH);

    // Currently we don't support Hermitian ACA operators. This is because we
    // don't have the means to really test them -- we would need complex-valued
    // basis functions for that. (Assembly of such a matrix would be very easy
    // -- just change complex_sym from true to false in the call to apprx_sym()
    // in AcaWeakFormAssemblerLoopBody::operator() -- but operations on
    // symmetric/Hermitian matrices are not always trivial and we do need to be
    // able to test them properly.)
    bool symmetric = symmetry & SYMMETRIC;
    if (symmetry & HERMITIAN && !(symmetry & SYMMETRIC) &&
            verbosityAtLeastDefault)
        std::cout << "Warning: assembly of non-symmetric Hermitian H-matrices "
                     "is not supported yet. A general H-matrix will be assembled"
                  << std::endl;

#ifndef WITH_TRILINOS
    if (!indexWithGlobalDofs)
        throw std::runtime_error("AcaGlobalAssembler::assembleDetachedWeakForm(): "
                                 "ACA assembly with globalAssemblyBeforeCompression "
                                 "set to false requires BEM++ to be linked with "
                                 "Trilinos");
#endif // WITH_TRILINOS

    const size_t testDofCount = indexWithGlobalDofs ?
                testSpace.globalDofCount() : testSpace.flatLocalDofCount();
    const size_t trialDofCount = indexWithGlobalDofs ?
                trialSpace.globalDofCount() : trialSpace.flatLocalDofCount();

    if (symmetric && testDofCount != trialDofCount)
        throw std::invalid_argument("AcaGlobalAssembler::assembleDetachedWeakForm(): "
                                    "you cannot generate a symmetric weak form "
                                    "using test and trial spaces with different "
                                    "numbers of DOFs");

    // o2p: map of original indices to permuted indices
    // p2o: map of permuted indices to original indices
    typedef ClusterConstructionHelper<BasisFunctionType> CCH;
    shared_ptr<AhmedBemCluster> testClusterTree;
    shared_ptr<IndexPermutation> test_o2pPermutation, test_p2oPermutation;
    CCH::constructBemCluster(testSpace, indexWithGlobalDofs, acaOptions,
                             testClusterTree,
                             test_o2pPermutation, test_p2oPermutation);
    shared_ptr<AhmedBemCluster> trialClusterTree;
    shared_ptr<IndexPermutation> trial_o2pPermutation, trial_p2oPermutation;
    if (symmetric || &testSpace == &trialSpace) {
        trialClusterTree = testClusterTree;
        trial_o2pPermutation = test_o2pPermutation;
        trial_p2oPermutation = test_p2oPermutation;
    } else
        CCH::constructBemCluster(trialSpace, indexWithGlobalDofs, acaOptions,
                                 trialClusterTree,
                                 trial_o2pPermutation, trial_p2oPermutation);

//    // Export VTK plots showing the disctribution of leaf cluster ids
//    std::vector<unsigned int> testClusterIds;
//    getClusterIds(*testClusterTree, test_p2oPermutation->permutedIndices(), testClusterIds);
//    testSpace.dumpClusterIds("testClusterIds", testClusterIds,
//                             indexWithGlobalDofs ? GLOBAL_DOFS : FLAT_LOCAL_DOFS);
//    std::vector<unsigned int> trialClusterIds;
//    getClusterIds(*trialClusterTree, trial_p2oPermutation->permutedIndices(), trialClusterIds);
//    trialSpace.dumpClusterIds("trialClusterIds", trialClusterIds,
//                              indexWithGlobalDofs ? GLOBAL_DOFS : FLAT_LOCAL_DOFS);

    if (verbosityAtLeastHigh)
        std::cout << "Test cluster count: " << testClusterTree->getncl()
                  << "\nTrial cluster count: " << trialClusterTree->getncl()
                  << std::endl;

    unsigned int blockCount = 0;
    shared_ptr<AhmedBemBlcluster> bemBlclusterTree(
                CCH::constructBemBlockCluster(acaOptions, symmetric,
                                              *testClusterTree, *trialClusterTree,
                                              blockCount).release());

    if (verbosityAtLeastHigh)
        std::cout << "Mblock count: " << blockCount << std::endl;

    std::vector<unsigned int> p2oTestDofs =
        test_p2oPermutation->permutedIndices();
    std::vector<unsigned int> p2oTrialDofs =
        trial_p2oPermutation->permutedIndices();
    WeakFormAcaAssemblyHelper<BasisFunctionType, ResultType>
        helper(testSpace, trialSpace, p2oTestDofs, p2oTrialDofs,
               localAssemblers, sparseTermsToAdd,
               denseTermsMultipliers, sparseTermsMultipliers, options);

    typedef mblock<typename AhmedTypeTraits<ResultType>::Type> AhmedMblock;
    boost::shared_array<AhmedMblock*> blocks =
            allocateAhmedMblockArray<ResultType>(bemBlclusterTree.get());

    // matgen_sqntl(helper, AhmedBemBlclusterTree.get(), AhmedBemBlclusterTree.get(),
    //              acaOptions.recompress, acaOptions.eps,
    //              acaOptions.maximumRank, blocks.get());

    // matgen_omp(helper, blockCount, AhmedBemBlclusterTree.get(),
    //            acaOptions.eps, acaOptions.maximumRank, blocks.get());

    // // Dump mblocks
    // const int mblockCount = AhmedBemBlclusterTree->nleaves();
    // for (int i = 0; i < mblockCount; ++i)
    //     if (blocks[i]->isdns())
    //     {
    //         char  buffer[1024];
    //         sprintf(buffer, "mblock-dns-%d-%d.txt",
    //                 blocks[i]->getn1(), blocks[i]->getn2());
    //         arma::Col<ResultType> block((ResultType*)blocks[i]->getdata(),
    //                                     blocks[i]->nvals());
    //         arma::diskio::save_raw_ascii(block, buffer);
    //     }
    //     else
    //     {
    //         char buffer[1024];
    //         sprintf(buffer, "mblock-lwr-%d-%d.txt",
    //                 blocks[i]->getn1(), blocks[i]->getn2());
    //         arma::Col<ResultType> block((ResultType*)blocks[i]->getdata(),
    //                                     blocks[i]->nvals());
    //         arma::diskio::save_raw_ascii(block, buffer);
    //     }

    AhmedLeafClusterArray leafClusters(bemBlclusterTree.get());
    leafClusters.sortAccordingToClusterSize();
    const size_t leafClusterCount = leafClusters.size();

    const ParallelizationOptions& parallelOptions =
            options.parallelizationOptions();
    int maxThreadCount = 1;
    if (!parallelOptions.isOpenClEnabled())
    {
        if (parallelOptions.maxThreadCount() == ParallelizationOptions::AUTO)
            maxThreadCount = tbb::task_scheduler_init::automatic;
        else
            maxThreadCount = parallelOptions.maxThreadCount();
    }
    tbb::task_scheduler_init scheduler(maxThreadCount);
    tbb::atomic<size_t> done;
    done = 0;

    std::vector<ChunkStatistics> chunkStats(leafClusterCount);

    //    typedef AcaWeakFormAssemblerLoopBody<BasisFunctionType, ResultType> Body;
    //    // std::cout << "Loop start" << std::endl;
    //    tbb::tick_count loopStart = tbb::tick_count::now();
    // //    tbb::parallel_for(tbb::blocked_range<size_t>(0, leafClusterCount),
    // //                      Body(helper, leafClusters, blocks, acaOptions, done
    // //                           , chunkStats));
    //    tbb::parallel_for(ScatteredRange(0, leafClusterCount),
    //                      Body(helper, leafClusters, blocks, acaOptions, done
    //                           , chunkStats));
    //    tbb::tick_count loopEnd = tbb::tick_count::now();
    //    // std::cout << "Loop end" << std::endl;

    typedef AcaWeakFormAssemblerLoopBody<BasisFunctionType, ResultType> Body;
    typename Body::LeafClusterIndexQueue leafClusterIndexQueue;
    for (size_t i = 0; i < leafClusterCount; ++i)
        leafClusterIndexQueue.push(i);

    if (verbosityAtLeastDefault)
        std::cout << "About to start the ACA assembly loop" << std::endl;
    tbb::tick_count loopStart = tbb::tick_count::now();
    {
        Fiber::SerialBlasRegion region; // if possible, ensure that BLAS is single-threaded
        tbb::parallel_for(tbb::blocked_range<size_t>(0, leafClusterCount),
                          Body(helper, leafClusters, blocks, acaOptions, done,
                               verbosityAtLeastDefault,
                               leafClusterIndexQueue, symmetric, chunkStats));
    }
    tbb::tick_count loopEnd = tbb::tick_count::now();
    if (verbosityAtLeastDefault) {
        std::cout << "\n"; // the progress bar doesn't print the final \n
        std::cout << "ACA loop took " << (loopEnd - loopStart).seconds() << " s"
                  << std::endl;
    }

    // TODO: parallelise!
    if (acaOptions.recompress) {
        if (verbosityAtLeastDefault)
            std::cout << "About to start ACA agglomeration" << std::endl;
        agglH(bemBlclusterTree.get(), blocks.get(),
              acaOptions.eps, acaOptions.maximumRank);
        if (verbosityAtLeastDefault)
            std::cout << "Agglomeration finished" << std::endl;
    }

    // // Dump timing data of individual chunks
    //    std::cout << "\nChunks:\n";
    //    for (int i = 0; i < leafClusterCount; ++i)
    //        if (chunkStats[i].valid) {
    //            int blockIndex = leafClusters[i]->getidx();
    //            std::cout << chunkStats[i].chunkStart << "\t"
    //                      << chunkStats[i].chunkSize << "\t"
    //                      << (chunkStats[i].startTime - loopStart).seconds() << "\t"
    //                      << (chunkStats[i].endTime - loopStart).seconds() << "\t"
    //                      << (chunkStats[i].endTime - chunkStats[i].startTime).seconds() << "\t"
    //                      << blocks[blockIndex]->getn1() << "\t"
    //                      << blocks[blockIndex]->getn2() << "\t"
    //                      << blocks[blockIndex]->islwr() << "\t"
    //                      << (blocks[blockIndex]->islwr() ? blocks[blockIndex]->rank() : 0) << "\n";
    //        }

    {
        size_t origMemory = sizeof(ResultType) * testDofCount * trialDofCount;
        size_t ahmedMemory = sizeH(bemBlclusterTree.get(), blocks.get());
        int maximumRank = Hmax_rank(bemBlclusterTree.get(), blocks.get());
        if (verbosityAtLeastDefault)
            std::cout << "\nNeeded storage: "
                      << ahmedMemory / 1024. / 1024. << " MB.\n"
                      << "Without approximation: "
                      << origMemory / 1024. / 1024. << " MB.\n"
                      << "Compressed to "
                      << (100. * ahmedMemory) / origMemory << "%.\n"
                      << "Maximum rank: " << maximumRank << ".\n"
                      << std::endl;

        if (acaOptions.outputPostscript) {
            if (verbosityAtLeastDefault)
                std::cout << "Writing matrix partition ..." << std::flush;
            std::ofstream os(acaOptions.outputFname.c_str());
            if (symmetric) // seems valid also for Hermitian matrices
                psoutputHeH(os, bemBlclusterTree.get(), testDofCount, blocks.get());
            else
                psoutputGeH(os, bemBlclusterTree.get(), testDofCount, blocks.get());
            os.close();
            if (verbosityAtLeastDefault)
                std::cout << " done." << std::endl;
        }
    }

    int outSymmetry = NO_SYMMETRY;
    if (symmetric) {
        outSymmetry = SYMMETRIC;
        if (!boost::is_complex<ResultType>())
            outSymmetry |= HERMITIAN;
    }
    std::auto_ptr<DiscreteAcaLinOp> acaOp(
                new DiscreteAcaLinOp(testDofCount, trialDofCount,
                                     acaOptions.eps,
                                     acaOptions.maximumRank,
                                     outSymmetry,
                                     bemBlclusterTree, blocks,
                                     *trial_o2pPermutation,
                                     *test_o2pPermutation,
                                     parallelOptions));

    std::auto_ptr<DiscreteBndOp> result;
    if (indexWithGlobalDofs)
        result = acaOp;
    else {
#ifdef WITH_TRILINOS
        // without Trilinos, this code will never be reached -- an exception
        // will be thrown earlier in this function
        typedef DiscreteBoundaryOperatorComposition<ResultType> DiscreteBndOpComp;
        shared_ptr<DiscreteBndOp> acaOpShared(acaOp.release());
        shared_ptr<DiscreteBndOp> trialGlobalToLocal =
                constructOperatorMappingGlobalToFlatLocalDofs<
                BasisFunctionType, ResultType>(trialSpace);
        shared_ptr<DiscreteBndOp> testLocalToGlobal =
                constructOperatorMappingFlatLocalToGlobalDofs<
                BasisFunctionType, ResultType>(testSpace);
        shared_ptr<DiscreteBndOp> tmp(
                    new DiscreteBndOpComp(acaOpShared, trialGlobalToLocal));
        result.reset(new DiscreteBndOpComp(testLocalToGlobal, tmp));
#endif // WITH_TRILINOS
    }
    return result;

#else // without Ahmed
    throw std::runtime_error("AcaGlobalAssembler::assembleDetachedWeakForm(): "
                             "To enable assembly in ACA mode, recompile BEM++ "
                             "with the symbol WITH_AHMED defined.");
#endif // WITH_AHMED
}
Esempio n. 29
0
int main() 
{
  // Time measurement.
  TimePeriod cpu_time;
  cpu_time.tick();

  // Create coarse mesh, set Dirichlet BC, enumerate basis functions.
  Space* space = new Space(A, B, NELEM, DIR_BC_LEFT, DIR_BC_RIGHT, P_INIT, NEQ);

  // Enumerate basis functions, info for user.
  int ndof = Space::get_num_dofs(space);
  info("ndof: %d", ndof);

  // Initialize the weak formulation.
  WeakForm wf;
  wf.add_matrix_form(jacobian);
  wf.add_vector_form(residual);

  double elem_errors[MAX_ELEM_NUM];      // This array decides what 
                                         // elements will be refined.
  ElemPtr2 ref_elem_pairs[MAX_ELEM_NUM]; // To store element pairs from the 
                                         // FTR solution. Decides how 
                                         // elements will be hp-refined. 
  for (int i=0; i < MAX_ELEM_NUM; i++) 
  {
    ref_elem_pairs[i][0] = new Element();
    ref_elem_pairs[i][1] = new Element();
  }

  // DOF and CPU convergence graphs.
  SimpleGraph graph_dof_exact, graph_cpu_exact;

  // Adaptivity loop:
  int as = 1;
  bool done = false;
  do
  {
    info("---- Adaptivity step %d:", as);

    // Initialize the FE problem.
    bool is_linear = false;
    DiscreteProblem *dp_coarse = new DiscreteProblem(&wf, space, is_linear);
    
    // Newton's loop on coarse mesh.
    // Fill vector coeff_vec using dof and coeffs arrays in elements.
    double *coeff_vec_coarse = new double[Space::get_num_dofs(space)];
    get_coeff_vector(space, coeff_vec_coarse);

    // Set up the solver, matrix, and rhs according to the solver selection.
    SparseMatrix* matrix_coarse = create_matrix(matrix_solver);
    Vector* rhs_coarse = create_vector(matrix_solver);
    Solver* solver_coarse = create_linear_solver(matrix_solver, matrix_coarse, rhs_coarse);

    int it = 1;
    while (1) 
    {
      // Obtain the number of degrees of freedom.
      int ndof_coarse = Space::get_num_dofs(space);

      // Assemble the Jacobian matrix and residual vector.
      dp_coarse->assemble(coeff_vec_coarse, matrix_coarse, rhs_coarse);

      // Calculate the l2-norm of residual vector.
      double res_l2_norm = get_l2_norm(rhs_coarse);

      // Info for user.
      info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(space), res_l2_norm);

      // If l2 norm of the residual vector is within tolerance, then quit.
      // NOTE: at least one full iteration forced
      //       here because sometimes the initial
      //       residual on fine mesh is too small.
      if(res_l2_norm < NEWTON_TOL_COARSE && it > 1) break;

      // Multiply the residual vector with -1 since the matrix 
      // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n).
      for(int i=0; i<ndof_coarse; i++) rhs_coarse->set(i, -rhs_coarse->get(i));

      // Solve the linear system.
      if(!solver_coarse->solve())
      error ("Matrix solver failed.\n");

      // Add \deltaY^{n+1} to Y^n.
      for (int i = 0; i < ndof_coarse; i++) coeff_vec_coarse[i] += solver_coarse->get_solution()[i];

      // If the maximum number of iteration has been reached, then quit.
      if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge.");
      
      // Copy coefficients from vector y to elements.
      set_coeff_vector(coeff_vec_coarse, space);
      
      it++;
    }
    
    // Cleanup.
    delete matrix_coarse;
    delete rhs_coarse;
    delete solver_coarse;
    delete [] coeff_vec_coarse;
    delete dp_coarse;

    // For every element perform its fast trial refinement (FTR),
    // calculate the norm of the difference between the FTR
    // solution and the coarse space solution, and store the
    // error in the elem_errors[] array.
    int n_elem = space->get_n_active_elem();
    for (int i=0; i < n_elem; i++) 
    {

      info("=== Starting FTR of Elem [%d].", i);

      // Replicate coarse space including solution.
      Space *space_ref_local = space->replicate();

      // Perform FTR of element 'i'
      space_ref_local->reference_refinement(i, 1);
      info("Elem [%d]: fine space created (%d DOF).", 
             i, space_ref_local->assign_dofs());

      // Initialize the FE problem. 
      bool is_linear = false;
      DiscreteProblem* dp = new DiscreteProblem(&wf, space_ref_local, is_linear);

      // Set up the solver, matrix, and rhs according to the solver selection.
      SparseMatrix* matrix = create_matrix(matrix_solver);
      Vector* rhs = create_vector(matrix_solver);
      Solver* solver = create_linear_solver(matrix_solver, matrix, rhs);

      // Newton's loop on the FTR space.
      // Fill vector coeff_vec using dof and coeffs arrays in elements.
      double *coeff_vec = new double[Space::get_num_dofs(space_ref_local)];
      get_coeff_vector(space_ref_local, coeff_vec);
      memset(coeff_vec, 0, Space::get_num_dofs(space_ref_local)*sizeof(double));

      int it = 1;
      while (1) 
      {
        // Obtain the number of degrees of freedom.
        int ndof = Space::get_num_dofs(space_ref_local);

        // Assemble the Jacobian matrix and residual vector.
        dp->assemble(coeff_vec, matrix, rhs);

        // Calculate the l2-norm of residual vector.
        double res_l2_norm = get_l2_norm(rhs);

        // Info for user.
        info("---- Newton iter %d, ndof %d, res. l2 norm %g", it, Space::get_num_dofs(space_ref_local), res_l2_norm);

        // If l2 norm of the residual vector is within tolerance, then quit.
        // NOTE: at least one full iteration forced
        //       here because sometimes the initial
        //       residual on fine mesh is too small.
        if(res_l2_norm < NEWTON_TOL_REF && it > 1) break;

        // Multiply the residual vector with -1 since the matrix 
        // equation reads J(Y^n) \deltaY^{n+1} = -F(Y^n).
        for(int i=0; i<ndof; i++) rhs->set(i, -rhs->get(i));

        // Solve the linear system.
        if(!solver->solve())
        error ("Matrix solver failed.\n");

        // Add \deltaY^{n+1} to Y^n.
        for (int i = 0; i < ndof; i++) coeff_vec[i] += solver->get_solution()[i];

        // If the maximum number of iteration has been reached, then quit.
        if (it >= NEWTON_MAX_ITER) error ("Newton method did not converge.");
        
        // Copy coefficients from vector y to elements.
        set_coeff_vector(coeff_vec, space_ref_local);

        it++;
      }
      
      // Cleanup.
      delete matrix;
      delete rhs;
      delete solver;
      delete dp;
      delete [] coeff_vec;

      // Print FTR solution (enumerated). 
      //Linearizer *lxx = new Linearizer(space_ref_local);
      //char out_filename[255];
      //sprintf(out_filename, "solution_ref_%d.gp", i);
      //lxx->plot_solution(out_filename);
      //delete lxx;

      // Calculate norm of the difference between the coarse space 
      // and FTR solutions.
      // NOTE: later we want to look at the difference in some quantity 
      // of interest rather than error in global norm.
      double err_est_array[MAX_ELEM_NUM];
      elem_errors[i] = calc_err_est(NORM, space, space_ref_local, err_est_array) * 100;
      info("Elem [%d]: absolute error (est) = %g%%", i, elem_errors[i]);

      // Copy the reference element pair for element 'i'.
      // into the ref_elem_pairs[i][] array
      Iterator *I = new Iterator(space);
      Iterator *I_ref = new Iterator(space_ref_local);
      Element *e, *e_ref;
      while (1) 
      {
        e = I->next_active_element();
        e_ref = I_ref->next_active_element();
        if (e->id == i) 
        {
  	  e_ref->copy_into(ref_elem_pairs[e->id][0]);
          // coarse element 'e' was split in space.
          if (e->level != e_ref->level) 
          {
            e_ref = I_ref->next_active_element();
            e_ref->copy_into(ref_elem_pairs[e->id][1]);
          }
          break;
        }
      }

      delete I;
      delete I_ref;
      delete space_ref_local;
    }  

    // Time measurement.
    cpu_time.tick();

    // If exact solution available, also calculate exact error.
    if (EXACT_SOL_PROVIDED) 
    {
      // Calculate element errors wrt. exact solution.
      double err_exact_rel = calc_err_exact(NORM, space, exact_sol, NEQ, A, B) * 100;
     
      // Info for user.
      info("Relative error (exact) = %g %%", err_exact_rel);

      // Add entry to DOF and CPU convergence graphs.
      graph_dof_exact.add_values(Space::get_num_dofs(space), err_exact_rel);
      graph_cpu_exact.add_values(cpu_time.accumulated(), err_exact_rel);
    }

    // Calculate max FTR error.
    double max_ftr_error = 0;
    for (int i=0; i < space->get_n_active_elem(); i++) 
    {
      if (elem_errors[i] > max_ftr_error) max_ftr_error = elem_errors[i];
    }
    info("Max FTR error = %g%%.", max_ftr_error);

    // Decide whether the max. FTR error is sufficiently small.
    if(max_ftr_error < TOL_ERR_FTR) break;

    // debug
    //if (as == 4) break;

    // Returns updated coarse space with the last solution on it. 
    adapt(NORM, ADAPT_TYPE, THRESHOLD, elem_errors, space, ref_elem_pairs);

    // Plot spaces, results, and errors.
    //adapt_plotting(space, ref_elem_pairs, NORM, EXACT_SOL_PROVIDED, exact_sol);

    as++;
  }
  while (done == false);

  info("Total running time: %g s", cpu_time.accumulated());
  
  // Save convergence graphs.
  graph_dof_exact.save("conv_dof_exact.dat");
  graph_cpu_exact.save("conv_cpu_exact.dat");

  // Test variable.
  bool success = true;
  info("ndof = %d.", Space::get_num_dofs(space));
  if (Space::get_num_dofs(space) > 400) success = false;

  if (success)
  {
    info("Success!");
    return ERROR_SUCCESS;
  }
  else
  {
    info("Failure!");
    return ERROR_FAILURE;
  }
}
Esempio n. 30
0
inline Space make_space(int x1, int y1, int x2, int y2) {
    Space sp;
    sp.set(x1, x2, y1, y2);

    return sp;
}