00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "Electrodes.hpp"
00030
00031 template<unsigned DIM>
00032 Electrodes<DIM>::Electrodes(AbstractTetrahedralMesh<DIM,DIM>& rMesh,
00033 bool groundSecondElectrode,
00034 unsigned index,
00035 double lowerValue,
00036 double upperValue,
00037 double magnitude,
00038 double duration)
00039 {
00040 DistributedVectorFactory factory(rMesh.GetDistributedVectorFactory()->GetProblemSize(),
00041 rMesh.GetDistributedVectorFactory()->GetLocalOwnership());
00042 assert(index < DIM);
00043 mGroundSecondElectrode = groundSecondElectrode;
00044 assert(duration > 0);
00045 mEndTime = 0.0 + duration;
00046 mAreActive = true;
00047
00048
00049 double local_min = DBL_MAX;
00050 double local_max = -DBL_MAX;
00051
00052 for (typename AbstractTetrahedralMesh<DIM,DIM>::NodeIterator iter=rMesh.GetNodeIteratorBegin();
00053 iter != rMesh.GetNodeIteratorEnd();
00054 ++iter)
00055 {
00056 double value = (*iter).rGetLocation()[index];
00057 if(value < local_min)
00058 {
00059 local_min = value;
00060 }
00061 if(value > local_max)
00062 {
00063 local_max = value;
00064 }
00065 }
00066
00067 double global_min;
00068 double global_max;
00069
00070 int mpi_ret = MPI_Allreduce(&local_min, &global_min, 1, MPI_DOUBLE, MPI_MIN, PETSC_COMM_WORLD);
00071 assert(mpi_ret == MPI_SUCCESS);
00072 mpi_ret = MPI_Allreduce(&local_max, &global_max, 1, MPI_DOUBLE, MPI_MAX, PETSC_COMM_WORLD);
00073 assert(mpi_ret == MPI_SUCCESS);
00074
00075 if( fabs(global_min - lowerValue) > 1e-6 )
00076 {
00077 EXCEPTION("Minimum value of coordinate is not the value given");
00078 }
00079 if( fabs(global_max - upperValue) > 1e-6 )
00080 {
00081 EXCEPTION("Maximum value of coordinate is not the value given");
00082 }
00083
00084 mpBoundaryConditionsContainer = new BoundaryConditionsContainer<DIM,DIM,2>;
00085
00086 ConstBoundaryCondition<DIM>* p_bc_flux_in = new ConstBoundaryCondition<DIM>(magnitude);
00087 ConstBoundaryCondition<DIM>* p_bc_flux_out = new ConstBoundaryCondition<DIM>(-magnitude);
00088
00089
00090
00091 for (typename AbstractTetrahedralMesh<DIM,DIM>::BoundaryElementIterator iter
00092 = rMesh.GetBoundaryElementIteratorBegin();
00093 iter != rMesh.GetBoundaryElementIteratorEnd();
00094 iter++)
00095 {
00096 if ( fabs((*iter)->CalculateCentroid()[index] - lowerValue) < 1e-6 )
00097 {
00098 mpBoundaryConditionsContainer->AddNeumannBoundaryCondition(*iter, p_bc_flux_in, 1);
00099 }
00100
00101 if (!mGroundSecondElectrode)
00102 {
00103 if ( fabs((*iter)->CalculateCentroid()[index] - upperValue) < 1e-6 )
00104 {
00105 mpBoundaryConditionsContainer->AddNeumannBoundaryCondition(*iter, p_bc_flux_out, 1);
00106 }
00107 }
00108 }
00109
00110
00111
00112 if (mGroundSecondElectrode)
00113 {
00114 ConstBoundaryCondition<DIM>* p_zero_bc = new ConstBoundaryCondition<DIM>(0.0);
00115
00116 for (typename AbstractTetrahedralMesh<DIM,DIM>::NodeIterator iter=rMesh.GetNodeIteratorBegin();
00117 iter != rMesh.GetNodeIteratorEnd();
00118 ++iter)
00119 {
00120 if (fabs((*iter).rGetLocation()[index]-upperValue)<1e-6)
00121 {
00122 mpBoundaryConditionsContainer->AddDirichletBoundaryCondition(&(*iter), p_zero_bc, 1);
00123 }
00124 }
00125
00126
00127 delete p_bc_flux_out;
00128 }
00129 }
00130
00132
00134
00135 template class Electrodes<1>;
00136 template class Electrodes<2>;
00137 template class Electrodes<3>;