MOAB: Mesh Oriented datABase  (version 5.4.1)
domain.cpp
Go to the documentation of this file.
00001 #include "MeshDomain1D.hpp"
00002 #include "PlanarDomain.hpp"
00003 #include "CylinderDomain.hpp"
00004 #include "ConicDomain.hpp"
00005 #include "SphericalDomain.hpp"
00006 #include "DomainClassifier.hpp"
00007 #include "MeshImpl.hpp"
00008 #include "CLArgs.hpp"
00009 #include "MsqError.hpp"
00010 #include "TopologyInfo.hpp"
00011 
00012 #include "domain.hpp"
00013 #include <iostream>
00014 #include <algorithm>
00015 #include <cstdlib>
00016 
00017 using namespace MBMesquite;
00018 
00019 class SphereDomainArg : public CLArgs::DoubleListArgI
00020 {
00021   private:
00022     std::vector< MeshDomain* >& domList;
00023     std::vector< int >& dimList;
00024 
00025   public:
00026     SphereDomainArg( std::vector< MeshDomain* >& domlist, std::vector< int >& dims )
00027         : domList( domlist ), dimList( dims )
00028     {
00029     }
00030     virtual bool value( const std::vector< double >& list );
00031 };
00032 bool SphereDomainArg::value( const std::vector< double >& list )
00033 {
00034     double rad = list[0];
00035     if( rad <= 0.0 ) return false;
00036     Vector3D center( 0, 0, 0 );
00037     if( list.size() == 4 ) center.set( list[1], list[2], list[3] );
00038     domList.push_back( new SphericalDomain( center, rad ) );
00039     dimList.push_back( 2 );
00040     return true;
00041 }
00042 
00043 class ConicDomainArg : public CLArgs::DoubleListArgI
00044 {
00045   private:
00046     std::vector< MeshDomain* >& domList;
00047     std::vector< int >& dimList;
00048 
00049   public:
00050     ConicDomainArg( std::vector< MeshDomain* >& domlist, std::vector< int >& dims )
00051         : domList( domlist ), dimList( dims )
00052     {
00053     }
00054     virtual bool value( const std::vector< double >& list );
00055 };
00056 bool ConicDomainArg::value( const std::vector< double >& vals )
00057 {
00058     double base_rad = vals[0];
00059     double height   = vals[1];
00060     Vector3D axis( 0, 0, 1 );
00061     if( vals.size() >= 5 )
00062     {
00063         axis[0] = vals[2];
00064         axis[1] = vals[3];
00065         axis[2] = vals[4];
00066     }
00067     Vector3D point( 0, 0, 0 );
00068     if( vals.size() == 8 )
00069     {
00070         axis[0] = vals[5];
00071         axis[1] = vals[6];
00072         axis[2] = vals[7];
00073     }
00074 
00075     domList.push_back( new ConicDomain( base_rad, height, axis, point ) );
00076     dimList.push_back( 2 );
00077     return true;
00078 }
00079 
00080 class CylinderDomainArg : public CLArgs::DoubleListArgI
00081 {
00082   private:
00083     std::vector< MeshDomain* >& domList;
00084     std::vector< int >& dimList;
00085 
00086   public:
00087     CylinderDomainArg( std::vector< MeshDomain* >& domlist, std::vector< int >& dims )
00088         : domList( domlist ), dimList( dims )
00089     {
00090     }
00091     virtual bool value( const std::vector< double >& list );
00092 };
00093 bool CylinderDomainArg::value( const std::vector< double >& vals )
00094 {
00095     double rad = vals[0];
00096     Vector3D normal( vals[1], vals[2], vals[3] );
00097     Vector3D point( 0, 0, 0 );
00098     if( vals.size() == 7 ) point.set( vals[4], vals[5], vals[6] );
00099     domList.push_back( new CylinderDomain( rad, normal, point ) );
00100     dimList.push_back( 2 );
00101     return true;
00102 }
00103 
00104 class PlanarDomainArg : public CLArgs::DoubleListArgI
00105 {
00106   private:
00107     std::vector< MeshDomain* >& domList;
00108     std::vector< int >& dimList;
00109 
00110   public:
00111     PlanarDomainArg( std::vector< MeshDomain* >& domlist, std::vector< int >& dims )
00112         : domList( domlist ), dimList( dims )
00113     {
00114     }
00115     virtual bool value( const std::vector< double >& list );
00116 };
00117 bool PlanarDomainArg::value( const std::vector< double >& list )
00118 {
00119     Vector3D normal( list[0], list[1], list[2] );
00120     Vector3D point( 0, 0, 0 );
00121     if( list.size() == 6 ) point.set( list[3], list[4], list[5] );
00122     domList.push_back( new PlanarDomain( normal, point ) );
00123     dimList.push_back( 2 );
00124     return true;
00125 }
00126 
00127 class LineDomainArg : public CLArgs::DoubleListArgI
00128 {
00129   private:
00130     std::vector< MeshDomain* >& domList;
00131     std::vector< int >& dimList;
00132 
00133   public:
00134     LineDomainArg( std::vector< MeshDomain* >& domlist, std::vector< int >& dims ) : domList( domlist ), dimList( dims )
00135     {
00136     }
00137     virtual bool value( const std::vector< double >& list );
00138 };
00139 bool LineDomainArg::value( const std::vector< double >& vals )
00140 {
00141     Vector3D dir( vals[0], vals[1], vals[2] );
00142     Vector3D point( 0, 0, 0 );
00143     if( vals.size() == 6 ) point.set( vals[3], vals[4], vals[5] );
00144     LineDomain* pdom = new LineDomain( point, dir );
00145     domList.push_back( pdom );
00146     dimList.push_back( 1 );
00147     return true;
00148 }
00149 
00150 class CircleDomainArg : public CLArgs::DoubleListArgI
00151 {
00152   private:
00153     std::vector< MeshDomain* >& domList;
00154     std::vector< int >& dimList;
00155 
00156   public:
00157     CircleDomainArg( std::vector< MeshDomain* >& domlist, std::vector< int >& dims )
00158         : domList( domlist ), dimList( dims )
00159     {
00160     }
00161     virtual bool value( const std::vector< double >& list );
00162 };
00163 bool CircleDomainArg::value( const std::vector< double >& vals )
00164 {
00165     double rad = vals[0];
00166     Vector3D normal( vals[1], vals[2], vals[3] );
00167     Vector3D point( 0, 0, 0 );
00168     if( vals.size() == 7 ) point.set( vals[4], vals[5], vals[6] );
00169     CircleDomain* pdom = new CircleDomain( point, normal, rad );
00170     domList.push_back( pdom );
00171     dimList.push_back( 1 );
00172     return true;
00173 }
00174 
00175 class PointDomainArg : public CLArgs::DoubleListArgI
00176 {
00177   private:
00178     std::vector< MeshDomain* >& domList;
00179     std::vector< int >& dimList;
00180 
00181   public:
00182     PointDomainArg( std::vector< MeshDomain* >& domlist, std::vector< int >& dims )
00183         : domList( domlist ), dimList( dims )
00184     {
00185     }
00186     virtual bool value( const std::vector< double >& list );
00187 };
00188 bool PointDomainArg::value( const std::vector< double >& vals )
00189 {
00190     Vector3D point( vals[0], vals[1], vals[2] );
00191     PointDomain* pdom = new PointDomain( point );
00192     domList.push_back( pdom );
00193     dimList.push_back( 0 );
00194     return true;
00195 }
00196 
00197 std::vector< MeshDomain* > domains;
00198 std::vector< int > domain_dims;
00199 SphereDomainArg sphere_arg( domains, domain_dims );
00200 ConicDomainArg conic_arg( domains, domain_dims );
00201 CylinderDomainArg cylinder_arg( domains, domain_dims );
00202 PlanarDomainArg plane_arg( domains, domain_dims );
00203 CircleDomainArg circle_arg( domains, domain_dims );
00204 LineDomainArg line_arg( domains, domain_dims );
00205 PointDomainArg point_arg( domains, domain_dims );
00206 CLArgs::ToggleArg skin_mesh( false );
00207 
00208 const char* SPHERE_VALUES[]   = { "rad", "x", "y", "z" };
00209 const char* CYLINDER_VALUES[] = { "rad", "i", "j", "k", "x", "y", "z" };
00210 const char* CONE_VALUES[]     = { "rad", "h", "i", "j", "k", "x", "y", "z" };
00211 
00212 void add_domain_args( CLArgs& args )
00213 {
00214     args.toggle_flag( SKIN_FLAG, "Mark boundary vertices as fixed (default if no domain specified)", &skin_mesh );
00215     args.double_list_flag( SPHERE_FLAG, "Spherical domain as center and radius", &sphere_arg );
00216     args.limit_list_flag( SPHERE_FLAG, 4, SPHERE_VALUES );
00217     args.limit_list_flag( SPHERE_FLAG, 1, SPHERE_VALUES );
00218     args.double_list_flag( PLANE_FLAG, "Planar domain as normal and point", &plane_arg );
00219     args.limit_list_flag( PLANE_FLAG, 3, CYLINDER_VALUES + 1 );
00220     args.limit_list_flag( PLANE_FLAG, 6, CYLINDER_VALUES + 1 );
00221     args.double_list_flag( CYLINDER_FLAG, "Cylindrical radius, axis, and point", &cylinder_arg );
00222     args.limit_list_flag( CYLINDER_FLAG, 4, CYLINDER_VALUES );
00223     args.limit_list_flag( CYLINDER_FLAG, 7, CYLINDER_VALUES );
00224     args.double_list_flag( CONE_FLAG, "Conic domain as base radius, height, axis, and base center", &conic_arg );
00225     args.limit_list_flag( CONE_FLAG, 2, CONE_VALUES );
00226     args.limit_list_flag( CONE_FLAG, 5, CONE_VALUES );
00227     args.limit_list_flag( CONE_FLAG, 8, CONE_VALUES );
00228     args.double_list_flag( LINE_FLAG, "Linear domain as direction and point", &line_arg );
00229     args.limit_list_flag( LINE_FLAG, 3, CYLINDER_VALUES + 1 );
00230     args.limit_list_flag( LINE_FLAG, 6, CYLINDER_VALUES + 1 );
00231     args.double_list_flag( CIRCLE_FLAG, "Circular domain as radius, normal, and center", &circle_arg );
00232     args.limit_list_flag( CIRCLE_FLAG, 4, CYLINDER_VALUES );
00233     args.limit_list_flag( CIRCLE_FLAG, 7, CYLINDER_VALUES );
00234     args.double_list_flag( POINT_FLAG, "Point domain", &point_arg );
00235     args.limit_list_flag( POINT_FLAG, 3, SPHERE_VALUES + 1 );
00236 }
00237 
00238 MeshDomain* process_domain_args( MeshImpl* mesh )
00239 {
00240     MsqPrintError err( std::cerr );
00241     MeshDomain* rval = 0;
00242 
00243     if( !domains.empty() )
00244     {
00245         int max_domain_dim = *std::max_element( domain_dims.begin(), domain_dims.end() );
00246         std::vector< Mesh::ElementHandle > elems;
00247         mesh->get_all_elements( elems, err );
00248         std::vector< EntityTopology > types( elems.size() );
00249         mesh->elements_get_topologies( arrptr( elems ), arrptr( types ), elems.size(), err );
00250         EntityTopology max_type = *std::max_element( types.begin(), types.end() );
00251         int max_elem_dim        = TopologyInfo::dimension( max_type );
00252 
00253         if( max_domain_dim == max_elem_dim && domains.size() == 1 )
00254         {
00255             rval = domains.front();
00256         }
00257         else
00258         {
00259             DomainClassifier* result = new DomainClassifier();
00260             if( max_domain_dim < max_elem_dim )
00261             {
00262                 DomainClassifier::classify_skin_geometrically( *result, mesh, 1e-4, arrptr( domains ),
00263                                                                arrptr( domain_dims ), domains.size(), err );
00264             }
00265             else
00266             {
00267                 DomainClassifier::classify_geometrically( *result, mesh, 1e-4, arrptr( domains ), arrptr( domain_dims ),
00268                                                           domains.size(), err );
00269             }
00270             rval = result;
00271         }
00272     }
00273     if( skin_mesh.value() )
00274     {
00275         mesh->mark_skin_fixed( err, false );
00276     }
00277     if( err )
00278     {
00279         std::cerr << err << std::endl;
00280         exit( 3 );
00281     }
00282 
00283     return rval;
00284 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines