//====================================================================== // Function: get_parents // Description: return entities attached to this edge // Author: sjowen // Date: 4/01 //====================================================================== void CubitFacetEdge::get_parents(DLIList<FacetEntity *> &facet_list) { DLIList<CubitFacet *> cf_list; facets( cf_list ); for (int ii=0; ii<cf_list.size(); ii++) facet_list.append(cf_list.get_and_step()); }
long create_odd_mapping(DeviceType const & device, SHEQuantity & quan, viennashe::config const & conf, long unknown_offset = 0) //nonzero value if e.g. the potential is also considered within Newton iteration { typedef typename DeviceType::mesh_type MeshType; typedef typename viennagrid::result_of::const_facet_range<MeshType>::type FacetContainer; typedef typename viennagrid::result_of::iterator<FacetContainer>::type FacetIterator; MeshType const & mesh = device.mesh(); FacetContainer facets(mesh); long unknown_index = unknown_offset; for (std::size_t index_H = 0; index_H < quan.get_value_H_size(); ++index_H) { for (FacetIterator fit = facets.begin(); fit != facets.end(); ++fit) { detail::map_facet(device, quan, conf, *fit, index_H, unknown_index); } } return unknown_index; }
void PST_Edge::make_facets( GMem& gmem, double tolerance, DLIList<PST_Edge*>& edge_list ) { assert(gmem.fListCount % 4 == 0); std::vector<double> points(gmem.pointListCount*3); std::vector<int> facets(gmem.fListCount*3/4); int i; GPoint* pitor = gmem.point_list(); std::vector<double>::iterator ditor = points.begin(); for ( i = gmem.pointListCount; i--; ) { *ditor++ = pitor->x; *ditor++ = pitor->y; *ditor++ = pitor->z; pitor++; } int* fitor = gmem.facet_list(); std::vector<int>::iterator iitor = facets.begin(); for ( i = 0; i < gmem.fListCount; i += 4 ) { assert( *fitor++ == 3 ); *iitor++ = *fitor++; *iitor++ = *fitor++; *iitor++ = *fitor++; } make_facets( points, facets, tolerance, edge_list ); }
void setup(SegmentT const & segment, StorageType & storage) { typedef typename SegmentT::config_type config_type; typedef viennamath::equation equ_type; typedef viennamath::expr expr_type; typedef typename expr_type::numeric_type numeric_type; typedef typename viennagrid::result_of::cell_tag<SegmentT>::type CellTag; typedef typename viennagrid::result_of::facet_tag<CellTag>::type FacetTag; typedef typename viennagrid::result_of::point<SegmentT>::type PointType; typedef typename viennagrid::result_of::element<SegmentT, FacetTag>::type FacetType; typedef typename viennagrid::result_of::element<SegmentT, CellTag >::type CellType; typedef typename viennagrid::result_of::const_element_range<SegmentT, FacetTag>::type FacetContainer; typedef typename viennagrid::result_of::iterator<FacetContainer>::type FacetIterator; typedef typename viennagrid::result_of::const_coboundary_range<SegmentT, FacetType, CellTag>::type CellOnFacetRange; // typedef typename viennagrid::result_of::const_element_range<FacetType, CellTag>::type CellOnFacetRange; typedef typename viennagrid::result_of::iterator<CellOnFacetRange>::type CellOnFacetIterator; typename viennadata::result_of::accessor<StorageType, viennafvm::facet_area_key, double, FacetType>::type facet_area_accessor = viennadata::make_accessor(storage, viennafvm::facet_area_key()); typename viennadata::result_of::accessor<StorageType, viennafvm::facet_distance_key, double, FacetType>::type facet_distance_accessor = viennadata::make_accessor(storage, viennafvm::facet_distance_key()); FacetContainer facets(segment); for (FacetIterator fit = facets.begin(); fit != facets.end(); ++fit) { CellOnFacetRange cells = viennagrid::coboundary_elements<FacetType, CellTag>(segment, fit.handle()); if (cells.size() == 2) { CellOnFacetIterator cofit = cells.begin(); PointType centroid_1 = viennagrid::centroid(*cofit); ++cofit; PointType centroid_2 = viennagrid::centroid(*cofit); PointType center_connection = centroid_1 - centroid_2; PointType outer_normal = util::unit_outer_normal(*fit, *cofit, viennagrid::default_point_accessor(segment)); //note: consistent orientation of center_connection and outer_normal is important here! double center_connection_len = viennagrid::norm(center_connection); double effective_facet_ratio = viennagrid::inner_prod(center_connection, outer_normal) / center_connection_len; // inner product of unit vectors double effective_facet_area = viennagrid::volume(*fit) * effective_facet_ratio; facet_area_accessor(*fit) = effective_facet_area; facet_distance_accessor(*fit) = center_connection_len; } } }
void test(std::string outfile) { typedef typename viennagrid::result_of::cell_tag<MeshType>::type CellTag; typedef typename viennagrid::result_of::vertex_range<MeshType>::type VertexContainer; typedef typename viennagrid::result_of::iterator<VertexContainer>::type VertexIterator; typedef typename viennagrid::result_of::line_range<MeshType>::type EdgeContainer; typedef typename viennagrid::result_of::iterator<EdgeContainer>::type EdgeIterator; typedef typename viennagrid::result_of::facet_range<MeshType>::type FacetContainer; typedef typename viennagrid::result_of::iterator<FacetContainer>::type FacetIterator; typedef typename viennagrid::result_of::cell_range<MeshType>::type CellContainer; typedef typename viennagrid::result_of::iterator<CellContainer>::type CellIterator; MeshType mesh; setup(mesh, CellTag()); std::cout << "Vertices: " << std::endl; VertexContainer vertices(mesh); for (VertexIterator vit = vertices.begin(); vit != vertices.end(); ++vit) std::cout << *vit << std::endl; std::cout << "Edges: " << std::endl; EdgeContainer edges(mesh); for (EdgeIterator eit = edges.begin(); eit != edges.end(); ++eit) std::cout << *eit << std::endl; std::cout << "Facets: " << std::endl; FacetContainer facets(mesh); for (FacetIterator fit = facets.begin(); fit != facets.end(); ++fit) std::cout << *fit << std::endl; std::cout << "Cells: " << std::endl; CellContainer cells(mesh); for (CellIterator cit = cells.begin(); cit != cells.end(); ++cit) std::cout << *cit << std::endl; viennagrid::io::vtk_writer<MeshType> my_vtk_writer; my_vtk_writer(mesh, outfile); }
void Cube3D::show() const { facets(Front,4,5,6,7); facets(Up ,2,3,7,6); facets(Right,1,2,6,5); facets(Left ,0,4,7,3); facets(Down ,0,1,5,4); facets(Back ,0,3,2,1); }
//====================================================================== // Function: num_adj_facets_on_surf // Description: count the number of adjacent facets to this edge that // have the specified tool id // Author: sjowen // Date: 5/01 //====================================================================== int CubitFacetEdge::num_adj_facets_on_surf( int tool_id ) { DLIList<CubitFacet *> cf_list; facets( cf_list ); CubitFacet *adj_facet = NULL; int nfacets = 0; for (int ii=0; ii<cf_list.size(); ii++) { adj_facet = cf_list.get_and_step(); if (adj_facet->tool_id() == tool_id) nfacets++; } return nfacets; }
typename viennagrid::result_of::coord< MeshT >::type surface_meshsegment(MeshT const & mesh_obj) { typedef typename viennagrid::result_of::const_element_range<MeshT, ElementTypeOrTag>::type ElementRange; typedef typename viennagrid::result_of::iterator<ElementRange>::type ElementIterator; typename viennagrid::result_of::coord<MeshT>::type result = 0; ElementRange facets(mesh_obj); for (ElementIterator fit = facets.begin(); fit != facets.end(); ++fit) { if (is_boundary(mesh_obj, *fit)) result += viennagrid::volume(*fit); } return result; }
//====================================================================== // Function: adj_facet_on_surf // Description: return the first facet on the adjacent facet list with // the indicated tool id // Author: sjowen // Date: 5/01 //====================================================================== CubitFacet *CubitFacetEdge::adj_facet_on_surf( int tool_id ) { DLIList<CubitFacet *> cf_list; facets( cf_list ); CubitFacet *adj_facet = NULL; int found = 0; for (int ii=0; ii<cf_list.size() && !found; ii++) { adj_facet = cf_list.get_and_step(); if (adj_facet->tool_id() == tool_id) { found = 1; } } if (!found) adj_facet = NULL; return adj_facet; }
void dual_box_flux_to_cell(DeviceType const & device, CellSetter & cell_setter, FacetAccessor const & facet_accessor) { typedef typename DeviceType::mesh_type MeshType; typedef typename viennagrid::result_of::cell<MeshType>::type CellType; typedef typename viennagrid::result_of::const_cell_range<MeshType>::type CellContainer; typedef typename viennagrid::result_of::iterator<CellContainer>::type CellIterator; typedef typename viennagrid::result_of::const_facet_range<CellType>::type FacetOnCellContainer; CellContainer cells(device.mesh()); for (CellIterator cit = cells.begin(); cit != cells.end(); ++cit) { FacetOnCellContainer facets(*cit); dual_box_flux_to_cell(*cit, facets, cell_setter, facet_accessor); } }
//====================================================================== // Function: other_facet // Description: return the other facet on the edge (assumes // max two facets per edge) // Author: sjowen // Date: 5/01 //====================================================================== CubitFacet *CubitFacetEdge::other_facet( CubitFacet *facet_ptr ) { DLIList<CubitFacet *> cf_list; facets( cf_list ); assert(cf_list.size() < 3); CubitFacet *adj_facet = NULL; if (cf_list.size() > 0) { adj_facet = cf_list.get_and_step(); if (adj_facet == facet_ptr) { if (cf_list.size() == 2) { adj_facet = cf_list.get(); } } } return adj_facet; }
//====================================================================== // Function: boundary_edge_points (PUBLIC) // Description: return the oriented endpoints of a facet edge assuming // the edge is at the frontier of the facets (only one adjacency) // Author: sjowen // Date: 8/00 //====================================================================== void CubitFacetEdge::boundary_edge_points( CubitPoint * &pt0, CubitPoint * &pt1, int tool_id ) { if(num_adj_facets() == 0) { pt0 = point(0); pt1 = point(1); return; } CubitFacet *facet = NULL; if (tool_id != 0) { int ii; int found = 0; DLIList <CubitFacet *> adj_facets; facets(adj_facets); for (ii=0; ii<adj_facets.size() && !found; ii++) { facet = adj_facets.get_and_step(); if (facet->tool_id() == tool_id) found = 1; } assert(found); } else { facet = adj_facet(0); if (!facet) facet = adj_facet(1); assert(facet != 0); } int index = facet->edge_index( this ); int use = facet->edge_use( index ); if (use == 1) { pt0 = point(0); pt1 = point(1); } else { pt0 = point(1); pt1 = point(0); } }
double mesh_surface(MeshType & mesh) { typedef typename viennagrid::result_of::facet<MeshType>::type FacetType; typedef typename viennagrid::result_of::cell<MeshType>::type CellType; typedef typename viennagrid::result_of::cell_range<MeshType>::type CellContainer; typedef typename viennagrid::result_of::iterator<CellContainer>::type CellIterator; typedef typename viennagrid::result_of::facet_range<CellType>::type FacetOnCellContainer; typedef typename viennagrid::result_of::iterator<FacetOnCellContainer>::type FacetOnCellIterator; typedef std::map<FacetType *, std::size_t> CellFacetMap; CellFacetMap cell_on_facet_cnt; CellContainer cells(mesh); for (CellIterator cit = cells.begin(); cit != cells.end(); ++cit) { FacetOnCellContainer facets(*cit); for (FacetOnCellIterator focit = facets.begin(); focit != facets.end(); ++focit) { cell_on_facet_cnt[&(*focit)] += 1; } } double mesh_surface = 0; for (typename CellFacetMap::iterator cfmit = cell_on_facet_cnt.begin(); cfmit != cell_on_facet_cnt.end(); ++cfmit) { if (cfmit->second == 1) { mesh_surface += viennagrid::volume(*(cfmit->first)); } } return mesh_surface; }
int surface_check(MeshType & mesh_old, MeshType & mesh_new) { typedef typename viennagrid::result_of::facet_range<MeshType>::type FacetContainer; typedef typename viennagrid::result_of::iterator<FacetContainer>::type FacetIterator; typedef typename viennagrid::result_of::cell_range<MeshType>::type CellContainer; typedef typename viennagrid::result_of::iterator<CellContainer>::type CellIterator; double old_surface = mesh_surface(mesh_old); double new_surface = mesh_surface(mesh_new); if ( (new_surface < 0.9999 * old_surface) || (new_surface > 1.0001 * old_surface) ) { CellContainer cells(mesh_new); for (CellIterator cit = cells.begin(); cit != cells.end(); ++cit) { std::cout << "Cell: "; std::cout << *cit << std::endl; } FacetContainer facets(mesh_new); for (FacetIterator fit = facets.begin(); fit != facets.end(); ++fit) { std::cout << "Facet: "; std::cout << *fit << std::endl; } std::cerr << "Surface check failed!" << std::endl; std::cerr << "Mesh surface before refinement: " << old_surface << std::endl; std::cerr << "Mesh surface after refinement: " << new_surface << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS; }
//====================================================================== // Function: other_facet_on_surf // Description: return the other facet on the edge that has the // same tool id. (finds the first occurrence // of the same tool id of the adjacent facets // to this edge that is not facet_ptr) // Author: sjowen // Date: 5/01 //====================================================================== CubitFacet *CubitFacetEdge::other_facet_on_surf( CubitFacet *facet_ptr ) { assert(facet_ptr != 0); int tool_id = facet_ptr->tool_id(); DLIList<CubitFacet *> cf_list; facets( cf_list ); CubitFacet *adj_facet = NULL; int found = 0; for (int ii=0; ii<cf_list.size() && !found; ii++) { adj_facet = cf_list.get_and_step(); if (adj_facet != facet_ptr) { if (adj_facet->tool_id() == tool_id) found = 1; } } if (!found) adj_facet = NULL; return adj_facet; }
void Perturb_Normal(Vector3d& Layer_Normal, const TNORMAL *Tnormal, const Vector3d& EPoint, Intersection *Intersection, const Ray *ray, TraceThreadData *Thread) { Vector3d TPoint,P1; DBL value1,Amount; int i; shared_ptr<NormalBlendMap> Blend_Map; if (Tnormal==NULL) { return; } /* If normal_map present, use it and return */ Blend_Map = std::tr1::dynamic_pointer_cast<NormalBlendMap>(Tnormal->Blend_Map); if (Blend_Map != NULL) { if (Tnormal->Type == UV_MAP_PATTERN) { Vector2d UV_Coords; /* Don't bother warping, simply get the UV vect of the intersection */ Intersection->Object->UVCoord(UV_Coords, Intersection, Thread); TPoint[X] = UV_Coords[U]; TPoint[Y] = UV_Coords[V]; TPoint[Z] = 0; Perturb_Normal(Layer_Normal,Blend_Map->Blend_Map_Entries[0].Vals,TPoint,Intersection,ray,Thread); Layer_Normal.normalize(); Intersection->PNormal = Layer_Normal; /* -hdf- June 98 */ return; } else if (Tnormal->Type != AVERAGE_PATTERN) { const NormalBlendMapEntry *Prev, *Cur; DBL prevWeight, curWeight; /* NK 19 Nov 1999 added Warp_EPoint */ Warp_EPoint (TPoint, EPoint, Tnormal); value1 = Evaluate_TPat(Tnormal, TPoint, Intersection, ray, Thread); Blend_Map->Search (value1,Prev,Cur,prevWeight,curWeight); Warp_Normal(Layer_Normal,Layer_Normal, Tnormal, Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG)); P1 = Layer_Normal; Warp_EPoint (TPoint, EPoint, Tnormal); Perturb_Normal(Layer_Normal,Cur->Vals,TPoint,Intersection,ray,Thread); if (Prev != Cur) { Perturb_Normal(P1,Prev->Vals,TPoint,Intersection,ray,Thread); Layer_Normal = prevWeight * P1 + curWeight * Layer_Normal; } UnWarp_Normal(Layer_Normal,Layer_Normal, Tnormal, Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG)); Layer_Normal.normalize(); Intersection->PNormal = Layer_Normal; /* -hdf- June 98 */ return; } // TODO - what if Tnormal->Type == AVERAGE_PATTERN? } /* No normal_map. */ if (Tnormal->Type <= LAST_NORM_ONLY_PATTERN) { Warp_Normal(Layer_Normal,Layer_Normal, Tnormal, Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG)); Warp_EPoint (TPoint, EPoint, Tnormal); switch (Tnormal->Type) { case BITMAP_PATTERN: bump_map (TPoint, Tnormal, Layer_Normal); break; case BUMPS_PATTERN: bumps (TPoint, Tnormal, Layer_Normal); break; case DENTS_PATTERN: dents (TPoint, Tnormal, Layer_Normal, Thread); break; case RIPPLES_PATTERN: ripples (TPoint, Tnormal, Layer_Normal, Thread); break; case WAVES_PATTERN: waves (TPoint, Tnormal, Layer_Normal, Thread); break; case WRINKLES_PATTERN: wrinkles (TPoint, Tnormal, Layer_Normal); break; case QUILTED_PATTERN: quilted (TPoint, Tnormal, Layer_Normal); break; case FACETS_PATTERN: facets (TPoint, Tnormal, Layer_Normal, Thread); break; case AVERAGE_PATTERN: Do_Average_Normals (TPoint, Tnormal, Layer_Normal, Intersection, ray, Thread); break; default: throw POV_EXCEPTION_STRING("Normal pattern not yet implemented."); } UnWarp_Normal(Layer_Normal,Layer_Normal, Tnormal, Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG)); } else { shared_ptr<SlopeBlendMap> slopeMap = std::tr1::dynamic_pointer_cast<SlopeBlendMap>(Tnormal->Blend_Map); Warp_Normal(Layer_Normal,Layer_Normal, Tnormal, Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG)); // TODO FIXME - two magic fudge factors Amount=Tnormal->Amount * -5.0; /*fudge factor*/ Amount*=0.02/Tnormal->Delta; /* NK delta */ /* warp the center point first - this is the last warp */ Warp_EPoint(TPoint,EPoint,Tnormal); for(i=0; i<=3; i++) { P1 = TPoint + (DBL)Tnormal->Delta * Pyramid_Vect[i]; /* NK delta */ value1 = Do_Slope_Map(Evaluate_TPat(Tnormal, P1, Intersection, ray, Thread), slopeMap.get()); Layer_Normal += (value1*Amount) * Pyramid_Vect[i]; } UnWarp_Normal(Layer_Normal,Layer_Normal,Tnormal, Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG)); } if ( Intersection ) Intersection->PNormal = Layer_Normal; /* -hdf- June 98 */ }
void Perturb_Normal(VECTOR Layer_Normal, const TNORMAL *Tnormal, const VECTOR EPoint, Intersection *Intersection, const Ray *ray, TraceThreadData *Thread) { VECTOR TPoint,P1; DBL value1,value2,Amount; int i; BLEND_MAP *Blend_Map; BLEND_MAP_ENTRY *Prev, *Cur; if (Tnormal==NULL) { return; } /* If normal_map present, use it and return */ if ((Blend_Map=Tnormal->Blend_Map) != NULL) { if ((Blend_Map->Type == NORMAL_TYPE) && (Tnormal->Type == UV_MAP_PATTERN)) { UV_VECT UV_Coords; Cur = &(Tnormal->Blend_Map->Blend_Map_Entries[0]); /* Don't bother warping, simply get the UV vect of the intersection */ Intersection->Object->UVCoord(UV_Coords, Intersection, Thread); TPoint[X] = UV_Coords[U]; TPoint[Y] = UV_Coords[V]; TPoint[Z] = 0; Perturb_Normal(Layer_Normal,Cur->Vals.Tnormal,TPoint,Intersection,ray,Thread); VNormalizeEq(Layer_Normal); Assign_Vector(Intersection->PNormal, Layer_Normal); /* -hdf- June 98 */ return; } else if ((Blend_Map->Type == NORMAL_TYPE) && (Tnormal->Type != AVERAGE_PATTERN)) { /* NK 19 Nov 1999 added Warp_EPoint */ Warp_EPoint (TPoint, EPoint, (TPATTERN *)Tnormal); value1 = Evaluate_TPat((TPATTERN *)Tnormal,TPoint,Intersection,ray,Thread); Search_Blend_Map (value1,Blend_Map,&Prev,&Cur); Warp_Normal(Layer_Normal,Layer_Normal, (TPATTERN *)Tnormal, Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG)); Assign_Vector(P1,Layer_Normal); Warp_EPoint (TPoint, EPoint, (TPATTERN *)Tnormal); Perturb_Normal(Layer_Normal,Cur->Vals.Tnormal,TPoint,Intersection,ray,Thread); if (Prev != Cur) { Perturb_Normal(P1,Prev->Vals.Tnormal,TPoint,Intersection,ray,Thread); value2 = (value1-Prev->value)/(Cur->value-Prev->value); value1 = 1.0-value2; VLinComb2(Layer_Normal,value1,P1,value2,Layer_Normal); } UnWarp_Normal(Layer_Normal,Layer_Normal,(TPATTERN *)Tnormal, Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG)); VNormalizeEq(Layer_Normal); Assign_Vector(Intersection->PNormal, Layer_Normal); /* -hdf- June 98 */ return; } } /* No normal_map. */ if (Tnormal->Type <= LAST_NORM_ONLY_PATTERN) { Warp_Normal(Layer_Normal,Layer_Normal, (TPATTERN *)Tnormal, Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG)); Warp_EPoint (TPoint, EPoint, (TPATTERN *)Tnormal); switch (Tnormal->Type) { case BITMAP_PATTERN: bump_map (TPoint, Tnormal, Layer_Normal); break; case BUMPS_PATTERN: bumps (TPoint, Tnormal, Layer_Normal); break; case DENTS_PATTERN: dents (TPoint, Tnormal, Layer_Normal, Thread); break; case RIPPLES_PATTERN: ripples (TPoint, Tnormal, Layer_Normal, Thread); break; case WAVES_PATTERN: waves (TPoint, Tnormal, Layer_Normal, Thread); break; case WRINKLES_PATTERN: wrinkles (TPoint, Tnormal, Layer_Normal); break; case QUILTED_PATTERN: quilted (TPoint, Tnormal, Layer_Normal); break; case FACETS_PATTERN: facets (TPoint, Tnormal, Layer_Normal, Thread); break; case AVERAGE_PATTERN: Do_Average_Normals (TPoint, Tnormal, Layer_Normal, Intersection, ray, Thread); break; default: throw POV_EXCEPTION_STRING("Normal pattern not yet implemented."); } UnWarp_Normal(Layer_Normal,Layer_Normal, (TPATTERN *)Tnormal, Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG)); } else { Warp_Normal(Layer_Normal,Layer_Normal, (TPATTERN *)Tnormal, Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG)); Amount=Tnormal->Amount * -5.0; /*fudge factor*/ Amount*=0.02/Tnormal->Delta; /* NK delta */ /* warp the center point first - this is the last warp */ Warp_EPoint(TPoint,EPoint,(TPATTERN *)Tnormal); for(i=0; i<=3; i++) { VAddScaled(P1,TPoint,Tnormal->Delta,Pyramid_Vect[i]); /* NK delta */ value1 = Do_Slope_Map(Evaluate_TPat((TPATTERN *)Tnormal,P1,Intersection,ray,Thread),Blend_Map); VAddScaledEq(Layer_Normal,value1*Amount,Pyramid_Vect[i]); } UnWarp_Normal(Layer_Normal,Layer_Normal,(TPATTERN *)Tnormal, Test_Flag(Tnormal,DONT_SCALE_BUMPS_FLAG)); } if ( Intersection ) Assign_Vector(Intersection->PNormal, Layer_Normal); /* -hdf- June 98 */ }
virtual void tris( DLIList<CubitFacet*> &facet_list ) { facets(facet_list); }
void assemble( DeviceType & device, TimeStepQuantitiesT & old_quantities, TimeStepQuantitiesT & quantities, viennashe::config const & conf, viennashe::she::unknown_she_quantity<VertexT, EdgeT> const & quan, MatrixType & A, VectorType & b, bool use_timedependence, bool quan_valid) { typedef typename DeviceType::mesh_type MeshType; typedef typename viennagrid::result_of::facet<MeshType>::type FacetType; typedef typename viennagrid::result_of::cell<MeshType>::type CellType; typedef typename viennagrid::result_of::const_facet_range<MeshType>::type FacetContainer; typedef typename viennagrid::result_of::iterator<FacetContainer>::type FacetIterator; typedef typename viennagrid::result_of::const_cell_range<MeshType>::type CellContainer; typedef typename viennagrid::result_of::iterator<CellContainer>::type CellIterator; typedef typename viennagrid::result_of::const_facet_range<CellType>::type FacetOnCellContainer; typedef typename viennagrid::result_of::iterator<FacetOnCellContainer>::type FacetOnCellIterator; typedef typename viennagrid::result_of::const_coboundary_range<MeshType, FacetType, CellType>::type CellOnFacetContainer; typedef typename viennagrid::result_of::iterator<CellOnFacetContainer>::type CellOnFacetIterator; typedef viennashe::math::sparse_matrix<double> CouplingMatrixType; typedef typename viennashe::she::timestep_quantities<DeviceType>::unknown_quantity_type SpatialUnknownType; std::vector< scattering_base<DeviceType> * > scattering_processes; if (conf.with_traps()) { if (! conf.with_electrons() || ! conf.with_holes()) throw viennashe::unavailable_feature_exception("Trapping without considering electrons or holes is not supported!"); if ( conf.get_electron_equation() != viennashe::EQUATION_SHE) throw viennashe::unavailable_feature_exception("Trapping without SHE for electrons is not supported!"); if ( conf.get_hole_equation() != viennashe::EQUATION_SHE) throw viennashe::unavailable_feature_exception("Trapping without SHE for holes is not supported!"); } // try // { MeshType const & mesh = device.mesh(); SpatialUnknownType const & potential = quantities.get_unknown_quantity(viennashe::quantity::potential()); SpatialUnknownType const & old_potential = old_quantities.get_unknown_quantity(viennashe::quantity::potential()); //TODO: Take old timestep viennashe::she::unknown_she_quantity<VertexT, EdgeT> const & old_quan = old_quantities.she_quantity(quan.get_name()); // // Set up scatter matrices: // const std::size_t L_max = static_cast<std::size_t>(conf.max_expansion_order()); const std::size_t num_harmonics = std::size_t(L_max+1) * std::size_t(L_max+1); CouplingMatrixType scatter_op_in(num_harmonics, num_harmonics); CouplingMatrixType scatter_op_out(num_harmonics, num_harmonics); for (std::size_t i=0; i < std::size_t(L_max+1) * std::size_t(L_max+1); ++i) scatter_op_out(i,i) += 1.0; scatter_op_in(0,0) += 1.0; //// preprocessing: compute coefficients a_{l,m}^{l',m'} and b_{l,m}^{l',m'} std::size_t Lmax = static_cast<std::size_t>(conf.max_expansion_order()); //maximum expansion order std::size_t coupling_rows = static_cast<std::size_t>((Lmax+1) * (Lmax+1)); std::size_t coupling_cols = coupling_rows; log::debug<log_assemble_all>() << "* assemble_all(): Computing coupling matrices..." << std::endl; CouplingMatrixType identity(coupling_rows, coupling_cols); for (std::size_t i=0; i<coupling_rows; ++i) for (std::size_t j=0; j<coupling_cols; ++j) identity(i,j) = (i == j) ? 1.0 : 0.0; CouplingMatrixType a_x(coupling_rows, coupling_cols); CouplingMatrixType a_y(coupling_rows, coupling_cols); CouplingMatrixType a_z(coupling_rows, coupling_cols); CouplingMatrixType b_x(coupling_rows, coupling_cols); CouplingMatrixType b_y(coupling_rows, coupling_cols); CouplingMatrixType b_z(coupling_rows, coupling_cols); //note: interchanged coordinates fill_coupling_matrices(a_x, a_y, a_z, b_x, b_y, b_z, static_cast<int>(Lmax)); CouplingMatrixType a_x_transposed = a_x.trans(); CouplingMatrixType a_y_transposed = a_y.trans(); CouplingMatrixType a_z_transposed = a_z.trans(); CouplingMatrixType b_x_transposed = b_x.trans(); CouplingMatrixType b_y_transposed = b_y.trans(); CouplingMatrixType b_z_transposed = b_z.trans(); if (log_assemble_all::enabled && log_assemble_all::debug) { log::debug<log_assemble_all>() << "a_x: " << a_x << std::endl; log::debug<log_assemble_all>() << "a_y: " << a_y << std::endl; log::debug<log_assemble_all>() << "a_z: " << a_z << std::endl; log::debug<log_assemble_all>() << "b_x: " << b_x << std::endl; log::debug<log_assemble_all>() << "b_y: " << b_y << std::endl; log::debug<log_assemble_all>() << "b_z: " << b_z << std::endl; log::debug<log_assemble_all>() << "identity: " << identity << std::endl; log::debug<log_assemble_all>() << "scatter_op_out: " << scatter_op_out << std::endl; log::debug<log_assemble_all>() << "scatter_op_in: " << scatter_op_in << std::endl; } // // Setup vector of scattering processes: // if (conf.scattering().acoustic_phonon().enabled()) { log::debug<log_assemble_all>() << "assemble(): Acoustic phonon scattering is ENABLED!" << std::endl; scattering_processes.push_back(new acoustic_phonon_scattering<DeviceType>(device, conf)); } if (conf.scattering().optical_phonon().enabled()) { log::debug<log_assemble_all>() << "assemble(): Optical phonon scattering is ENABLED!" << std::endl; scattering_processes.push_back(new optical_phonon_scattering<DeviceType>(device, conf, conf.energy_spacing())); } if (conf.scattering().ionized_impurity().enabled()) { log::debug<log_assemble_all>() << "assemble(): Ionized impurity scattering is ENABLED!" << std::endl; scattering_processes.push_back(new ionized_impurity_scattering<DeviceType>(device, conf)); } if (conf.scattering().impact_ionization().enabled()) { // Warn the user if we already know that he/she is going to simulate bullshit. if ( ! conf.with_holes() || conf.get_hole_equation() != viennashe::EQUATION_SHE ) log::warn() << std::endl << "WARNING: II scattering enabled, but 'BTE for holes' is disabled! Expect inconsistent results!" << std::endl; if ( ! conf.with_electrons() || conf.get_electron_equation() != viennashe::EQUATION_SHE ) log::warn() << std::endl << "WARNING: II scattering enabled, but 'BTE for electrons' is disabled! Expect inconsistent results!" << std::endl; scattering_processes.push_back(new impact_ionization_scattering<DeviceType>(device, conf)); } if (conf.with_traps() && conf.scattering().trapped_charge().enabled()) { log::debug<log_assemble_all>() << "assemble(): Trapped charge scattering is ENABLED!" << std::endl; scattering_processes.push_back(new trapped_charge_scattering<DeviceType, TimeStepQuantitiesT>(device, conf, quantities)); } typedef typename viennashe::electric_field_wrapper<DeviceType, SpatialUnknownType> ElectricFieldAccessor; ElectricFieldAccessor Efield(device, potential); if (conf.scattering().surface().enabled()) { log::debug<log_assemble_all>() << "assemble(): Surface roughness scattering is ENABLED!" << std::endl; scattering_processes.push_back(new surface_scattering<DeviceType, ElectricFieldAccessor>(device, conf, Efield)); } // // Assemble SHE system: // - scattering operators on vertices // - free streaming operator on vertices // - scattering operators on edges // - free streaming operator on edges // - any other stuff (traps on cells, etc.) // if (quan_valid && conf.scattering().electron_electron() && conf.with_electrons()) { log::debug<log_assemble_all>() << "assemble(): Electron electron scattering is ENABLED!" << std::endl; assemble_ee_scattering(device, conf, quan, old_quan, A, b); } // // Step 1: Assemble on even nodes // log::debug<log_assemble_all>() << "* assemble_all(): Even unknowns..." << std::endl; CellContainer cells(mesh); for (CellIterator cit = cells.begin(); cit != cells.end(); ++cit) { log::debug<log_assemble_all>() << "* assemble_all(): Assembling on cell " << *cit << std::endl; for (std::size_t index_H = 0; index_H < quan.get_value_H_size(); ++index_H) { if (log_assemble_all::enabled) log::debug<log_assemble_all>() << "* assemble_all(): Assembling on energy index " << index_H << std::endl; assemble_boundary_on_box(device, conf, quan, A, b, *cit, index_H, identity); if (viennashe::materials::is_conductor(device.get_material(*cit))) continue; // // Scattering operator Q{f} // assemble_scattering_operator_on_box( scattering_processes, device, conf, quan, A, b, *cit, index_H, scatter_op_in, scatter_op_out); } // // Free streaming operator L{f} // // iterate over neighbor cells holding the odd unknowns: FacetOnCellContainer facets_on_cell(*cit); for (FacetOnCellIterator focit = facets_on_cell.begin(); focit != facets_on_cell.end(); ++focit) { if (log_assemble_all::enabled) log::debug<log_assemble_all>() << "* assemble_all(): Assembling coupling with facet " << *focit << std::endl; CellType const *other_cell_ptr = util::get_other_cell_of_facet(mesh, *focit, *cit); if (!other_cell_ptr) continue; //Facet is on the boundary of the simulation domain -> homogeneous Neumann conditions CouplingMatrixType coupling_matrix_diffusion = coupling_matrix_in_direction(a_x, a_y, a_z, *cit, *other_cell_ptr, quan.get_carrier_type_id()); // note that the sign change due to MEDS is included in the choice of the normal vector direction (order of vertex vs. other_vertex): // - B \cdot n for even unknowns, // + B \cdot n for odd unknowns CouplingMatrixType coupling_matrix_drift = coupling_matrix_in_direction(b_x, b_y, b_z, *other_cell_ptr, *cit, quan.get_carrier_type_id()); for (std::size_t index_H = 0; index_H < quan.get_value_H_size(); ++index_H) { assemble_free_streaming_operator_on_box( device, conf, quan, A, b, *cit, *focit, index_H, coupling_matrix_diffusion, coupling_matrix_drift, false); } } //for edges // // Time dependence df/dt (and possibly df/dH * dH/dt) // if (use_timedependence) { for (std::size_t index_H = 0; index_H < quan.get_value_H_size(); ++index_H) { viennashe::she::assemble_timederivative(device, conf, quan, old_quan, A, b, *cit, index_H, identity, potential, old_potential); } } } //for cells // // Step 2: Assemble on odd 'nodes' (i.e. facets). TODO: Resolve code duplication w.r.t. above // log::info<log_assemble_all>() << "* assemble_all(): Odd unknowns..." << std::endl; FacetContainer facets(mesh); for (FacetIterator fit = facets.begin(); fit != facets.end(); ++fit) { if (log_assemble_all::enabled) log::debug<log_assemble_all>() << "* assemble_all(): Assembling on facet " << *fit << std::endl; for (std::size_t index_H = 0; index_H < quan.get_value_H_size(); ++index_H) { if (log_assemble_all::enabled) log::debug<log_assemble_all>() << "* assemble_all(): Assembling on energy index " << index_H << std::endl; // // Scattering operator Q{f} // assemble_scattering_operator_on_box(scattering_processes, device, conf, quan, A, b, *fit, index_H, scatter_op_in, scatter_op_out); } // // Free streaming operator L{f} // // iterate over cells of facet CellOnFacetContainer cells_on_facet(mesh, fit.handle()); for (CellOnFacetIterator cofit = cells_on_facet.begin(); cofit != cells_on_facet.end(); ++cofit) { if (log_assemble_all::enabled) log::debug<log_assemble_all>() << "* assemble_all(): Assembling coupling with cell " << *cofit << std::endl; CellType const *other_cell_ptr = util::get_other_cell_of_facet(mesh, *fit, *cofit); if (!other_cell_ptr) continue; //Facet is on the boundary of the simulation domain -> homogeneous Neumann conditions CouplingMatrixType coupling_matrix_diffusion = coupling_matrix_in_direction(a_x_transposed, a_y_transposed, a_z_transposed, *other_cell_ptr, *cofit, quan.get_carrier_type_id()); // note that the sign change due to MEDS is included in the choice of the normal vector direction (order of vertex vs. other_vertex): // - B \cdot n for even unknowns, // + B \cdot n for odd unknowns CouplingMatrixType coupling_matrix_drift = coupling_matrix_in_direction(b_x_transposed, b_y_transposed, b_z_transposed, *other_cell_ptr, *cofit, quan.get_carrier_type_id()); for (std::size_t index_H = 0; index_H < quan.get_value_H_size(); ++index_H) { assemble_free_streaming_operator_on_box( device, conf, quan, A, b, *cofit, *fit, index_H, coupling_matrix_diffusion, coupling_matrix_drift, true); } } //for vertices // // Time dependence df/dt (and possibly df/dH * dH/dt) // if (use_timedependence) { for (std::size_t index_H = 0; index_H < quan.get_value_H_size(); ++index_H) { viennashe::she::assemble_timederivative(device, conf, quan, old_quan, A, b, *fit, index_H, identity, potential, old_potential); } } } //for facets // Assemble traps on cells (to be integrated into the assembly above): if (conf.with_traps()) { log::debug<log_assemble_all>() << "assemble(): Assembly for traps ..." << std::endl; viennashe::she::assemble_traps(device, quantities, conf, quan, A, b); } // // Cleanup: // for (std::size_t i=0; i<scattering_processes.size(); ++i) { if ( scattering_processes[i] ) delete scattering_processes[i]; scattering_processes[i] = 0; } /* } catch (...) { // // Cleanup: // for (std::size_t i=0; i<scattering_processes.size(); ++i) if ( scattering_processes[i] ) delete scattering_processes[i]; // Rethrow throw; } */ }
int facet_check(MeshType & mesh) { typedef typename viennagrid::result_of::facet<MeshType>::type FacetType; typedef typename viennagrid::result_of::cell<MeshType>::type CellType; typedef typename viennagrid::result_of::facet_range<MeshType>::type FacetContainer; typedef typename viennagrid::result_of::iterator<FacetContainer>::type FacetIterator; typedef typename viennagrid::result_of::cell_range<MeshType>::type CellContainer; typedef typename viennagrid::result_of::iterator<CellContainer>::type CellIterator; typedef typename viennagrid::result_of::facet_range<CellType>::type FacetOnCellContainer; typedef typename viennagrid::result_of::iterator<FacetOnCellContainer>::type FacetOnCellIterator; typedef std::map<FacetType *, std::size_t> CellFacetMap; CellFacetMap cell_on_facet_cnt; CellContainer cells(mesh); for (CellIterator cit = cells.begin(); cit != cells.end(); ++cit) { FacetOnCellContainer facets(*cit); for (FacetOnCellIterator focit = facets.begin(); focit != facets.end(); ++focit) { cell_on_facet_cnt[&(*focit)] += 1; } } for (typename CellFacetMap::iterator cfmit = cell_on_facet_cnt.begin(); cfmit != cell_on_facet_cnt.end(); ++cfmit) { if (cfmit->second > 2) { std::cerr << "Topology problem for facet: " << std::endl; std::cout << *(cfmit->first) << std::endl; CellContainer cells(mesh); for (CellIterator cit = cells.begin(); cit != cells.end(); ++cit) { std::cout << "Cell: "; std::cout << *cit << std::endl; } FacetContainer facets(mesh); for (FacetIterator fit = facets.begin(); fit != facets.end(); ++fit) { std::cout << "Facet: "; std::cout << *fit << std::endl; } return EXIT_FAILURE; } } return EXIT_SUCCESS; }