/******************************************************************************* * 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
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; }