C1DAnisoMTSynthData.cpp

Go to the documentation of this file.
00001 #include "C1DAnisoMTSynthData.h"
00002 #include <cassert>
00003 #include <limits>
00004 #include <fstream>
00005 
00006 const int frequenzen = 50;
00007 const float T[frequenzen] = {
00008 0.0025 ,0.00308337, 0.00513901, 0.00625, 0.0104167, 0.0125, 0.0208333, 0.025, 0.0416667, 0.05, 0.0833333,0.1,
00009 0.166667,0.2,0.333333,0.4 ,0.667,0.64,1.06667,1.29333,2.15554 ,2.59997,4.33332, 5.19994 ,8.66701 ,10.666667, 
00010         16.000, 21.333, 32.000, 42.667, 64.0, 85.332, 127.992,
00011                           170.678, 256.016, 341.297, 512.033, 682.594, 1023.541, 1366.120,
00012                           2049.180, 2732.240, 4098.361, 5464.481, 8196.722, 10869.565, 16393.443,
00013                           28800, 43200, 86400};
00014 
00015 void C1DAnisoMTSynthData::TransformRho()
00016 {
00017         assert(rho1.size() == rho2.size());
00018         assert(rho1.size() == rho3.size());
00019         assert(rho1.size() == strikes.size());
00020         assert(rho1.size() == slants.size());
00021         assert(rho1.size() == dips.size());
00022         
00023         const unsigned int nlayers = rho1.size();
00024         effcond1.assign(nlayers,0.0);
00025         effcond2.assign(nlayers,0.0);
00026         effstrike.assign(nlayers,0.0);
00027         for (unsigned int i = 0; i < nlayers; ++i)
00028         {
00029                 double s1 = 1./rho1.at(i);//transform to conductivity
00030                 double s2 = 1./rho2.at(i);
00031                 double s3 = 1./rho3.at(i);
00032                 double strike = PI * strikes.at(i)/180.0; //transform angles to radian
00033                 double dip = PI * dips.at(i)/180.0;
00034                 double slant = PI * slants.at(i)/180.0;
00035                 //calculate some frequently used sines and cosines
00036                 double sps = sin(strike);
00037                 double cps = cos(strike);
00038                 double sth = sin(dip);
00039                 double cth = cos(dip);
00040                 double sfi = sin(slant);
00041                 double cfi = cos(slant);
00042                 double pom1 = s1 * cfi * cfi + s2 * sfi * sfi;
00043                 double pom2 = s1 * sfi * sfi + s2 * cfi * cfi;
00044                 double pom3 = (s1 - s2) * sfi * cfi;
00045                 double c2ps = cps * cps;
00046                 double s2ps = sps * sps;
00047                 double c2th = cth * cth;
00048                 double s2th = sth * sth;
00049                 double csps = cps * sps;
00050                 double csth = cth * sth;
00051                 //contruct the conductivity tensor elements
00052                 double sg11 = pom1 * c2ps + pom2 * s2ps * c2th - 2. * pom3 * cth * csps + s3 * s2th * s2ps;
00053                 double sg12 = pom1 * csps - pom2 * c2th * csps + pom3 * cth *(c2ps - s2ps) - s3 * s2th * csps;
00054                 double sg13 = - pom2 * csth * sps + pom3 * sth * cps + s3 * csth * sps;
00055                 double sg21 = sg12;
00056                 double sg22 = pom1 * s2ps + pom2 * c2ps * c2th + 2. * pom3 * cth * csps + s3 * s2th * c2ps;
00057                 double sg23 = pom2 * csth * cps + pom3 * sth * sps - s3 * csth * cps;
00058                 double sg31 = sg13;
00059                 double sg32 = sg23;
00060                 double sg33 = pom2 * s2th + s3 * c2th;
00061                 double axx = sg11 - sg13*sg31/sg33;
00062                 double axy = sg12 - sg13*sg32/sg33;
00063                 double ayx = sg21 - sg31*sg23/sg33;
00064                 double ayy = sg22 - sg23*sg32/sg33;
00065                 //calculate effective horizontal conductivity
00066                 double da12 = sqrt((axx-ayy)*(axx-ayy)+ 4.0 * axy * ayx);
00067                 effcond1.at(i) = (0.5 * (axx+ayy+da12));
00068                 effcond2.at(i) = (0.5 * (axx+ayy-da12));
00069                 if (gsl_fcmp(da12,0.0,GSL_DBL_EPSILON) !=0)
00070                 {
00071                         effstrike.at(i) = 0.5 * acos((axx-ayy)/da12);
00072                         assert(gsl_finite(effstrike.at(i)));
00073                 }
00074                 else
00075                 {
00076                         effstrike.at(i) = 0.0;
00077                 }
00078                 if (axy < 0.0 ) effstrike.at(i) *= -1.0;
00079                 //std::cout << effcond1.at(i) << " " << effcond2.at(i) << " " << effstrike.at(i)*180./PI << std::endl;
00080                 
00081         }
00082 }
00083 
00084 void C1DAnisoMTSynthData::GetData()
00085 {
00086         
00087                 calc_frequencies = GetFrequencies();
00088                 if (calc_frequencies.empty())
00089                 {
00090                         for (int i = 0; i < frequenzen; ++i)
00091                                 calc_frequencies.push_back(1.0/T[i]);
00092                 }
00093                 Assign(calc_frequencies.size());
00094                 TransformRho();
00095                 CalcZ();
00096             Update();
00097 
00098 }
00099 
00100 inline dcomp dfp(const dcomp x)
00101 {
00102         //std::cout << 1.0 + exp(-2.0 * x) << std::endl;
00103         return 1.0 + exp(-2.0 * x);
00104 }
00105 
00106 inline dcomp dfm(const dcomp x)
00107 {
00108         //std::cout << 1.0 - exp(-2.0 * x) << std::endl;
00109         return 1.0 - exp(-2.0 * x);
00110 }
00111 
00112 void C1DAnisoMTSynthData::CalcZ()
00113 {
00114         dcomp omegamu; 
00115         const double convfactor = 1./(1000. * mu);
00116         
00117         for (unsigned  int i = 0; i < calc_frequencies.size(); ++i)
00118         {
00119                 omegamu = -I * 8e-7 * PI * PI * calc_frequencies.at(i); 
00120                 dcomp k0 =(1. - I) * 2.0e-3 * PI * sqrt(calc_frequencies.at(i)/10.0);
00121                 dcomp zxyrot = k0 / sqrt(effcond1.back());
00122                 dcomp zyxrot = -k0 / sqrt(effcond2.back());
00123                 double currstrike = effstrike.back();
00124                 MTTensor CurrZ(dcomp(0.0,0.0),zxyrot,zyxrot,dcomp(0.0,0.0),calc_frequencies.at(i));
00125                 for (int j = thicknesses.size()-2 ; j >= 0 ; --j)
00126                 {
00127                         double currthick = 1000.0 * thicknesses.at(j);
00128                         if (currstrike != effstrike.at(j) && effcond1.at(j) != effcond2.at(j))
00129                         {
00130                                 CurrZ.Rotate(effstrike.at(j)-currstrike);
00131                                 currstrike = effstrike.at(j);
00132                         }
00133                         MTTensor BottomZ(CurrZ);
00134                         //std::cout << CurrZ.GetZxy() * convfactor<< " " << CurrZ.GetZyx() * convfactor << std::endl;
00135                         dcomp dz1 = k0/sqrt(effcond1.at(j));
00136                         dcomp dz2 = k0/sqrt(effcond2.at(j));
00137                         dcomp ag1 = k0 * sqrt(effcond1.at(j)) * currthick;
00138                         dcomp ag2 = k0 * sqrt(effcond2.at(j)) * currthick;
00139                         
00140                         dcomp detzbottom = BottomZ.GetDet();
00141                         dcomp denominator = detzbottom * dfm(ag1) * dfm(ag2)/(dz1*dz2) + BottomZ.GetZxy()*dfm(ag1)*dfp(ag2)/dz1
00142                                         - BottomZ.GetZyx() * dfp(ag1) * dfm(ag2)/dz2+ dfp(ag1)*dfp(ag2);
00143                         //std::cout << dz1 << dz2 << ag1 << ag2 << detzbottom << denominator << std::endl;
00144                         CurrZ.SetZxx() = 4.0 * BottomZ.GetZxx() * exp(-ag1-ag2)/denominator;
00145                         CurrZ.SetZxy() = (BottomZ.GetZxy() * dfp(ag1) * dfp(ag2) - BottomZ.GetZyx() * dfm(ag1) * dfm(ag2)*dz1/dz2
00146                                         + detzbottom * dfp(ag1) * dfm(ag2)/dz2 +dfm(ag1) *dfp(ag2)*dz1)/denominator;
00147                         CurrZ.SetZyx() = (BottomZ.GetZyx()  * dfp(ag1) * dfp(ag2) - BottomZ.GetZxy() * dfm(ag1) * dfm(ag2)*dz2/dz1
00148                                 - detzbottom * dfm(ag1) * dfp(ag2)/dz1 -dfp(ag1) *dfm(ag2)*dz2)/denominator;
00149                         CurrZ.SetZyy() = 4.0 * BottomZ.GetZyy() * exp(-ag1-ag2)/denominator;
00150                 }
00151                 CurrZ.SetRotangle() = currstrike;
00152                 CurrZ.SetZxx() = convfactor * conj(CurrZ.SetZxx());
00153                 CurrZ.SetZxy() = convfactor * conj(CurrZ.SetZxy());
00154                 CurrZ.SetZyx() = convfactor * conj(CurrZ.SetZyx());
00155                 CurrZ.SetZyy() = convfactor * conj(CurrZ.SetZyy());
00156                 assert(gsl_finite(abs(CurrZ.GetZxx()))); //there seem to be some problems with certain calculations
00157                 assert(gsl_finite(abs(CurrZ.GetZxy()))); //safeguard to help investigate
00158                 assert(gsl_finite(abs(CurrZ.GetZyx())));
00159                 assert(gsl_finite(abs(CurrZ.GetZyy())));
00160                 //std::cout << CurrZ.GetZxy() << " " << CurrZ.GetZyx() << std::endl << std::endl;
00161                 CurrZ.Rotate(-CurrZ.GetRotangle());
00162                 //
00163                 SetMTData().at(i) = CurrZ;
00164                 /*std::copy(effstrike.begin(),effstrike.end(),std::ostream_iterator<double>(std::cout," "));
00165                 std::cout << std::endl;
00166                 std::copy(effcond1.begin(),effcond1.end(),std::ostream_iterator<double>(std::cout," "));
00167                 std::cout << std::endl;
00168                 std::copy(effcond2.begin(),effcond2.end(),std::ostream_iterator<double>(std::cout," "));
00169                 std::cout << std::endl;*/
00170                 
00171         }
00172 }
00173 
00174 void C1DAnisoMTSynthData::WriteModel(std::string filename) 
00175 {
00176         assert(rho1.size() == thicknesses.size());
00177         assert(rho2.size() == thicknesses.size());
00178         assert(rho3.size() == thicknesses.size());
00179         assert(strikes.size() == thicknesses.size());
00180         assert(slants.size() == thicknesses.size());
00181         assert(dips.size() == thicknesses.size());
00182         std::ofstream outfile(filename.c_str());
00183         if (outfile)
00184         {
00185                 outfile << thicknesses.size() << std::endl;
00186                 for (unsigned int i = 0; i < thicknesses.size(); ++i)
00187                 {
00188                                 outfile << thicknesses.at(i) << "  " << rho1.at(i) << " ";
00189                                 outfile << rho2.at(i) << "  " << rho3.at(i) << " ";
00190                                 outfile << strikes.at(i) << "  " << slants.at(i) << " ";
00191                                 outfile << dips.at(i) << std::endl;
00192                 }
00193         }
00194         else
00195         {
00196                 throw CFatalException("Problem writing to file: "+filename);
00197         }
00198         
00199 }
00200 
00201 void C1DAnisoMTSynthData::ReadModel(std::string filename)
00202 {
00203 
00204         int layers;
00205         double currthick,currho1, currho2, currho3, currstrike, currslant, currdip;
00206         int i = 0;
00207         
00208         std::ifstream infile(filename.c_str());
00209         infile >> layers;
00210         if (!infile.good() || layers < 0)
00211                 throw CFatalException("Problem reading file: "+filename);
00212         thicknesses.reserve(layers);
00213         rho1.reserve(layers);
00214         rho2.reserve(layers);
00215         rho3.reserve(layers);
00216         strikes.reserve(layers);
00217         slants.reserve(layers);
00218         dips.reserve(layers);
00219         while (infile.good())
00220         {
00221                 infile >> currthick >> currho1 >> currho2 >> currho3 >> currstrike >> currslant >> currdip;
00222                 if (infile.good())
00223                 {
00224                         thicknesses.push_back(currthick);
00225                         rho1.push_back(currho1);
00226                         rho2.push_back(currho2);
00227                         rho3.push_back(currho3);
00228                         strikes.push_back(currstrike);
00229                         slants.push_back(currslant);
00230                         dips.push_back(currdip);
00231                         ++i;
00232                 }
00233         }
00234         assert(rho1.size() == thicknesses.size());
00235         assert(rho2.size() == thicknesses.size());
00236         assert(rho3.size() == thicknesses.size());
00237         assert(strikes.size() == thicknesses.size());
00238         assert(slants.size() == thicknesses.size());
00239         assert(dips.size() == thicknesses.size());
00240         assert(i==layers);
00241 }
00242 
00243 void C1DAnisoMTSynthData::WritePlot(std::string filename)
00244 {
00245         std::ofstream outfile(filename.c_str());
00246         double cumthick = 0;
00247         TransformRho();
00248         assert(effcond1.size() == thicknesses.size());
00249         assert(effcond2.size() == thicknesses.size());
00250         assert(effstrike.size() == thicknesses.size());
00251         for (unsigned int i = 0; i < thicknesses.size(); ++i)
00252         {
00253                         outfile << cumthick << "  " << 1./effcond1.at(i) << " ";
00254                         outfile << 1./effcond2.at(i) << "  " << effstrike.at(i) * 180./PI;
00255                         outfile << std::endl;
00256                         cumthick += thicknesses.at(i);
00257                         outfile << cumthick << "  " << 1./effcond1.at(i) << " ";
00258                         outfile << 1./effcond2.at(i) << "  " << effstrike.at(i) * 180./PI;
00259                         outfile << std::endl;
00260          }
00261 }
00262 
00263 gplib::rvec C1DAnisoMTSynthData::GetModelVector()
00264 {
00265         TransformRho();
00266         assert(effcond1.size() == thicknesses.size());
00267         assert(effcond2.size() == thicknesses.size());
00268         assert(effstrike.size() == thicknesses.size());
00269         const unsigned int length = thicknesses.size();
00270         gplib::rvec result(length*4);
00271         for (unsigned int i = 0; i < length; ++i)
00272         {
00273                 result(i) = log10(1./effcond1.at(i));
00274                 result(i+length) = thicknesses.at(i);
00275                 result(i+2*length) = log10(effcond1.at(i)/effcond2.at(i));
00276                 result(i+3*length) = effstrike.at(i) * 180./PI;
00277         }
00278         return result;
00279 }
00280 
00281 C1DAnisoMTSynthData::C1DAnisoMTSynthData(const C1DAnisoMTSynthData &old):
00282 MTStation(old),
00283 calc_frequencies(old.calc_frequencies),
00284 thicknesses(old.thicknesses), 
00285 strikes(old.strikes),
00286 slants(old.slants),
00287 dips(old.dips),
00288 rho1(old.rho1),
00289 rho2(old.rho2),
00290 rho3(old.rho3),
00291 effcond1(old.effcond1),
00292 effcond2(old.effcond2),
00293 effstrike(old.effstrike)
00294 {
00295         
00296 }
00297 C1DAnisoMTSynthData::C1DAnisoMTSynthData()
00298 {
00299 }
00300 
00301 C1DAnisoMTSynthData::~C1DAnisoMTSynthData()
00302 {
00303 }

Generated on Fri Jul 4 15:30:20 2008 for GPLIB++ by  doxygen 1.5.5