⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 structure.cpp

📁 来自mit的fdtd开放性源代码meep
💻 CPP
📖 第 1 页 / 共 2 页
字号:
}#endif// fallback meaneps using libctl's adaptive cubature routinevoid geom_epsilon::fallback_meaneps(double &meps, double &minveps,				    const meep::geometric_volume &gv,				    double tol, int maxeval){  number esterr;  integer errflag, n;  number xmin[3], xmax[3];  vector3 gvmin, gvmax;  gvmin = vec_to_vector3(gv.get_min_corner());  gvmax = vec_to_vector3(gv.get_max_corner());  xmin[0] = gvmin.x; xmax[0] = gvmax.x;   if (dim == meep::Dcyl) {    xmin[1] = gvmin.z; xmin[2] = gvmin.y; xmax[1] = gvmax.z; xmax[2] = gvmax.y;  }  else{    xmin[1] = gvmin.y; xmin[2] = gvmin.z; xmax[1] = gvmax.y; xmax[2] = gvmax.z;  }  if (xmin[2] == xmax[2])    n = xmin[1] == xmax[1] ? 1 : 2;  else    n = 3;  double vol = 1;  for (int i = 0; i < n; ++i) vol *= xmax[i] - xmin[i];  if (dim == meep::Dcyl) vol *= (xmin[0] + xmax[0]) * 0.5;  eps_ever_negative = 0;#ifdef CTL_HAS_COMPLEX_INTEGRATION  cnumber ret = cadaptive_integration(ceps_func, xmin, xmax, n, (void*) this,				      0, tol, maxeval, &esterr, &errflag);  meps = ret.re / vol;  minveps = ret.im / vol;#else  meps = adaptive_integration(eps_func, xmin, xmax, n, (void*) this,			      0, tol, maxeval, &esterr, &errflag) / vol;  minveps = adaptive_integration(inveps_func, xmin, xmax, n, (void*) this,				 0, tol, maxeval, &esterr, &errflag) / vol;#endif  if (eps_ever_negative) // averaging negative eps causes instability    minveps = 1.0 / (meps = eps(gv.center()));}bool geom_epsilon::has_chi3(){  for (int i = 0; i < geometry.num_items; ++i) {    if (geometry.items[i].material.which_subclass == MTS::MEDIUM) {      if (geometry.items[i].material.subclass.medium_data->chi3 != 0)	return true;     }  }    /* FIXME: what to do about material-functions?       Currently, we require that at least *one* ordinary material       property have non-zero chi3 for Kerr to be enabled.   It might       be better to have set_chi3 automatically delete chi3[] if the       chi3's are all zero. */  return (default_material.which_subclass == MTS::MEDIUM &&	  default_material.subclass.medium_data->chi3 != 0);}double geom_epsilon::chi3(const meep::vec &r) {  material_type material;  bool destroy_material = get_material_pt(material, r);    double chi3_val;  switch (material.which_subclass) {  case MTS::MEDIUM:    chi3_val = material.subclass.medium_data->chi3;    break;  default:    chi3_val = 0;  }    if (destroy_material)    material_type_destroy(material);    return chi3_val;}bool geom_epsilon::has_chi2(){  for (int i = 0; i < geometry.num_items; ++i) {    if (geometry.items[i].material.which_subclass == MTS::MEDIUM) {      if (geometry.items[i].material.subclass.medium_data->chi2 != 0)	return true;     }  }    /* FIXME: what to do about material-functions?       Currently, we require that at least *one* ordinary material       property have non-zero chi2 for Kerr to be enabled.   It might       be better to have set_chi2 automatically delete chi2[] if the       chi2's are all zero. */  return (default_material.which_subclass == MTS::MEDIUM &&	  default_material.subclass.medium_data->chi2 != 0);}double geom_epsilon::chi2(const meep::vec &r) {  material_type material;  bool destroy_material = get_material_pt(material, r);    double chi2_val;  switch (material.which_subclass) {  case MTS::MEDIUM:    chi2_val = material.subclass.medium_data->chi2;    break;  default:    chi2_val = 0;  }    if (destroy_material)    material_type_destroy(material);    return chi2_val;}bool geom_epsilon::has_mu(){  for (int i = 0; i < geometry.num_items; ++i) {    if (geometry.items[i].material.which_subclass == MTS::MEDIUM) {      if (geometry.items[i].material.subclass.medium_data->mu != 1)	return true;     }  }    /* FIXME: what to do about material-functions?       Currently, we require that at least *one* ordinary material       property have non-zero chi2 for Kerr to be enabled.   It might       be better to have set_chi2 automatically delete chi2[] if the       chi2's are all zero. */  return (default_material.which_subclass == MTS::MEDIUM &&	  default_material.subclass.medium_data->mu != 1);}double geom_epsilon::mu(const meep::vec &r) {  material_type material;  bool destroy_material = get_material_pt(material, r);  double mu_val;  switch (material.which_subclass) {  case MTS::MEDIUM:    mu_val = material.subclass.medium_data->mu;    break;  default:    mu_val = 1;  }    if (destroy_material)    material_type_destroy(material);    return mu_val;}static double get_cnd(meep::component c, const medium *m) {  switch (c) {  case meep::Dr: case meep::Dx: return m->D_conductivity_diag.x;  case meep::Dp: case meep::Dy: return m->D_conductivity_diag.y;  case meep::Dz: return m->D_conductivity_diag.z;  case meep::Br: case meep::Bx: return m->B_conductivity_diag.x;  case meep::Bp: case meep::By: return m->B_conductivity_diag.y;  case meep::Bz: return m->B_conductivity_diag.z;  default: return 0;  }}bool geom_epsilon::has_conductivity(meep::component c){  for (int i = 0; i < geometry.num_items; ++i) {    if (geometry.items[i].material.which_subclass == MTS::MEDIUM) {      if (get_cnd(c, geometry.items[i].material.subclass.medium_data) != 0)	return true;     }  }    /* FIXME: what to do about material-functions?       Currently, we require that at least *one* ordinary material       property have non-zero chi2 for Kerr to be enabled.   It might       be better to have set_chi2 automatically delete chi2[] if the       chi2's are all zero. */  return (default_material.which_subclass == MTS::MEDIUM &&	  get_cnd(c, default_material.subclass.medium_data) != 0);}double geom_epsilon::conductivity(meep::component c, const meep::vec &r) {  material_type material;  bool destroy_material = get_material_pt(material, r);  double cond_val;  switch (material.which_subclass) {  case MTS::MEDIUM:    cond_val = get_cnd(c, material.subclass.medium_data);    break;  default:    cond_val = 0;  }    if (destroy_material)    material_type_destroy(material);    return cond_val;}double geom_epsilon::sigma(const meep::vec &r) {  vector3 p = vec_to_vector3(r);  boolean inobject;  material_type material =    material_of_unshifted_point_in_tree_inobject(p, restricted_tree, &inobject);    int destroy_material = 0;  if (material.which_subclass == MTS::MATERIAL_TYPE_SELF) {    material = default_material;  }  if (material.which_subclass == MTS::MATERIAL_FUNCTION) {    material = eval_material_func(material.subclass.				  material_function_data->material_func,				  p);    destroy_material = 1;  }    double sigma = 0;  if (material.which_subclass == MTS::MEDIUM) {    polarizability_list plist =       material.subclass.medium_data->polarizations;    for (int j = 0; j < plist.num_items; ++j)      if (plist.items[j].omega == omega &&	  plist.items[j].gamma == gamma &&	  plist.items[j].delta_epsilon == deps &&	  plist.items[j].energy_saturation == energy_sat) {	sigma = plist.items[j].sigma;	break;      }  }    if (destroy_material)    material_type_destroy(material);  return sigma;}struct pol {  double omega, gamma, deps, esat;  struct pol *next;};// add a polarization to the list if it is not already therestatic pol *add_pol(pol *pols,		    double omega, double gamma, double deps, double esat){  struct pol *p = pols;  while (p && !(p->omega == omega && p->gamma == gamma		&& p->deps == deps && p->esat == esat))    p = p->next;  if (!p) {    p = new pol;    p->omega = omega;    p->gamma = gamma;    p->deps = deps;    p->esat = esat;    p->next = pols;    pols = p;  }  return pols;}static pol *add_pols(pol *pols, const polarizability_list plist) {  for (int j = 0; j < plist.num_items; ++j) {    pols = add_pol(pols,		   plist.items[j].omega, plist.items[j].gamma,		   plist.items[j].delta_epsilon,		   plist.items[j].energy_saturation);  }  return pols;}void geom_epsilon::add_polarizabilities(meep::structure *s) {  pol *pols = 0;  // construct a list of the unique polarizabilities in the geometry:  for (int i = 0; i < geometry.num_items; ++i) {    if (geometry.items[i].material.which_subclass == MTS::MEDIUM)      pols = add_pols(pols, geometry.items[i].material		      .subclass.medium_data->polarizations);  }  if (default_material.which_subclass == MTS::MEDIUM)    pols = add_pols(pols, default_material		    .subclass.medium_data->polarizations);      for (struct pol *p = pols; p; p = p->next) {    master_printf("polarizability: omega=%g, gamma=%g, deps=%g, esat=%g\n",		  p->omega, p->gamma, p->deps, p->esat);    s->add_polarizability(*this, p->omega, p->gamma, p->deps, p->esat);  }    while (pols) {    struct pol *p = pols;    pols = pols->next;    delete p;  }}/***********************************************************************/// wrapper around Scheme function for PML profilestatic double scm_pml_profile(double u, void *f_){  SCM f = (SCM) f_;  return ctl_convert_number_to_c(gh_call1(f, ctl_convert_number_to_scm(u)));}// for passing to multidimensional integration routinestatic double scm_pml_profile2(int dim, double *u, void *f_){  SCM f = (SCM) f_; (void) dim;  return ctl_convert_number_to_c(gh_call1(f, ctl_convert_number_to_scm(*u)));}meep::structure *make_structure(int dims, vector3 size, vector3 center,				double resolution, bool enable_averaging,				double subpixel_tol, int subpixel_maxeval,				bool ensure_periodicity_p,				geometric_object_list geometry,				material_type default_mat,				pml_list pml_layers,				symmetry_list symmetries,				int num_chunks, double Courant){  master_printf("-----------\nInitializing structure...\n");    // only cartesian lattices are currently allowed  geom_initialize();  geometry_center = center;    number no_size = 2.0 / ctl_get_number("infinity");  if (size.x <= no_size)    size.x = 0.0;  if (size.y <= no_size)    size.y = 0.0;  if (size.z <= no_size)    size.z = 0.0;    set_dimensions(dims);    geometry_lattice.size = size;  master_printf("Working in %s dimensions.\n", meep::dimension_name(dim));    meep::volume v;  switch (dims) {  case 0: case 1:    v = meep::vol1d(size.z, resolution);    break;  case 2:    v = meep::vol2d(size.x, size.y, resolution);    break;  case 3:    v = meep::vol3d(size.x, size.y, size.z, resolution);    break;  case CYLINDRICAL:    v = meep::volcyl(size.x, size.z, resolution);    break;  default:    CK(0, "unsupported dimensionality");  }  v.center_origin();  v.shift_origin(vector3_to_vec(center));    meep::symmetry S;  for (int i = 0; i < symmetries.num_items; ++i)     switch (symmetries.items[i].which_subclass) {    case symmetry::SYMMETRY_SELF: break; // identity    case symmetry::MIRROR_SYM:      S = S + meep::mirror(meep::direction(symmetries.items[i].direction), v)	* complex<double>(symmetries.items[i].phase.re,			  symmetries.items[i].phase.im);      break;    case symmetry::ROTATE2_SYM:      S = S + meep::rotate2(meep::direction(symmetries.items[i].direction), v)	* complex<double>(symmetries.items[i].phase.re,			  symmetries.items[i].phase.im);      break;    case symmetry::ROTATE4_SYM:      S = S + meep::rotate4(meep::direction(symmetries.items[i].direction), v)	* complex<double>(symmetries.items[i].phase.re,			  symmetries.items[i].phase.im);      break;    }  meep::boundary_region br;  for (int i = 0; i < pml_layers.num_items; ++i) {    double umin = 0, umax = 1, esterr;    int errflag;    using namespace meep;    if (pml_layers.items[i].direction == -1) {      LOOP_OVER_DIRECTIONS(v.dim, d) {	if (pml_layers.items[i].side == -1) {	  FOR_SIDES(b)	    br = br + meep::boundary_region	    (meep::boundary_region::PML,	     pml_layers.items[i].thickness,	     pow(pml_layers.items[i].R_asymptotic,		 pml_layers.items[i].strength),	     scm_pml_profile, pml_layers.items[i].pml_profile,	     adaptive_integration(scm_pml_profile2, &umin, &umax, 1,				  (void*) pml_layers.items[i].pml_profile,				  1e-9, 1e-4, 50000, &esterr, &errflag),	     d, b);	}	else	  br = br + meep::boundary_region	    (meep::boundary_region::PML,	     pml_layers.items[i].thickness,	     pow(pml_layers.items[i].R_asymptotic,		 pml_layers.items[i].strength),	     scm_pml_profile, pml_layers.items[i].pml_profile,	     adaptive_integration(scm_pml_profile2, &umin, &umax, 1,				  (void*) pml_layers.items[i].pml_profile,				  1e-9, 1e-4, 50000, &esterr, &errflag),	     d,	     (meep::boundary_side) pml_layers.items[i].side);      }    }    else {	if (pml_layers.items[i].side == -1) {	  FOR_SIDES(b)	    br = br + meep::boundary_region	    (meep::boundary_region::PML,	     pml_layers.items[i].thickness,	     pow(pml_layers.items[i].R_asymptotic,		 pml_layers.items[i].strength),	     scm_pml_profile, pml_layers.items[i].pml_profile,	     adaptive_integration(scm_pml_profile2, &umin, &umax, 1,				  (void*) pml_layers.items[i].pml_profile,				  1e-9, 1e-4, 50000, &esterr, &errflag),	     (meep::direction) pml_layers.items[i].direction,	     b);	}	else	  br = br + meep::boundary_region	    (meep::boundary_region::PML,	     pml_layers.items[i].thickness,	     pow(pml_layers.items[i].R_asymptotic,		 pml_layers.items[i].strength),	     scm_pml_profile, pml_layers.items[i].pml_profile,	     adaptive_integration(scm_pml_profile2, &umin, &umax, 1,				  (void*) pml_layers.items[i].pml_profile,				  1e-9, 1e-4, 50000, &esterr, &errflag),	     (meep::direction) pml_layers.items[i].direction,	     (meep::boundary_side) pml_layers.items[i].side);    }  }    ensure_periodicity = ensure_periodicity_p;  default_material = default_mat;  geom_epsilon geps(geometry, v.pad().surroundings());  if (subpixel_maxeval < 0) subpixel_maxeval = 0; // no limit  meep::structure *s = new meep::structure(v, geps, br, S, 					   num_chunks, Courant,					   enable_averaging,					   subpixel_tol,					   subpixel_maxeval);  geps.add_polarizabilities(s);  master_printf("-----------\n");    return s;}/*************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -