C1DAnisoMTSynthData.cpp

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

Generated on Tue May 4 16:52:14 2010 for GPLIB++ by  doxygen 1.5.8