Example #1
0
/*******************************************************************************
 * For each run, the input filename must be given on the command line.  In all *
 * cases, the command line is:                                                 *
 *                                                                             *
 *    executable <input file name>                                             *
 *                                                                             *
 *******************************************************************************/
int
main(int argc, char* argv[])
{
    // Initialize PETSc, MPI, and SAMRAI.
    PetscInitialize(&argc, &argv, NULL, NULL);
    SAMRAI_MPI::setCommunicator(PETSC_COMM_WORLD);
    SAMRAI_MPI::setCallAbortInSerialInsteadOfExit();
    SAMRAIManager::startup();

    { // cleanup dynamically allocated objects prior to shutdown

        // Parse command line options, set some standard options from the input
        // file, and enable file logging.
        Pointer<AppInitializer> app_initializer = new AppInitializer(argc, argv, "sc_poisson.log");
        Pointer<Database> input_db = app_initializer->getInputDatabase();

        // Create major algorithm and data objects that comprise the
        // application.  These objects are configured from the input database.
        Pointer<CartesianGridGeometry<NDIM> > grid_geometry = new CartesianGridGeometry<NDIM>(
            "CartesianGeometry", app_initializer->getComponentDatabase("CartesianGeometry"));
        Pointer<PatchHierarchy<NDIM> > patch_hierarchy = new PatchHierarchy<NDIM>("PatchHierarchy", grid_geometry);
        Pointer<StandardTagAndInitialize<NDIM> > error_detector = new StandardTagAndInitialize<NDIM>(
            "StandardTagAndInitialize", NULL, app_initializer->getComponentDatabase("StandardTagAndInitialize"));
        Pointer<BergerRigoutsos<NDIM> > box_generator = new BergerRigoutsos<NDIM>();
        Pointer<LoadBalancer<NDIM> > load_balancer =
            new LoadBalancer<NDIM>("LoadBalancer", app_initializer->getComponentDatabase("LoadBalancer"));
        Pointer<GriddingAlgorithm<NDIM> > gridding_algorithm =
            new GriddingAlgorithm<NDIM>("GriddingAlgorithm",
                                        app_initializer->getComponentDatabase("GriddingAlgorithm"),
                                        error_detector,
                                        box_generator,
                                        load_balancer);

        // Create variables and register them with the variable database.
        VariableDatabase<NDIM>* var_db = VariableDatabase<NDIM>::getDatabase();
        Pointer<VariableContext> ctx = var_db->getContext("context");

        Pointer<SideVariable<NDIM, double> > u_sc_var = new SideVariable<NDIM, double>("u_sc");
        Pointer<SideVariable<NDIM, double> > f_sc_var = new SideVariable<NDIM, double>("f_sc");
        Pointer<SideVariable<NDIM, double> > e_sc_var = new SideVariable<NDIM, double>("e_sc");
        Pointer<SideVariable<NDIM, double> > r_sc_var = new SideVariable<NDIM, double>("r_sc");

        const int u_sc_idx = var_db->registerVariableAndContext(u_sc_var, ctx, IntVector<NDIM>(1));
        const int f_sc_idx = var_db->registerVariableAndContext(f_sc_var, ctx, IntVector<NDIM>(1));
        const int e_sc_idx = var_db->registerVariableAndContext(e_sc_var, ctx, IntVector<NDIM>(1));
        const int r_sc_idx = var_db->registerVariableAndContext(r_sc_var, ctx, IntVector<NDIM>(1));

        Pointer<CellVariable<NDIM, double> > u_cc_var = new CellVariable<NDIM, double>("u_cc", NDIM);
        Pointer<CellVariable<NDIM, double> > f_cc_var = new CellVariable<NDIM, double>("f_cc", NDIM);
        Pointer<CellVariable<NDIM, double> > e_cc_var = new CellVariable<NDIM, double>("e_cc", NDIM);
        Pointer<CellVariable<NDIM, double> > r_cc_var = new CellVariable<NDIM, double>("r_cc", NDIM);

        const int u_cc_idx = var_db->registerVariableAndContext(u_cc_var, ctx, IntVector<NDIM>(0));
        const int f_cc_idx = var_db->registerVariableAndContext(f_cc_var, ctx, IntVector<NDIM>(0));
        const int e_cc_idx = var_db->registerVariableAndContext(e_cc_var, ctx, IntVector<NDIM>(0));
        const int r_cc_idx = var_db->registerVariableAndContext(r_cc_var, ctx, IntVector<NDIM>(0));

        // Register variables for plotting.
        Pointer<VisItDataWriter<NDIM> > visit_data_writer = app_initializer->getVisItDataWriter();
        TBOX_ASSERT(visit_data_writer);

        visit_data_writer->registerPlotQuantity(u_cc_var->getName(), "VECTOR", u_cc_idx);
        for (unsigned int d = 0; d < NDIM; ++d)
        {
            ostringstream stream;
            stream << d;
            visit_data_writer->registerPlotQuantity(u_cc_var->getName() + stream.str(), "SCALAR", u_cc_idx, d);
        }

        visit_data_writer->registerPlotQuantity(f_cc_var->getName(), "VECTOR", f_cc_idx);
        for (unsigned int d = 0; d < NDIM; ++d)
        {
            ostringstream stream;
            stream << d;
            visit_data_writer->registerPlotQuantity(f_cc_var->getName() + stream.str(), "SCALAR", f_cc_idx, d);
        }

        visit_data_writer->registerPlotQuantity(e_cc_var->getName(), "VECTOR", e_cc_idx);
        for (unsigned int d = 0; d < NDIM; ++d)
        {
            ostringstream stream;
            stream << d;
            visit_data_writer->registerPlotQuantity(e_cc_var->getName() + stream.str(), "SCALAR", e_cc_idx, d);
        }

        visit_data_writer->registerPlotQuantity(r_cc_var->getName(), "VECTOR", r_cc_idx);
        for (unsigned int d = 0; d < NDIM; ++d)
        {
            ostringstream stream;
            stream << d;
            visit_data_writer->registerPlotQuantity(r_cc_var->getName() + stream.str(), "SCALAR", r_cc_idx, d);
        }

        // Initialize the AMR patch hierarchy.
        gridding_algorithm->makeCoarsestLevel(patch_hierarchy, 0.0);
        int tag_buffer = 1;
        int level_number = 0;
        bool done = false;
        while (!done && (gridding_algorithm->levelCanBeRefined(level_number)))
        {
            gridding_algorithm->makeFinerLevel(patch_hierarchy, 0.0, 0.0, tag_buffer);
            done = !patch_hierarchy->finerLevelExists(level_number);
            ++level_number;
        }

        // Allocate data on each level of the patch hierarchy.
        for (int ln = 0; ln <= patch_hierarchy->getFinestLevelNumber(); ++ln)
        {
            Pointer<PatchLevel<NDIM> > level = patch_hierarchy->getPatchLevel(ln);
            level->allocatePatchData(u_sc_idx, 0.0);
            level->allocatePatchData(f_sc_idx, 0.0);
            level->allocatePatchData(e_sc_idx, 0.0);
            level->allocatePatchData(r_sc_idx, 0.0);
            level->allocatePatchData(u_cc_idx, 0.0);
            level->allocatePatchData(f_cc_idx, 0.0);
            level->allocatePatchData(e_cc_idx, 0.0);
            level->allocatePatchData(r_cc_idx, 0.0);
        }

        // Setup vector objects.
        HierarchyMathOps hier_math_ops("hier_math_ops", patch_hierarchy);
        const int h_sc_idx = hier_math_ops.getSideWeightPatchDescriptorIndex();

        SAMRAIVectorReal<NDIM, double> u_vec("u", patch_hierarchy, 0, patch_hierarchy->getFinestLevelNumber());
        SAMRAIVectorReal<NDIM, double> f_vec("f", patch_hierarchy, 0, patch_hierarchy->getFinestLevelNumber());
        SAMRAIVectorReal<NDIM, double> e_vec("e", patch_hierarchy, 0, patch_hierarchy->getFinestLevelNumber());
        SAMRAIVectorReal<NDIM, double> r_vec("r", patch_hierarchy, 0, patch_hierarchy->getFinestLevelNumber());

        u_vec.addComponent(u_sc_var, u_sc_idx, h_sc_idx);
        f_vec.addComponent(f_sc_var, f_sc_idx, h_sc_idx);
        e_vec.addComponent(e_sc_var, e_sc_idx, h_sc_idx);
        r_vec.addComponent(r_sc_var, r_sc_idx, h_sc_idx);

        u_vec.setToScalar(0.0);
        f_vec.setToScalar(0.0);
        e_vec.setToScalar(0.0);
        r_vec.setToScalar(0.0);

        // Setup exact solutions.
        muParserCartGridFunction u_fcn("u", app_initializer->getComponentDatabase("u"), grid_geometry);
        muParserCartGridFunction f_fcn("f", app_initializer->getComponentDatabase("f"), grid_geometry);

        u_fcn.setDataOnPatchHierarchy(e_sc_idx, e_sc_var, patch_hierarchy, 0.0);
        f_fcn.setDataOnPatchHierarchy(f_sc_idx, f_sc_var, patch_hierarchy, 0.0);

        // Setup the Poisson solver.
        PoissonSpecifications poisson_spec("poisson_spec");
        poisson_spec.setCConstant(0.0);
        poisson_spec.setDConstant(-1.0);
        vector<RobinBcCoefStrategy<NDIM>*> bc_coefs(NDIM, static_cast<RobinBcCoefStrategy<NDIM>*>(NULL));
        SCLaplaceOperator laplace_op("laplace_op");
        laplace_op.setPoissonSpecifications(poisson_spec);
        laplace_op.setPhysicalBcCoefs(bc_coefs);
        laplace_op.initializeOperatorState(u_vec, f_vec);

        string solver_type = input_db->getString("solver_type");
        Pointer<Database> solver_db = input_db->getDatabase("solver_db");
        string precond_type = input_db->getString("precond_type");
        Pointer<Database> precond_db = input_db->getDatabase("precond_db");
        Pointer<PoissonSolver> poisson_solver = SCPoissonSolverManager::getManager()->allocateSolver(
            solver_type, "poisson_solver", solver_db, "", precond_type, "poisson_precond", precond_db, "");
        poisson_solver->setPoissonSpecifications(poisson_spec);
        poisson_solver->setPhysicalBcCoefs(bc_coefs);
        poisson_solver->initializeSolverState(u_vec, f_vec);

        // Solve -L*u = f.
        u_vec.setToScalar(0.0);
        poisson_solver->solveSystem(u_vec, f_vec);

        // Compute error and print error norms.
        e_vec.subtract(Pointer<SAMRAIVectorReal<NDIM, double> >(&e_vec, false),
                       Pointer<SAMRAIVectorReal<NDIM, double> >(&u_vec, false));
        pout << "|e|_oo = " << e_vec.maxNorm() << "\n";
        pout << "|e|_2  = " << e_vec.L2Norm() << "\n";
        pout << "|e|_1  = " << e_vec.L1Norm() << "\n";

        // Compute the residual and print residual norms.
        laplace_op.apply(u_vec, r_vec);
        r_vec.subtract(Pointer<SAMRAIVectorReal<NDIM, double> >(&f_vec, false),
                       Pointer<SAMRAIVectorReal<NDIM, double> >(&r_vec, false));
        pout << "|r|_oo = " << r_vec.maxNorm() << "\n";
        pout << "|r|_2  = " << r_vec.L2Norm() << "\n";
        pout << "|r|_1  = " << r_vec.L1Norm() << "\n";

        // Interpolate the side-centered data to cell centers for output.
        static const bool synch_cf_interface = true;
        hier_math_ops.interp(u_cc_idx, u_cc_var, u_sc_idx, u_sc_var, NULL, 0.0, synch_cf_interface);
        hier_math_ops.interp(f_cc_idx, f_cc_var, f_sc_idx, f_sc_var, NULL, 0.0, synch_cf_interface);
        hier_math_ops.interp(e_cc_idx, e_cc_var, e_sc_idx, e_sc_var, NULL, 0.0, synch_cf_interface);
        hier_math_ops.interp(r_cc_idx, r_cc_var, r_sc_idx, r_sc_var, NULL, 0.0, synch_cf_interface);

        // Set invalid values on coarse levels (i.e., coarse-grid values that
        // are covered by finer grid patches) to equal zero.
        for (int ln = 0; ln <= patch_hierarchy->getFinestLevelNumber() - 1; ++ln)
        {
            Pointer<PatchLevel<NDIM> > level = patch_hierarchy->getPatchLevel(ln);
            BoxArray<NDIM> refined_region_boxes;
            Pointer<PatchLevel<NDIM> > next_finer_level = patch_hierarchy->getPatchLevel(ln + 1);
            refined_region_boxes = next_finer_level->getBoxes();
            refined_region_boxes.coarsen(next_finer_level->getRatioToCoarserLevel());
            for (PatchLevel<NDIM>::Iterator p(level); p; p++)
            {
                Pointer<Patch<NDIM> > patch = level->getPatch(p());
                const Box<NDIM>& patch_box = patch->getBox();
                Pointer<CellData<NDIM, double> > e_cc_data = patch->getPatchData(e_cc_idx);
                Pointer<CellData<NDIM, double> > r_cc_data = patch->getPatchData(r_cc_idx);
                for (int i = 0; i < refined_region_boxes.getNumberOfBoxes(); ++i)
                {
                    const Box<NDIM> refined_box = refined_region_boxes[i];
                    const Box<NDIM> intersection = Box<NDIM>::grow(patch_box, 1) * refined_box;
                    if (!intersection.empty())
                    {
                        e_cc_data->fillAll(0.0, intersection);
                        r_cc_data->fillAll(0.0, intersection);
                    }
                }
            }
        }

        // Output data for plotting.
        visit_data_writer->writePlotData(patch_hierarchy, 0, 0.0);

    } // cleanup dynamically allocated objects prior to shutdown

    SAMRAIManager::shutdown();
    PetscFinalize();
    return 0;
} // main
Example #2
0
DISMOD4_BEGIN_NAMESPACE
/*!
\file fg_info_eval_r.cpp
Implementation of the \ref FG_info member function \ref FG_info::eval_r().
*/


