void
SpongeLayerForceFunction::setDataOnPatchCell(Pointer<CellData<NDIM, double> > F_data,
                                             Pointer<CellData<NDIM, double> > U_current_data,
                                             Pointer<CellData<NDIM, double> > U_new_data,
                                             const double kappa,
                                             Pointer<Patch<NDIM> > patch)
{
#if !defined(NDEBUG)
    TBOX_ASSERT(F_data && U_current_data);
#endif
    const int cycle_num = d_fluid_solver->getCurrentCycleNumber();
    const Box<NDIM>& patch_box = patch->getBox();
    Pointer<CartesianPatchGeometry<NDIM> > pgeom = patch->getPatchGeometry();
    const double* const dx = pgeom->getDx();
    const double* const x_lower = pgeom->getXLower();
    const double* const x_upper = pgeom->getXUpper();
    const IntVector<NDIM>& ratio = pgeom->getRatio();
    const Box<NDIM> domain_box =
        Box<NDIM>::refine(d_grid_geometry->getPhysicalDomain()[0], ratio);
    for (unsigned int location_index = 0; location_index < 2 * NDIM; ++location_index)
    {
        const unsigned int axis = location_index / 2;
        const unsigned int side = location_index % 2;
        const bool is_lower = side == 0;
        for (unsigned int d = 0; d < NDIM; ++d)
        {
            if (d_forcing_enabled[location_index][d] &&
                pgeom->getTouchesRegularBoundary(axis, side))
            {
                Box<NDIM> bdry_box = domain_box;
                const int offset = static_cast<int>(d_width[location_index] / dx[axis]);
                if (is_lower)
                {
                    bdry_box.upper(axis) = domain_box.lower(axis) + offset;
                }
                else
                {
                    bdry_box.lower(axis) = domain_box.upper(axis) - offset;
                }
                for (Box<NDIM>::Iterator b(bdry_box * patch_box); b; b++)
                {
                    const Index<NDIM>& i = b();
                    const double U_current = U_current_data ? (*U_current_data)(i, d) : 0.0;
                    const double U_new = U_new_data ? (*U_new_data)(i, d) : 0.0;
                    const double U = (cycle_num > 0) ? 0.5 * (U_new + U_current) : U_current;
                    const double x =
                        x_lower[axis] +
                        dx[axis] *
                            (static_cast<double>(i(axis) - patch_box.lower(axis)) + 0.5);
                    const double x_bdry = (is_lower ? x_lower[axis] : x_upper[axis]);
                    (*F_data)(i, d) = smooth_kernel((x - x_bdry) / d_width[location_index]) *
                                      kappa * (0.0 - U);
                }
            }
        }
    }
    return;
} // setDataOnPatchCell
void
StaggeredStokesOpenBoundaryStabilizer::setDataOnPatch(const int data_idx,
                                                      Pointer<Variable<NDIM> > /*var*/,
                                                      Pointer<Patch<NDIM> > patch,
                                                      const double /*data_time*/,
                                                      const bool initial_time,
                                                      Pointer<PatchLevel<NDIM> > /*level*/)
{
    Pointer<SideData<NDIM, double> > F_data = patch->getPatchData(data_idx);
#if !defined(NDEBUG)
    TBOX_ASSERT(F_data);
#endif
    F_data->fillAll(0.0);
    if (initial_time) return;
    const int cycle_num = d_fluid_solver->getCurrentCycleNumber();
    const double dt = d_fluid_solver->getCurrentTimeStepSize();
    const double rho = d_fluid_solver->getStokesSpecifications()->getRho();
    const double kappa = cycle_num >= 0 ? 0.5 * rho / dt : 0.0;
    Pointer<SideData<NDIM, double> > U_current_data =
        patch->getPatchData(d_fluid_solver->getVelocityVariable(), d_fluid_solver->getCurrentContext());
    Pointer<SideData<NDIM, double> > U_new_data =
        patch->getPatchData(d_fluid_solver->getVelocityVariable(), d_fluid_solver->getNewContext());
#if !defined(NDEBUG)
    TBOX_ASSERT(U_current_data);
#endif
    const Box<NDIM>& patch_box = patch->getBox();
    Pointer<CartesianPatchGeometry<NDIM> > pgeom = patch->getPatchGeometry();
    const double* const dx = pgeom->getDx();
    const double* const x_lower = pgeom->getXLower();
    const double* const x_upper = pgeom->getXUpper();
    const IntVector<NDIM>& ratio = pgeom->getRatio();
    const Box<NDIM> domain_box = Box<NDIM>::refine(d_grid_geometry->getPhysicalDomain()[0], ratio);
    for (unsigned int location_index = 0; location_index < 2 * NDIM; ++location_index)
    {
        const unsigned int axis = location_index / 2;
        const unsigned int side = location_index % 2;
        const bool is_lower = side == 0;
        if (d_open_bdry[location_index] && pgeom->getTouchesRegularBoundary(axis, side))
        {
            Box<NDIM> bdry_box = domain_box;
            const int offset = static_cast<int>(d_width[location_index] / dx[axis]);
            if (is_lower)
            {
                bdry_box.upper(axis) = domain_box.lower(axis) + offset;
            }
            else
            {
                bdry_box.lower(axis) = domain_box.upper(axis) - offset;
            }
            for (Box<NDIM>::Iterator b(SideGeometry<NDIM>::toSideBox(bdry_box * patch_box, axis)); b; b++)
            {
                const Index<NDIM>& i = b();
                const SideIndex<NDIM> i_s(i, axis, SideIndex<NDIM>::Lower);
                const double U_current = U_current_data ? (*U_current_data)(i_s) : 0.0;
                const double U_new = U_new_data ? (*U_new_data)(i_s) : 0.0;
                const double U = (cycle_num > 0) ? 0.5 * (U_new + U_current) : U_current;
                const double n = is_lower ? -1.0 : +1.0;
                if ((d_inflow_bdry[location_index] && U * n > 0.0) || (d_outflow_bdry[location_index] && U * n < 0.0))
                {
                    const double x = x_lower[axis] + dx[axis] * static_cast<double>(i(axis) - patch_box.lower(axis));
                    const double x_bdry = (is_lower ? x_lower[axis] : x_upper[axis]);
                    (*F_data)(i_s) = smooth_kernel((x - x_bdry) / d_width[location_index]) * kappa * (0.0 - U);
                }
            }
        }
    }
    return;
} // setDataOnPatch
示例#3
0
int 
main( int argc, char* argv[]) 
{

	// read in observations 


	// read in starting model


	// read in frequency group and iteration number 


	// set up acquisition 
	gen_acquisition(srcx,srcy,srcz,recx,recy,recz);

	// loop over frequency 
	for (int iw=0; iw<nw; iw++ ) { 
		freq=ow+iw*dw; // frequency 

		// loop over cg iterations
		for (int iter=0; iter< niter; iter++ ) {

			// helm solver forward 
			helm_solver(model,freq,solution,adjoint);

			// generate adjoint sources and misfits 
			gen_adjsrc(solution,obs,adjreal,adjimag,misfit,recx,recy,recz,nx,ny,nz,nsrc,nrec);

			// helm solver adjoint 
			helm_solver(model,freq,adjreal,adjimag,kernel,adjoint);

			// smooth kernel 
			smooth_kernel(kernel,kernel_smooth,nx,ny,nz,sigma2); 

			curker=kernel_smooth;

			// calculate direction 
			if ( iter ==0 ) {
				calc_gradient_sd(curker,curdir,nx,ny,nz);
			else 
				calc_gradient_cg(curker,preker,predir,curdir,nx,ny,nz); 
			}

			// line search
			misfit0=misfit;
			for (istep=0, step=1.0; istep < nstep; istep++, step*=0.5) {
			
				update_model(model,curdir,model_test,step,nx,ny,nz); 
				
				// helm solver forward
				helm_solver(model_test,freq,solution,adjoint);

				// calc misfit value 
				gen_adjsrc(solution,obs,adjreal,adjimag,misfit1,recx,recy,recz,nx,ny,nz,nsrc,nrec);
				if (misfit1>misfit0) { 
					alpha=step;	
					break;
				}
				misfit0=misfit1;
			}	

			// model update 
			update_model(model,curdir,model_new,alpha,nx,ny,nz);
			preker=curker;
			predir=curdir;
			model=model_new;

		}