/*!
\def DISMOD4_FG_INFO_EVAL_R_TRACE
Should the fg_info_eval_r print its retun fg vector each time it is called
(1 for yes and 0 for no).
*/
# define DISMOD4_FG_INFO_EVAL_R_TRACE 0

// ------------------------------------------------------------------------
/*!
This function is effectively const, but it needs to be the virtual
replacement for a non-const function.

\param [out] fg
The input elements of this vector does not matter, but it must 
have the correct size. Upon retunrn it is [ f(x), g(x) ]; i.e.,
the objective followed by the constraints.

\param [in] x
is a vector containing the state followed by values for the
Laplace distributed measurements.
*/

void FG_info::operator()(ADvector& fg, const ADvector&  x)
{	// temporaries
	size_t i, j, k, ell, q, i_grid, i_grid_p;

	// number of grid points
	const size_t n_grid       = grid_.size();
	// number of components in the state vector
	const size_t n_state      = n_grid * n_stochastic_;
	// number of measurements
	const size_t n_measure    = measure_in_.size();

	// check arguments
	assert( x.size() == n_state + n_auxillary_ + n_effect_ );
	assert( fg.size() ==  1 + n_equality_ + n_inequality_  );

	// split x into state, auxillary variables, and covariate multipliers
	ADvector state( n_state );
	ADvector aux( n_auxillary_ );
	ADvector beta( n_effect_ );
	for(i = 0; i < n_state; i++)
	{
# if DISMOD4_RESCALE_SFUN_OPT
		state[i] = exp( x[i] ) - sfun_in_[i].optimize_zeta;
# else
		state[i] = x[i];
# endif
	}
	for(i = 0; i < n_auxillary_; i++)
		aux[i] = x[n_state + i];
	for(i = 0; i < n_effect_; i++)
		beta[i] = x[n_state + n_auxillary_ + i];

	// declare the return vector

	// initialize summation for objective function f(x)
	ADdouble sum = 0.;

	/*
	now compute the objective f(x) and the constraints g(x)
	*/
	size_t aux_index = 0;
	size_t g_index   = 0;
	ADdouble res     = 0.;
	double   sigma   = 0.;
	bool     valid   = false;
	ADvector r_vec(n_stochastic_);
	for(i_grid = 0; i_grid < n_grid; i_grid++)
	{	grid_.unpack(j, k, i_grid);
		size_t jp = j+1;
		// first direct prior residuals for this grid point
		for(q = 0; q < n_stochastic_; q++)
		{	i     = i_grid * n_stochastic_ + q;
			sigma = sfun_in_[i].prior_sigma;
			res   = prior_scaled(
				j, k, Stochastic_Enum(q), state
			);
			if( sigma == infinity_ )
				;
			else if( sigma == 0. )
			{	assert( g_lower_[g_index] == 0. );
				assert( g_upper_[g_index] == 0. );
				// scale factor to better ensure constraints
				fg[++g_index] = res;
			}
			else	switch( sfun_in_[i].prior_like )
			{
				// f(x) = f(x) + res * res / 2
				case gaussian_enum:
				sum = sum + res * res / 2.;
				break;

				// f(x) = f(x) + aux[aux_index]
				// aux[aux_index] >= + sqrt(2) * res
				// aux[aux_index] >= - sqrt(2) * res
				case laplace_enum:
				sum = sum + aux[aux_index];
				//
				assert( g_lower_[g_index] == 0. );
				assert( g_upper_[g_index] == infinity_ );
				fg[++g_index] = aux[aux_index] - sqrt(2.) * res;
				//
				assert( g_lower_[g_index] == 0. );
				assert( g_upper_[g_index] == infinity_ );
				fg[++g_index] = aux[aux_index] + sqrt(2.) * res;
				//
				aux_index++;
				break;

				default:
				assert(false);
			}
		}
		valid = grid_.pack(jp, k, i_grid_p);
		if( valid )
		{	// second comes age residuals for this grid point
			r_vec = age_scaled(j, k, state);
			for(q = 0; q < n_stochastic_; q++)
			{	i     = i_grid * n_stochastic_ + q;
				sigma = sfun_in_[i].age_sigma;
				res   = r_vec[q];
				if( sfun_in_[i].age_order == 2 )
					valid = grid_.pack(jp+1, k, i_grid_p);
				else	valid = true;
				if( ! valid | (sigma == infinity_) )
					;
				else if( sigma == 0. )
				{	assert( g_lower_[g_index] == 0. );
					assert( g_upper_[g_index] == 0. );
					// scale factor to better ensure constraints
					fg[++g_index] = res;
				}
				else	switch( sfun_in_[i].age_like )
				{	// f(x) = f(x) + res * res / 2
					case gaussian_enum:
					sum = sum + res * res / 2.;
					break;

					// f(x) = f(x) + aux[aux_index]
					// aux[aux_index] >= + sqrt(2) * res
					// aux[aux_index] >= - sqrt(2) * res
					case laplace_enum:
					sum = sum + aux[aux_index];
					//
					assert( g_lower_[g_index] == 0. );
					assert( g_upper_[g_index] == infinity_ );
					fg[++g_index] = aux[aux_index] - sqrt(2.) * res;
					//
					assert( g_lower_[g_index] == 0. );
					assert( g_upper_[g_index] == infinity_ );
					fg[++g_index] = aux[aux_index] + sqrt(2.) * res;
					//
					aux_index++;
					break;

					default:
					assert(false);
				}
			}
		}
		valid = grid_.pack(j, k+1, i_grid_p);
		if( valid )
		{	// third comes cohort residuals for this grid point
			for(q = 0; q < n_stochastic_; q++)
			{	i     = i_grid * n_stochastic_ + q;
				sigma = sfun_in_[i].cohort_sigma;
				if( sfun_in_[i].cohort_order == 2 )
					valid = grid_.pack(j, k+2, i_grid_p);
				else	valid = true;
				if( ! valid | (sigma == infinity_) )
					;
				else
				{	res   = cohort_scaled(
						j, k, Stochastic_Enum(q), state
					);
					if( sigma == 0. )
					{	assert( g_lower_[g_index] == 0. );
						assert( g_upper_[g_index] == 0. );
						// scale factor to better ensure constraints
						fg[++g_index] = res;
					}
					else	switch(sfun_in_[i].cohort_like)
					{	// f(x) = f(x) + res * res / 2
						case gaussian_enum:
						sum = sum + res * res / 2.;
						break;

						// f(x) = f(x) + aux[aux_index]
						// aux[aux_index] >= + sqrt(2) * res
						// aux[aux_index] >= - sqrt(2) * res
						case laplace_enum:
						sum = sum + aux[aux_index];
						//
						assert( g_lower_[g_index] == 0. );
						assert( g_upper_[g_index] == infinity_ );
						fg[++g_index] = aux[aux_index] - sqrt(2.) * res;
						//
						assert( g_lower_[g_index] == 0. );
						assert( g_upper_[g_index] == infinity_ );
						fg[++g_index] = aux[aux_index] + sqrt(2.) * res;
						//
						aux_index++;
						break;

						default:
						assert(false);
					}
				}
			}
		} 
		valid  = true;
		valid &= grid_.pack(j,   k+1,  i_grid_p);
		valid &= grid_.pack(j+1,   k,  i_grid_p);
		valid &= grid_.pack(j+1,  k+1, i_grid_p);
		if( valid )
		{	// fourth comes cross residuals for this grid point
			for(q = 0; q < n_stochastic_; q++)
			{	i     = i_grid * n_stochastic_ + q;
				sigma = sfun_in_[i].cross_sigma;

				if( ! valid | (sigma == infinity_) )
					;
				else
				{	res = cross_scaled(
						j, k, Stochastic_Enum(q), state
					);
				 	if( sigma == 0. )
					{	assert( g_lower_[g_index] == 0. );
						assert( g_upper_[g_index] == 0. );
						fg[++g_index] = res;
					}
					else	switch( sfun_in_[i].cross_like )
					{	// f(x) = f(x) + res * res / 2
						case gaussian_enum:
						sum = sum + res * res / 2.;
						break;

						// f(x) = f(x) + aux[aux_index]
						// aux[aux_index] >= + sqrt(2) * res
						// aux[aux_index] >= - sqrt(2) * res
						case laplace_enum:
						sum = sum + aux[aux_index];
						//
						assert( g_lower_[g_index] == 0. );
						assert( g_upper_[g_index] == infinity_ );
						fg[++g_index] = aux[aux_index] - sqrt(2.) * res;
						//
						assert( g_lower_[g_index] == 0. );
						assert( g_upper_[g_index] == infinity_ );
						fg[++g_index] = aux[aux_index] + sqrt(2.) * res;
						//
						aux_index++;
						break;

						default:
						assert(false);
					}
				}
			}
		}
	} // end loop over grid residuals
	// last come the measurements residuals
	for(ell = 0; ell < n_measure; ell++)
	{	res = measure_scaled(ell, state, beta);
		if( measure_in_[ell].meas_sigma == infinity_ )
			;
		else if( measure_in_[ell].meas_sigma == 0. )
		{	assert( g_lower_[g_index] == 0. );
			assert( g_upper_[g_index] == 0. );
			// scale factor to better ensure constraints
			fg[++g_index] = res;
		}
		else	switch( measure_in_[ell].meas_like )
		{	// f(x) = f(x) + res * res / 2
			case gaussian_enum:
			sum = sum + res * res / 2.;
			break;

			// f(x) = f(x) + aux[aux_index]
			// aux[aux_index] >= + sqrt(2) * res
			// aux[aux_index] >= - sqrt(2) * res
			case laplace_enum:
			sum = sum + aux[aux_index];
			//
			assert( g_lower_[g_index] == 0. );
			assert( g_upper_[g_index] == infinity_ );
			fg[++g_index] = aux[aux_index] - sqrt(2.) * res;
			//
			assert( g_lower_[g_index] == 0. );
			assert( g_upper_[g_index] == infinity_ );
			fg[++g_index] = aux[aux_index] + sqrt(2.) * res;
			//
			aux_index++;
			break;

			default:
			assert(false);
		}
	}
	assert( g_index == n_equality_ + n_inequality_ );
	assert( aux_index == n_auxillary_ );
	fg[0] = sum;

	DISMOD4_ASSERT_MSG(
		! CppAD::hasnan(fg) ,
		"fg_info_eval_r: objective or constraint is not a number"
	);
# if DISMOD4_FG_INFO_EVAL_R_TRACE
	for(i = 0; i < fg.size(); i++)
		std::cout << "fg[" << i << "] = " << fg[i] << std::endl;
# else
# endif
	return;
}